这个俄罗斯方块是用c++基于windows控制台制作的。

源码地址:https://github.com/Guozhi-explore

话不多说,先上图感受一下:(控制台丑陋的界面不是我的锅emmm)

我们知道俄罗斯方块有俄罗斯方块的规则:

1.生成五种不同形状的方块 :L、Z、T、I和方形。

2.通过键盘控制左移、右移、旋转与直接下落。

3.遇到边界或者静止方块停止运动。

4.一行都有方块时自动消去,分数增加,上层方块下落。

5.如果顶部出现了堆积方块时游戏结束。

6.小框提前放映出待会出现的方块形状。

7.等级升高,速度增大。

现在就来讲一讲如和在这些规则都实现的前提下制作俄罗斯方块的游戏,并尽可能的提高用户的游戏体验。

先来总体的规划一番,我们需要设计的类有:

单元类:Unit;   负责存储每个小单元的位置(x,y)以便于在控制台上打印出来。

工具类:Tool;      借助于windows提供的API,移动到特定的位置,打印图案或消除图案。

界面类:Frame;    打印出游戏运行时的外围框架和游戏信息。

游戏逻辑类: Diamond(名字与游戏不是很相关orz);    最长和最复杂的一个类,所有的游戏逻辑都将在这里实现。

主程序类: main.cpp;

一:

为了阅读的方便,我把以后要经常用到的Unit、Tool类先介绍一二:

我们知道windows控制台默认的大小是80*40,也就是说我们游戏要打印出来的所有内容的位置坐标必须都在0<x<80,y<x<40这个范围内。

那怎么样才能控制打印的位置呢?

我借助windows提供的函数自己在Tool类里面封装了一个函数:

void Tool::gotoxy(int x, int y)
{
COORD coor;
coor.X = x;
coor.Y = y;
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(handle, coor);
}

通过windows里的SetConsoleCursorPosition函数,能将光标带到我们指定的控制台坐标(x,y)。

很显然,使用了gotoxy函数我们就能够在控制台上将光标带到各个位置,绘制出我们想要的任何形状。

那么谁来提供这个坐标呢?

答案就是Unit单元类了。

Unit.h

 1 #pragma once
2 #include"Tool.h"
3 #include"Frame.h"
4 class Unit
5 {
6 private: int pos_x, pos_y;
7 char pic='#';
8 public:
9 Unit(int x,int y);
10 ~Unit();
11 void show();
12 int get_x();
13 int get_y();
14 void set_x(int x);
15 void set_y(int y);
16 };

Unit.cpp

 1 #include "Unit.h"
2 Unit::Unit(int x,int y)
3 {
4 pos_x = x;
5 pos_y = y;
6 }
7 Unit::~Unit()
8 {
9 }
10 void Unit::show()
11 {
12 Tool T;
13 T.gotoxy(pos_x, pos_y);
14 cout << pic; //俄罗斯方块由‘#’号组成
15 return;
16 }
17 int Unit::get_x()
18 {
19 return pos_x;
20 }
21 int Unit::get_y()
22 {
23 return pos_y;
24 }
25 void Unit::set_x(int x)
26 {
27 pos_x = x;
28 }
29 void Unit::set_y(int y)
30 {
31 pos_y = y;
32 }

说完了这两个基础类,我们就来进一步的介绍Frame类。

二:

Frame类要打印出来的信息如图:

Frame类不仅要把东西打印出来,它还负责着区域的划定,在Frame类里面有一些const参数:

1     const int UP = 5;
2 const int BUTTOM = 20;
3 const int LEFT = 18 ;
4 const int RIGHT = 30;
5 const int RIGHT2 = 46;
6 const int RIGHT3 = 63;
7 const int MIDDLE1 = 12;
8 const int MIDDLE2 = 17;

这些参数要放在public里面,以便在Diamond类中实现游戏区域、小屏幕、得分区三个区域各自的任务时能够访问的到。

三:

Diamond类

这是最关键的一个类,实现出来光是.cpp中就有300多行代码。

