C++ 扫雷游戏实现

这个星期在尝试着自己写一个扫雷游戏。功能基本和windows下的功能差不多。左键单击翻开一个格子,如果没有雷则显示其周围格子中含有雷的个数,没有周围的没有雷的话,那么就扩展空白块。 

扫雷游戏的难点在于如何扩展空白块和捕捉到鼠标的点击操作。  

扩展空白块的步骤为:1、翻开一个格子,如果检测有雷,则退出游戏;2、如果检测没有雷,那么就检测其周围的八个格子,如果周围有雷的话,显示含有雷的个数,跳到第四步;3、没有周围都没有雷的话,翻开这个格子,并且对周围的八个格子重复第二步。4、进行下一次鼠标点击检测。 

HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);COORD coord, pos;INPUT_RECORD mouseRec;DWORD res;ReadConsoleInput(hin, &mouseRec, 1, &res); //该函数用于读取鼠标和键盘事件if (mouseRec.EventType == MOUSE_EVENT) //检查是否有鼠标的按键按下{cout << "鼠标" << endl;if (mouseRec.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) //最左边的按键按下{cout << "左" << endl;}if (mouseRec.Event.MouseEvent.dwButtonState == RIGHTMOST_BUTTON_PRESSED) //最右边的按键按下{cout << "右" << endl;cout << "|>";}}  

捕捉鼠标的点击操作:注意在控制台窗口中,直接运行这个程序是不能捕捉到鼠标的点击操作的,需要在打开的那个控制台窗口上面那个白色边框,右键鼠标选择属性,然后关闭快速编辑选项,之后就可以正常的捕捉到鼠标的点击操作了。

int detect_sweeper_eight(int a, int b, int init_p[], vector<vector> map_sweeper){int temp_sweeper_count = 0;for (int i = a - 1; i < a + 2; ++i) //统计点开的格子周围的地雷的个数for (int j = b - 1; j < b + 2; ++j) //检测雷区这一块还需要进行相应的更改{if (i<0 || j<0 i="">init_p[0] - 1 || j>init_p[1] - 1){temp_sweeper_count = temp_sweeper_count;}else{if (map_sweeper[i][j] == 1)temp_sweeper_count++;}}return temp_sweeper_count;}/* 这个游戏中需要对已经翻开的格子进行做了标记,这个是重点,第一次因为没有对已经翻开的格子进行标记,导致程序进入了死循环;第二次加入了标记,能够正确的扩展空白块,但是一直在空白块之间循环,后来发现是那个用来标识地雷的数组没有进行引用传递。用的是值传递的方式,这样导致了无限循环,但是程序不会退出*/void detect_sweeper(int a, int b, int init_p[], vector<vector> map_sweeper, vector<vector> &map_sweeper_flag){int sweeper_count = 0;int map_a = a + init_p[2];int map_b = b + init_p[3];sweeper_count = detect_sweeper_eight(a, b, init_p, map_sweeper);if (!sweeper_count) //如果点开的格子周围都没有地雷的话,那么就把这九个空格给消去 {locate(map_b, map_a);cout << " ";map_sweeper_flag[a][b] = 0;for (int i = a - 1; i < a + 2; ++i)for (int j = b - 1; j < b + 2; ++j){if ((i == a && j == b) || i<0 || j<0 i="">init_p[0] - 1 || j>init_p[1] - 1) //是中心点、到达边界{} else{if (map_sweeper_flag[i][j] == 0){} //已经翻开的格子进行做了标记,这个是重点,之前不会退出循环,后来发现是那个用来标识地雷的数组没有进行引用传递。else //用的是值传递的方式,这样导致了无限循环{detect_sweeper(i, j, init_p, map_sweeper, map_sweeper_flag);}}}}else{locate(map_b, map_a);cout << sweeper_count;map_sweeper_flag[a][b] = 0;}}

还有一个计时的功能,之前写的程序只有一个线程,然后时间显示总是跳跃性的。然后我就把时间显示的功能放到另外的一个子线程中。然后就好了。

猜你喜欢

转载自blog.csdn.net/u014077947/article/details/75136777