扫雷对初学者来说是一个比较困难的小程序,今天的文章就教大家如何独立做出自己的扫雷游戏,如果您认为我写的不错,请给小陈点赞,收藏加关注,话不多说,让我们开始!
1.游戏的整体思路
一个较为复杂的小程序一般有着不同的文件来负责不同的功能。我们只需要运用几个算法模块来实现,会分成game.h,test.c,game.c等几个模块来运行,为了方便可以创建多个项目来实现。我们这里需要新建三个文件。
1. test.c 负责游戏整体流程的实现
2. game.c 负责游戏内部复杂函数的实现
3. game.h 负责包含所有函数所需的头文件
需要注意的是,game.c和test.c文件创建时选择c++文件,而game.h选择头文件
2.游戏菜单的创建
首先是游戏菜单的创建
int main() { int input; do { scanf("%d", &input); switch (input)//用1来表示开始游戏,用0来表示退出游戏 //这样做的好处是,当输入为0时,input的值判断为假,则直接跳出循环 { case 1: game(); break; case 0:printf("游戏结束\n"); break; default:printf("输入错误,请重新输入\n"); break; } } while (input); return 0; }
只是这样太过单调,我们加入可视化的菜单,为此我们单独创建menu函数
void menu() { printf("**************************\n"); printf("******** 1 play ********\n"); printf("******** 0 exit ********\n"); printf("**************************\n"); } int main() { int input; do { menu(); scanf("%d", &input); switch (input) { case 1: game(); break; case 0:printf("游戏结束\n"); break; default:printf("输入错误,请重新输入\n"); break; } } while (input); return 0; }
3.棋盘的初始化
想要做出扫雷,首先要做出扫雷的底盘,它应该有以下的两个功能。
1.读取输入的排雷位置,并判断该位置有没有雷
2.在读取位置之后,在没爆炸的情况下显示出周围8个格子雷的个数
为了打印出棋盘,和三子棋类似,我们可以使用喜闻乐见的二维数组,如果我们想要实现9x9的扫雷游戏,难道我们要创建9x9的二维数组吗?答案是否定的,至于原因:
程序需要判断周围8个格子所含雷的个数,假如选择9X9的二维数组,在输入边缘位置时就会有数组越界的现象。那我们就要在9X9的边界多上一圈元素,也就要定义11X11的数组元素,
多出来的部分需要打印吗?答案是否定的,我们自己心里知道有这部分就行。
在game.h文件中定义行和列 ,在test.c中完成对数组的定义。
#define COLS 11 #define ROWS 11 #define EASY_COUNT 10//下面会讲
char mine[COLS][ROWS], show[COLS][ROWS];
在show数组中,用字符‘0’表示无雷区域,用字符‘1’表示有雷区域
在mine数组中,用’✳‘来覆盖然后来排雷,之后用数字来取代,数字代表其周围的雷的个数
3.1函数部分
我们使用InitBoard函数来打印出棋盘。
void InitBoard(char a[COLS][ROWS], int col, int row, char set); InitBoard(mine, COLS, ROWS, '*'); InitBoard(show, COLS, ROWS, '0');
void InitBoard(char a[COLS][ROWS], int col, int row, char set) { int i, j; for (i = 0;i <=col;i++) { for (j = 0;j <=row;j++) { a[i][j] = set; } } }
为了同时照顾到两个数组,我们定义出set,为两个数组分配不同的符号。
3.2棋盘的打印
我们定义出DisplayBoard函数来完成棋盘的打印,并贴心地打印出行号和列号
void DisplayBoard(char a[COLS][ROWS], int col, int row) { int i, j; printf("********扫雷*******\n"); for (i = 0;i < 10;i++) { printf("%d ", i);//行号 }printf("\n"); for (i = 1;i < 10;i++) { printf("%d ", i);//列号 for (j = 1;j < 10;j++) { printf("%c ", a[i][j]); } printf("\n"); } }
打印出来的效果就是这样。
4.下棋功能的实现
打印出棋盘之后,接下来就轮到下棋的功能了。
为了实现其中的rand()函数,我们需要引用时间戳,在test.c文件中引用时间戳。
int main() { int input; srand((unsigned int)time(NULL));//时间戳 do { menu(); scanf("%d", &input); switch (input) { case 1: game(); break; case 0:printf("游戏结束\n"); break; default:printf("输入错误,请重新输入\n"); break; } } while (input); return 0; }
并在game.h中包含所需头文件
#include<stdlib.h> #include<time.h>
接着是玩家下棋的部分。
void BreakBoard(char mine[COLS][ROWS],char show[COLS][ROWS], int col, int row) { int x, y, set, k = 0; do { scanf("%d%d", &x, &y); if (x >= 1 && x <= 9 && y >= 1 && y <= 9) { if (show[x][y] == '1') { DisplayBoard(show, COLS, ROWS);//打印棋盘让人死的明白 printf("很遗憾,你被炸死\n"); break; } else { open(mine, show, x, y); DisplayBoard(mine, COLS, ROWS); printf("未发现危险\n"); k++; } } else { printf("重新输入\n"); } if (k == 71) { printf("恭喜你,扫雷成功!\n"); break; } } while (k<=71); }
假设一共有10个雷,我们总共循环71=81-10次,当我们已经循环了71次后,就代表我们已经将所有非雷区域全部排除了,我们在前面定义了一个k如果我们排对了就++,当达到了71次就代表我们已经将所有非雷区域全部排除了,紧接着打印扫雷成功。