在Diamond类的主战场,游戏区域我设置了一个grid二维数组,用来保存游戏区域的方块信息,一个arrays数组用来保持当前运动的四个方块的信息,一个speed数组用来设置速度,LEVEL是最高级别,speed是当前速度(speed是每次Sleep()函数的时长,speed越小方块运动越快),level是当前级别,scoretotal是当前得分。

Diamond.h代码:

 1 #pragma once
2 #include"Frame.h"
3 #include<vector>
4 #include"Unit.h"
5 #include<ctime>
6 #include<cstdlib>
7 class Diamond
8 {
9 private:
10 static const int LEVEL = 15;
11 bool grid[17][19];
12 vector<Unit> arrays;
13 int Speed[LEVEL];
14 int speed=700;
15 int level = 0, scoretotal = 0;
16 public:
17 Diamond();
18 ~Diamond();
19 void create();
20 void rotate();
21 void show();
22 void move();
23 void shift();
24 void set_speed(int m_speed);
25 void control();
26 int get_level();
28 int eliminate();
29 bool judge_death();
30 bool delay();
31 };

Diamond构造函数:

 1 Diamond::Diamond()
2 {
3 Frame F;
4 grid[F.RIGHT - F.LEFT - 1][F.BUTTOM - F.UP - 1]; //有方块是true,没有是false
5 for (int i = 0; i <= F.RIGHT - F.LEFT - 2; ++i)
6 {
7 for (int j = 0; j <= F.BUTTOM - F.UP - 2; ++j)
8 {
9 grid[i][j] = false;
10 }
11 }
12 for (int i = 0; i < 13; ++i)
13 {
14 Speed[i] = 700 - 30 * i;
15 }
16 for (int i = 13; i < LEVEL; ++i)
17 {
18 Speed[i] = 300; //制作速度等级数组
19 }
20 F.Draw_score(0, 0);
21 }

前面讲到了俄罗斯方块的一些规则,第一个就是生成五种不同的方块,分别是Z\T\L\I\方形。

它们之间虽然形状各异,但好在有一个共同的地方,它们都是由四个基础方块(也就是四个Unit)组成的。

不妨用一个数组arrays来实现这五种方块。

arrays是由Unit组成的数组,通过给数组里unit单元不同的x、y值得到不同的形状(unit【0】位于游戏区域的正上方)。

借助于随机函数我们可以每次出现不同的方块(方块出现的概率有差别时,游戏体验更佳),然后使用旋转函数rotate(之后会实现)得到更为丰富的方块形状。

arrays得到之后,我们就要打印了。(由于unit【0】作为基准点在游戏区域的正上方,不用考虑方块旋转之后碰到两侧框架的问题)

打印有两个地方:1.游戏区域,2.小屏幕。

打印完之后,需要在grid数组表示arrays里面各个单元的元素设置为true(此时已经有方块)。

代码贴出如下:

 1 void Diamond::create()
