
目标创建一个9行9列的扫雷范围一共有10个地雷。开始游戏后用户选择一个位置如果有雷则游戏失败如果没有雷则该位置显示以此为中心一圈范围的雷的数量并继续扫雷。将10个雷之外所有非雷的位置找出来则成功。游戏的扫雷范围和扫雷数量可以更改。扫雷游戏的编写思路用c语言编写一段扫雷游戏的代码首先需要将扫雷游戏的功能拆分多个模块每个模块的功能写对应的函数去实现最后按需求依次在主函数中使用这些具有不同功能的函数从而完成扫雷游戏的简单实现。因此我们先创建三个文件一个是mian.c源文件在该源文件中写主体结构的代码一个是game.c源文件在这个源文件中定义各个模块所需要的具备各种功能的各个函数一个是game.h头文件该文件中主要声明各个函数。1 整体框架的构建1.1 构建主函数int main() { int input 0; do { menu();//目录 printf(请选择); scanf(%d, input); switch (input) { case 1: game(); break; case 0: printf(退出游戏。\n); break; default: printf(选择错误重新选择。\n); break; } } while(input); return 0; }先在main.c文件中创建一个do-while循环循环中写扫雷游戏的框架。do-while的目的是先执行再根据选择决定要不要继续执行。所以接下来用scanf接收用户的选择。我们规定输入1开始游戏输入0退出游戏。因此我们将输入值“input”放在while的条件中1为真继续执行0为假退出循环结束游戏。我们用switch语句来实现以上要求输入1选择开始游戏那么在里面放入game函数后续编写开始游戏输入0退出游戏输入其他数字提醒用户输入错误重新选择。由于非0表示真所以会继续循环重新选择。1.2 制作目录制作一个目录美化我们的代码让用户知道输入1开始游戏输入0退出游戏。void menu() { printf(---------------------\n); printf(---------------------\n); printf(-------1. play-------\n); printf(-------0. exit-------\n); printf(---------------------\n); printf(---------------------\n); }写一个函数内容是打印目录这样在主函数中直接使用这个函数就可以打印目录。2 扫雷游戏棋盘的构建2.1 用二维数组表示扫雷棋盘扫雷的棋盘可以看成9行9列的表格格子中是空的或者有地雷。我们可以创建一个9行9列的二维数组简单将其表示出来。其中字符‘0’表示没有雷字符‘1’表示有雷。在我们选择某个边界的位置时周围一圈的位置就会溢出我们创建的二维数组查找雷的时候并不方便。所以我们可以创建一个比扫雷范围大一圈的二维数组。例如9行9列的棋盘我们就创建一个11行11列的二维数组这样判断边界位置上周围雷的个数的时候就不会超出数组的范围便于计算。2.2 头文件的使用为了让游戏的内容更灵活代码更改方便我们在game.h头文件中定义几个变量#define ROW 9//这是展示出来的数组的行数 #define COL 9//这是展示出来的数组的列数 #define ROWS ROW2//这是实际需要的创建的数组的行数 #define COLS COL2//这是实际需要的创建的数组的列数 #define EASY_COUNT 10//这是地雷的数量在我们需要更改扫雷游戏的棋盘大小和地雷数量时我们可以直接在这里更改。2.3 创建两个二维数组我们需要创建两个二维数组一个二维数组用来存放‘0’和‘1’表示该位置下有没有地雷。另一个数组用来展示给用户看让用户知道自己查找了哪些位置并显示那些查找过的位置的四周有几个地雷。void game() { char mine[ROWS][COLS] {0};//布置雷的数组 char show[ROWS][COLS] {0};//展示给用户的数组 }2.4初始化两个二维数组创建好两个二维数组后我们需要先初始化这两个二维数组给它们填入对应的内容。那么我们在game.c文件中出创建一个InitBoard函数。void InitBoard(char board[ROWS][COLS], int r, int c, char set) { int i 0; int j 0; for (i 0; i r; i)//定位行 { for (j 0; j c; j)//定位列 { board[i][j] set; } } }这个函数的四个参数分别对应数组需要初始化的行的数量需要初始化的列的数量填充的内容。这样我们就可以引用两次InitBoard函数来分别初始化这两个数组。void game() { char mine[ROWS][COLS] {0};//布置雷的数组 char show[ROWS][COLS] {0};//展示给用户的数组 //初始化游戏区域 InitBoard(mine, ROWS, COLS, 0);//先全部用‘0’填充后续再随机插入地雷 InitBoard(show, ROWS, COLS, *);//用‘*’表示该位置没有翻开 }3 打印出扫雷棋盘将数组的内容填好后我们就需要打印出数组让用户看见。我们创建一个DisplayBoard函数来实现这一功能。void DisplayBoard(char board[ROWS][COLS], int r, int c) { int i 0; int j 0; for (j 0; j c; j)//打印列号,从0到c0与行号对齐避免错位 { printf(%d , j); } printf(\n);//打印完列号后换行 for (i 1; i r; i)//i从1开始r结束不显示第0行和最后一行那是外围的一圈 { printf(%d , i);//先打印行号再打印这一行中每列的内容 for (j 1; j c; j)//j从1开始c结束不显示第0列和最后一列那是外围的一圈 { printf(%c , board[i][j]); } printf(\n);//每行结束后换行 } printf(\n); }这三个参数分别对应数组需要打印的行的数量需要打印的列的数量这样我们就可以应用该函数来打印mine数组。void game() { char mine[ROWS][COLS] {0};//布置雷的数组 char show[ROWS][COLS] {0};//展示给用户看的数组 //初始化游戏区域 InitBoard(mine, ROWS, COLS, 0); InitBoard(show, ROWS, COLS, *); //打印棋盘 DisplayBoard(show, ROW, COL); }4 将雷布置到棋盘中打印出棋盘后我们需要在棋盘的随机位置填充地雷我们可以创建SetMine函数来实现这一功能。void SetMine(char mine[ROWS][COLS], int r, int c) { int count EASY_COUNT;//布置得雷的数量 while (count) { int x rand() % r 1;//控制布置雷的行的范围 int y rand() % c 1;//控制布置雷的列的范围 if (mine[x][y] ! 1)//当这个位置没有被布置过雷的条件下 { mine[x][y] 1; count--;//每布置成功一次-1使该循环的循环次数为count次 } } }这三个参数分别对应被布置雷的数组需要被布置雷的行的数量范围需要被布置的列的数量范围。rand会随机生成一个数这个随机数%r那么得到的数字范围就是0 ~ r-11后范围就是1~r。使用rand函数需要在主函数中加入种子srand((unsigned int)time(NULL))。并加上#include stdlib.h和#include time.h这两个头文件。这样我们就可以在数组中随机生成一定数量的雷了void game() { char mine[ROWS][COLS] {0};//布置雷的数组 char show[ROWS][COLS] {0};//展示给用户看的数组 //初始化游戏区域 InitBoard(mine, ROWS, COLS, 0); InitBoard(show, ROWS, COLS, *); //打印棋盘 DisplayBoard(show, ROW, COL); //布置雷 SetMine(mine, ROW, COL); }5 在棋盘中排查雷将雷布置好后就可以开始排查雷了。我们可以创建一个FindMine函数来实现这个功能。由于这个函数较复杂我们还可以写一个简单的函数GetMineCount来帮助FindMine的实现int GetMineCount(char mine[ROWS][COLS], int x, int y) { /*利用ASCII码值进行计算0的ASCII码值是481的ASCII码值是49四周八个位置的字符的ASCII码值加起来减8个0的ASCII码值就是周围1的个数*/ return (mine[x - 1][y] mine[x - 1][y - 1] mine[x][y - 1] mine[x 1][y - 1] mine[x 1][y] mine[x 1][y 1] mine[x][y 1] mine[x - 1][y 1] - 8 * 0); } void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int r, int c) { int x 0; int y 0; int win 0; while (win (r*c - EASY_COUNT))//当排雷的次数小于棋盘格子数减雷的数量说明还没有排完继续进入循环排雷 { printf(请输入要排查的坐标); scanf(%d%d, x, y); //判断坐标是否在棋盘范围内 if (x 1 x r y 1 y c) { //判断坐标是否被排查过 if(show[x][y] *) { //判断该位置是不是雷 if (mine[x][y] 0)//不是雷 { int count GetMineCount(mine, x, y);//周围雷的数量 show[x][y] (char)(count 0);//将排查到的雷的数量转化为字符类型显示在棋盘上 DisplayBoard(show, ROW, COL);//打印排查后的棋盘信息 win;//排查成功的次数1 } else//是雷 { printf(很遗憾你被炸死了\n); DisplayBoard(mine, ROW, COL);//展示雷的布局 break;//跳出循环结束游戏 } } else//坐标被排查过的情况结束后会重新进入循环选择坐标由于win没有1不会影响使游戏结束需要的排雷成功的次数 { printf(该坐标已经排查过了请重新输入坐标\n); } } else//坐标不在棋盘范围的情况结束后会重新进入循环选择坐标由于win没有 1不会影响使游戏结束需要的排雷成功的次数 { printf(输入错误坐标请重新输入\n); } } //结束循环后来到这里成功或失败 if (win r * c - EASY_COUNT)//成功的情况 { printf(恭喜你,排雷成功\n); DisplayBoard(mine, ROW, COL); } }这四个参数分别对应雷的布局的数组展示给用户看的数组排查雷的行的数量范围排查雷的列的数量范围在game函数中加上这个函数后game函数的功能就完整了void game() { char mine[ROWS][COLS] {0};//布置雷的数组 char show[ROWS][COLS] {0};//展示给用户看的数组 //初始化游戏区域 InitBoard(mine, ROWS, COLS, 0); InitBoard(show, ROWS, COLS, *); //打印棋盘 DisplayBoard(show, ROW, COL); //布置雷 SetMine(mine, ROW, COL); //DisplayBoard(mine, ROW, COL); //排查雷 FindMine(mine, show, ROW, COL); }总结这样就用c语言写了一个简单的扫雷游戏。如有错误欢迎指出。