2 {
3 Frame F;
4 Tool T;
5 int key;
6 int base_point;
7 int rotate_time=0;
8 srand(time(NULL));
9 base_point = ( F.RIGHT-F.LEFT) / 2;
10 key = rand() % 5; //随机出形状
11 rotate_time = rand() % 9; //随机旋转原始形状,已达到丰富的目的
12 arrays.clear(); //为了降低难度,每个图形出现的比例应该不一样
13 switch(key)
14 {
15 case 0:
16 arrays.clear();
17 for (int i = 0; i < 4; ++i)
18 {
19 Unit unit(i + F.LEFT+base_point+1, F.UP + 1); //****型
20 arrays.push_back(unit);
21 }
22 for (int i = 0; i < rotate_time; ++i)
23 {
24 rotate();
25 }
26 break;
27 case 1:case 5:case 6:
28 arrays.clear();
29 for (int i = 0; i < 2; ++i)
30 {
31 for (int j = 0; j < 2; ++j)
32 {
33 Unit unit(i + F.LEFT + base_point + 1, F.UP + 1 + j); //正方形
34 arrays.push_back(unit);
35 }
36 }
37 break;
38 case 2:case 7: //枪形
39 arrays.clear();
40 arrays.push_back(Unit(F.LEFT + base_point + 1, F.UP + 1));
41 arrays.push_back(Unit (F.LEFT + base_point+2, F.UP + 1));
42 arrays.push_back(Unit (F.LEFT + base_point + 3, F.UP + 1));
43 arrays.push_back(Unit(F.LEFT + base_point + 3, F.UP + 2));
44 for (int i = 0; i < rotate_time; ++i)
45 {
46 rotate();
47 }
48 break;
49 case 3: //梯形
50 arrays.clear();
51 arrays.push_back(Unit(F.LEFT + base_point + 1, F.UP + 1));
52 arrays.push_back(Unit(F.LEFT + base_point+1, F.UP + 2));
53 arrays.push_back(Unit(F.LEFT + base_point + 2, F.UP + 2));
54 arrays.push_back(Unit(F.LEFT + base_point + 2, F.UP + 3));
55 for (int i = 0; i < rotate_time; ++i)
56 {
57 rotate();
58 }
59 break;
60 case 4: case 8:
61 arrays.clear(); //城墙形
62 arrays.push_back(Unit(F.LEFT + base_point + 1, F.UP + 1));
63 arrays.push_back(Unit(F.LEFT + base_point + 2, F.UP + 1));
64 arrays.push_back(Unit(F.LEFT + base_point + 3, F.UP + 1));
65 arrays.push_back(Unit(F.LEFT + base_point + 2, F.UP + 2));
66 for (int i = 0; i < rotate_time; ++i)
67 {
68 rotate();
69 }
70 break;
71 }
72 //应该先将小屏幕清空。
73 for (int i = 0; i < F.RIGHT2 - F.RIGHT - 1; ++i)
74 {
75 for (int j = 0; j < F.MIDDLE1 - F.UP - 1; ++j)
76 {
77 T.gotoxy(F.RIGHT + 1 + i, F.UP + j + 1);
78 cout << " ";
79 }
80 }
81 for (int i = 0; i < 4; ++i)
82 {
83 Unit unit(F.RIGHT + 7 + arrays[i].get_x() - arrays[0].get_x(), F.UP + 4 + arrays[i].get_y() - arrays[0].get_y());
84 unit.show(); //按照实际的俄罗斯方块,小屏幕放映的应该是下一个出现的方块形状,这里先将功能简单化
85 }
86 for (int i = 0; i < 4; ++i)
87 {
88 grid[arrays[i].get_x() - 1 - F.LEFT][arrays[i].get_y()-1-F.UP] = true;
89 }
90 }

create

特别注意,在小屏幕打印之前应将其清空。

rotate()旋转函数:

在create()函数里用到了rotate()函数,这里来将其实现。

在开始制作旋转函数的时候,我想这个应该是特别难的,因为有5种形状,而且旋转完之后可能会触碰到两侧框架和静止方块。

但是其实只要用上一点数学知识和技巧,便可以将这些问题轻松解决。

因为旋转(我的游戏中是逆时针转90度)其实就是arrays后三个单元对arrays[0]这个基准点来一个相对x、y的互换(看代码就明白了)。

 1 void Diamond::rotate()
2 {
3 Frame F;
4 for (int i = 0; i < 4; ++i)
5 {
6 grid[arrays[i].get_x() - 1 - F.LEFT][arrays[i].get_y()-F.UP-1] = false;
7 }
8 for (int i = 1; i <= 3; ++i)
9 {
10 int gap1 = arrays[i].get_x() - arrays[0].get_x();
11 int gap2 = arrays[i].get_y() - arrays[0].get_y();
12 arrays[i].set_x(arrays[0].get_x() - gap2);
13 arrays[i].set_y(arrays[0].get_y() + gap1);
14 }
15 return;
16 }

就是这么简单,只用了四行,就完成了五种形状方块的旋转。

注意到这里先将grid里面arrays每个单元所代表的元素都设置为了false(有方块是true,没有是false),而且在旋转完之后没有设置回true。这是因为我们的rotate()函数不是独立存在的,都只是被其他的函数引用。注意到旋转分为生成时旋转和过程中旋转。生成时我们会统一的设置true,而过程中会在shift函数设置(这样能避开相撞问题)。如果有疑问接着看下去就好了。

说完旋转,接着说下落吧。

move()函数

这个函数很简单,直接贴代码:

 1 void Diamond::move()
2 {
3 Frame F;
4 //Sleep(speed); 暂停会在control函数里实现
5 for (int i = 0; i < 4; ++i)
6 {
7 grid[arrays[i].get_x() - 1 - F.LEFT][arrays[i].get_y()-1-F.UP] = false;
8 }
9 for (int i = 0; i < 4; ++i)
10 {
11 arrays[i].set_y(arrays[i].get_y()+1);
12 }
13 for (int i = 0; i < 4; ++i)
14 {
15 grid[arrays[i].get_x() - 1 - F.LEFT][arrays[i].get_y()-F.UP-1] = true;
16 } //虽说move后面是shift函数,但是为了保持函数的独立性还是在每个函数里面都写上false、true这部分
17 return;
18 }

这里的move设置回了true,因为考虑到move是和shift()函数并列的,而rotate()实在shift()函数里面的。

说曹操,曹操到,shift()函数到了。

这个函数中我们要实现一个很重要的功能——用户操控。

A、a——左移,D、d——右移,R、r——旋转,D、d——速降。

_kbhit()是windows提供的函数,作用是检测到键盘输入。用一个while()持续检测后,在switch语句里判断输入目的。

左移,右移,旋转都有一个问题,如果新的位置与两侧框架、静止方块重合,那么这个运动应当作废,还是得回到原来的位置,并且这次运动不能呈现给用户(不然游戏体验太差了emmm)在这个函数中会将这个问题考虑解决掉。

速降功能实现很简单,只需要把用set_speed()函数设置speed为10(这种速度很快)就好了。

代码贴出来就都明白了(hhh)

 1 void Diamond::shift()
2 {
3 Frame F;
4 vector<Unit> array_wait;
5 //防止与两侧方块重合
6 bool flag = false;
7 for (int i = 0; i < 4; ++i)
8 {
9 array_wait.push_back(arrays[i]); //记录下arrays的原始位置
10 grid[arrays[i].get_x() - 1 - F.LEFT][arrays[i].get_y()-F.UP-1] = false;
11 }
12 while(_kbhit())
13 {
14 switch (_getch())
15 {
16 case 97:case 65:case VK_LEFT: //左移
17 for (int i = 0; i < 4; ++i)
18 {
19 int m_x = arrays[i].get_x();
20 arrays[i].set_x(m_x - 1);
21 }
22 break;
23 case 100:case 68: case VK_RIGHT: //右移
24 for (int i = 0; i < 4; ++i)
25 {
26 int m_x = arrays[i].get_x();
27 arrays[i].set_x(m_x + 1);
28 }
29 break;
30 case 82:case 114: //输入字符R(rotate)的大写或者小写,旋转
31 rotate();
32 break;
33 case 83:case 115:
34 set_speed(10); //实现速降功能 这个功能做得简单又有用户体验!!!
35 default:
36 break;
37 }
38 }
39 for (int i = 0; i < 4; ++i)
40 {
41 if (grid[arrays[i].get_x() - 1 - F.LEFT][arrays[i].get_y() - 1 - F.UP] == true)
42 flag = true;
43 if (arrays[i].get_x() <= F.LEFT || arrays[i].get_x() >= F.RIGHT)
44 flag = true;
45 }
46 if (flag == true) //如果相撞,则回到原始位置
47 {
48 arrays.clear();
49 for (int i = 0; i < 4; ++i)
50 {
51 arrays.push_back(array_wait[i]);
52 }
53 }
54 for (int i = 0; i < 4; ++i)
55 {
56 grid[arrays[i].get_x() - 1 - F.LEFT][arrays[i].get_y()-1-F.UP] = true;
57 }
58 return;
59 }

为了避免与框架或者静止方块相撞,设计了一个arrays_wait数组记录原来位置。

由于arrays各个单元在grid里面的投射点已经全部变成了false,这个时候一旦新的arrays有true,肯定是遇到了静止的方块,那么这次运动应该恢复。

讲了这么多移动,我们还没有把方块移动后的方块和静止方块一块打印在游戏区呢,这就要看show()了。

原理很简单,扫视整个grid数组,true打印#,false打印空格(为了将刚刚为true,现在为false的点恢复)。

 1 void Diamond::show()
2 {
3 Frame F;
4 Tool T;
5 for (int i = F.LEFT+1; i < F.RIGHT; ++i)
6 {
7 for (int j = F.UP + 1; j < F.BUTTOM; ++j)
8 {
9 if (grid[i - F.LEFT - 1][j - F.UP - 1] == true)
10 {
11 T.gotoxy(i, j);
12 cout << "#";
13 }
14 else
15 {
16 T.gotoxy(i, j);
17 cout << " ";
18 }
19 }
20 }
21 return;
22 }

好的移动的函数讲的差不多了,可以上一些检测的函数了。

检测函数共三个:

delay()滞留函数——如果arrays各个方块下面有静止方块,那么返回true。

eliminate()消除函数——如果有一行被方块填满了,消除该行,上面的方块下落一格,继续检测,返回整形,用来得到分数。

judge_death()生死函数——如果静止的方块堆积到了最上面一格,那么返回true,此时该轮游戏将结束。

我们来一个一个实现:

delay()基本与刚刚shift里面的方法一致,先设置为false,检测,再设置为true。

 1 bool Diamond::delay()
2 {
3 bool flag = false;
4 Frame F;
5 for (int i = 0; i < 4; ++i)
6 {
7 grid[arrays[i].get_x() - F.LEFT - 1][arrays[i].get_y() - F.UP - 1] = false;
8 }
9 for (int i = 0; i < 4; ++i)
10 {
11 if (arrays[i].get_y() == F.BUTTOM - 1)
12 flag=true;
13 if (grid[arrays[i].get_x()-F.LEFT-1][arrays[i].get_y() + 1-F.UP-1] == true)
14 flag = true;
15 }
16 for (int i = 0; i < 4; ++i)
17 {
18 grid[arrays[i].get_x() - F.LEFT - 1][arrays[i].get_y() - F.UP - 1] = true;
19 }
20 return flag;
21 }

eliminate():

从下往上一行行检测。

 1 int Diamond::eliminate()
2 {
3 Frame F;
4 int level = 0;
5 int i;
6 for ( i = F.BUTTOM - F.UP - 2; i >= 0; --i)
7 {
8 bool temp = true;
9 for (int j = 0; j < F.RIGHT - F.LEFT - 1; ++j)
10 {
11 if (grid[j][i] == false)
12 temp = false;
13 }
14 if (temp == true)
15 {
16 level++;
17 for (int k = 0; k < F.RIGHT - F.LEFT - 1; ++k)
18 {
19 for (int t = i; t > 0; --t)
20 {
21 grid[k][t] = grid[k][t - 1];
22 }
23 }
24 for (int k = 0; k < F.RIGHT - F.LEFT - 1; ++k)
25 {
26 grid[k][0] = false;
27 }
28 i++; //检测刚刚替补的一行
29 }
30
31 temp = true;
32 }
33 return level;
34 }

judge_death()函数:

很简单,看代码。

 1 bool Diamond::judge_death()
2 {
3 Frame F;
4 int temp = 0;
5 for (int i = 0; i < F.RIGHT - F.LEFT - 1; ++i)
6 {
7 if (grid[i][0] == true)
8 return true;
9 }
10 return false;
11 }

control函数。

contorl函数是很关键的函数,在它里面将之前的函数依次调用才能实现俄罗斯方块的功能。这个顺序也不能随意安排,必须根据程序的逻辑和各个函数的完善程度。

例如倘若我将create()函数放在了judge_death()之前,中间又没有delay()函数,那么judge_death()很可能因为arrays里面的运动方块投射在grid里面是true而返回true,那么游戏就结束了,与实际规则完全不同,因此这一个函数要经过多次调试才能写出最佳效果。

同时这个函数还包含了一些总体布局功能,如分数、等级的计算和打印,速度的设置。

代码如下:

 1 void Diamond::control()
2 {
3 Frame F;
4 Tool T;
5 while (judge_death()==false)
6 {
7 create();
8 show();
9 int score = 0;
10 while(!delay()) //判断下面是否有方块,从而停止此次运动
11 {
12 shift();
13 move();
14 show();
15 Sleep(speed);
16 }
17 score = eliminate();
18 scoretotal += score;
19 level = scoretotal / 4;
20 if (level == LEVEL)
21 {
22 break;
23 }
24 speed = Speed[level]; //根据等级改变速度,同时关闭速降功能
25 F.Draw_score(scoretotal, level+1);
26 Sleep(speed);
27 }
28 return;
29 }

至此300多行的Diamond类讲的差不多了,如果要看整体代码可以进入文章末尾的Github账号。

main.cpp

这里的设置就很简单了,用一个while循环是游戏实现再来一局的功能。

 1 #include<iostream>
2 using namespace std;
3 #include"Tool.h"
4 #include"Frame.h"
5 #include"Unit.h"
6 #include"Diamond.h"
7 /* coded by 郭志
8 2018/9/18 */
9 int main()
10 {
11 Tool T;
12 Frame F;
13 char chioce;
14 bool flag=true;
15 F.Draw_border();
16 F.Draw_message("郭志");
17
18 while (flag)
19 {
20 Diamond diamond;
21 diamond.control();
22 if (diamond.get_level() < 50)
23 {
24 T.gotoxy(0, 0);
25 cout << "你这盘达到的等级是" << diamond.get_level() << endl;
26 cout << "是否继续? 是(y)" << endl;
27 cin >> chioce;
28 if (chioce == 'y')
29 {
30 flag = true;
31 }
32 else flag = false;
33 }
34 }
35 return 0;
36 }

好的,俄罗斯方块的实现基本就是这些了,会了算法和游戏逻辑,虽然现在的界面比较丑陋,但是相信以后也能做出一些好看、好玩的俄罗斯方块。

源代码地址 https://github.com/Guozhi-explore

俄罗斯方块(c++)的更多相关文章

  1. 还是俄罗斯方块之android版

    前面的,口水话 请直接跳过. 虽然现在不比以前了 也没多少人气了,放到首页 都不到几百的点击量.也许博客园整体水平也是在往水的方向发展.不谈那些了,哥也曾经辉煌过 有过一天上千的点击量 ,哥也曾经有过 ...

  2. x01.Tetris: 俄罗斯方块

    最强大脑有个小孩玩俄罗斯方块游戏神乎其技,那么,就写一个吧,玩玩而已. 由于逻辑简单,又作了一些简化,所以代码并不多. using System; using System.Collections.G ...

  3. 俄罗斯方块C#版

    using System; using System.Windows.Forms; using System.Drawing; using System.Media; class me : Form ...

  4. 纯JS实现俄罗斯方块,打造属于你的游戏帝国

    纯JS俄罗斯方块,打造属于你的游戏帝国. 本文原始作者博客 http://www.cnblogs.com/toutou 俄罗斯方块(Tetris, 俄文:Тетрис)是一款电视游戏机和掌上游戏机游戏 ...

  5. 用纯JS做俄罗斯方块 - 简要思路介绍(1)

    大家都知道俄罗斯方块是一款大众化的游戏了,我很小的时候就玩过,今年已经25岁了,可以说俄罗斯方块确实是历史悠久,做俄罗斯方块是我上个星期开始的想法.也许是由于自己从来没有写过这种东西吧,所以有生疏.代 ...

  6. 趣味python编程之经典俄罗斯方块

    国庆期间闲不住,用python把经典俄罗斯方块实现了一遍,找到了些儿时的乐趣.因此突发奇想,打算用python写点经典又确实有趣的小程序形成系列.正统编程之余也给自己找点儿乐趣,换个角度写程序. 原计 ...

  7. javascript俄罗斯方块游戏

    在线试玩:http://keleyi.com/game/5/ 操作指南:键盘方向键←→控制左右移动,↑键变形,↓键快速下落. 别看这段js代码只有短短的100多行,效果却非常不错,用键盘的方向键操作, ...

  8. 俄罗斯方块(Win32实现,Codeblocks+GCC编译)

    缘起: 在玩Codeblocks自带的俄罗斯方块时觉得不错,然而有时间限制.所以想自己再写一个. 程序效果: 主要内容: 程序中有一个board数组,其中有要显示的部分,也有不显示的部分,不显示的部分 ...

  9. CCF 201604-2 俄罗斯方块

    题目不难,但是感觉很有意思.一开始忘了把调试信息注释掉,WA了两次... 试题编号: 201604-2 试题名称: 俄罗斯方块 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 ...

  10. Javascript 俄罗斯方块 游戏代码解释!

    俄罗斯方块代码说明 /** 名称:Javascript 俄罗斯方块! 作者:Gloot 邮箱:glootz@gmail.com QQ:345268267 网站:http://www.cnblogs.c ...

随机推荐

  1. Xshell6连Linux

    一.安装 文件 链接: 提取码:8rmr 二.连Linux 名称填自己喜欢的.续之前,我们保持一样的名字.主机填IP,根据之前Linux填的静态IP去连接. 然后双击,连接 我们用最高权限,填root ...

  2. 使用 cmake 来搭建跨平台的应用程序框架:C语言版本

    目录 一.前言 二.示例代码说明 1. 功能描述 2. 文件结构 3. cmake 构建步骤 4. Utils 目录说明 5. Application 目录说明 三.Linux 系统下操作步骤 1. ...

  3. webpack 快速入门 系列 —— 初步认识 webpack

    初步认识 webpack webpack 是一种构建工具 webpack 是构建工具中的一种. 所谓构建,就是将资源转成浏览器可以识别的.比如我们用 less.es6 写代码,浏览器不能识别 less ...

  4. 使用find_if算法搜寻map的value

    // // main.cpp // map_find // // Created by PKU on 14-9-8. // Copyright (c) 2014年 PKU. All rights re ...

  5. mitmproxy 获取请求响应数据

    比较好的一个介绍是:https://blog.wolfogre.com/posts/usage-of-mitmproxy/ mitproxy 获取请求响应数据的代码如下: # -*- coding: ...

  6. OAuth2.0 授权方式及步骤梳理总结

    OAuth 2.0授权协议使第三方应用程序可以通过协调资源所有者和HTTP服务之间的批准交互,或者通过允许第三方应用程序代表资源所有者来获得对HTTP服务的有限访问权,或者代表资源所有者. 代表自己获 ...

  7. [刷题] 235 Lowest Common Ancestor of a Binary Search Tree

    要求 给定一棵二分搜索树和两个节点,寻找这两个节点的最近公共祖先 示例 2和8的最近公共祖先是6 2和4的最近公共祖先是2 思路 p q<node node<p q p<=node& ...

  8. Linux创建RAID1_实战

    Linux创建RAID1实战 Linux创建RAID1 RAID1俗称镜像,它最少由两个硬盘组成,且两个硬盘上存储的数据均相同,以实现数据冗余 RAID1读操作速度有所提高,写操作理论上与单硬盘速度一 ...

  9. 测usb读写

    dd if=/dev/sda of=/dev/null bs=1M count=1000每次测完 清一下 memory cacheecho 3 > /proc/sys/vm/drop_cache ...

  10. ssh安全优化免密登陆

    ssh协议 为什么使用ssh协议? 在进行传输时,会对数据进行加密,保证会话安全:telnet协议不是加密传输,在传输过程中如果被抓包,就会造成信息泄露,telnet默认不支持root远程. # 常用 ...