扫雷游戏

  • 了解扫雷游戏规则
  • 菜单以及是否进入游戏的选择
  • 棋盘设置以及规则设置
  • 打印棋盘
  • 布置雷
  • 排查雷
  • 代码
    • game.h
    • game.c
    • test.c

仍然是拆分为三个文件来写,test.c来实现扫雷游戏的测试;game.c来写游戏的实现;game.h来写游戏的函数的声明。

了解扫雷游戏规则

在网页搜索“扫雷游戏网页在线玩”,可以看到游戏界面如下图所示。

游戏规则是:第一次点击不会是雷,格子里的数字代表的是它周围有几个雷。游戏的目标是找出所有雷,‘触雷’则输。

菜单以及是否进入游戏的选择

这个游戏要想实现玩一把之后还想玩就还可以继续玩的功能,就要用到do while的结构。首先要打印菜单,那么就要写一个简易的菜单打印函数menu来实现简易的打印功能;其次在菜单里写到了可以对是否进入游戏进行选择,那么就需要写出一个选择语句来进行选择。

void menu()
{printf("***********************\n");printf("*********1.play********\n");printf("*********0.exit********\n");printf("***********************\n");}int main()
{int input = 0;do{menu();printf("请选择:》");scanf("%d",&input);switch (input){case 1:printf("扫雷游戏\n");break;case 0:printf("退出游戏\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);return 0;
}

写代码遵循一边写一边测试的原则,因为这个代码比较长,这样就可以及早地发现问题所在。下面测试一下是否可以实现打印菜单以及进入游戏的选择。

***********************
*********1.play********
*********0.exit********
***********************
请选择:》2
选择错误,重新选择
***********************
*********1.play********
*********0.exit********
***********************
请选择:》1
扫雷游戏
***********************
*********1.play********
*********0.exit********
***********************
请选择:》0
退出游戏

棋盘设置以及规则设置

排雷游戏首先要在棋盘上布置雷的位置,接下来再是排查雷。
关于棋盘显示(9x9的棋盘):
最好是给出一个9x9的二维数组,这样才可以将雷随机布置进去;接下来如何设定某个格子雷呢?我们用1来表示。如果一个格子处的值是1则代表有雷;当格子处的值是0则代表不是雷的位置。
关于排查雷的时候的事项:
假设想要排查一下某坐标的位置是不是雷的位置,如果排查到该坐标周围有1个雷,就应该在该坐标处放上数字“1”,那么这个时候就有一个问题了,这个放置的数字1在后续排查的时候到底是会被认为是排查出来的雷的信息呢还是是此处埋雷的意思呢?之前想到可以这样,在是雷的地方放上*号,在不是雷的地方放上#,然后用数字来显示排查出来的雷的信息,这样是可以很好地规避刚才的那个问题,但是扫雷游戏在进行的时候,每次排查出来信息都要显示出来的,但是雷与非雷的位置是不显示的,如果采用这种方式,在打印的时候就得每一个格子判断一下是否是数字,是数字才可以打印,不是数字不打印,就很麻烦。
那怎么办呢?再创建一个数组,当排查出来雷的信息的时候,将这个信息放在新创建的数组里面(这个数组专门用来存放排查出来的雷的信息),这样排除出来的雷的信息和雷所在的位置就互不干扰啦。

还有一个问题,在排查雷的过程中,如果该格子不是处于棋盘的边界上,那么就是排查该格子上下左右共8个位置处排查是否有雷;那如果该格子是边界上的格子,那它周围就是只有3个格子。要是非得找出跟她相邻的8个元素,那么其它的格子就属于是越界。为了不让它算作越界,将棋盘上下左右各加上一排。也就是将9x9的棋盘改为11x11的棋盘。


结论:
需要给出两个数组,一个用来存放布置好的雷的信息,另一个用来存放排查出的雷的信息。
设置棋盘,使得棋盘在一开始的时候每个位置都放置 ,代表这个还没有被排查。一旦排查出来的时候,再将 * 替换。 数组 中放置的是,那就最好将数组设置为char类型。数组是char类型,那就需要调整一下规则了,当元素所在的位置是雷的话,就给那个位置放置一个字符“1”;如果所在位置非雷,就在那个位置放置一个字符“0”。
如果想要每个格子在寻找相邻的8个格子的时候不产生越界,就在创建数组的时候创建成11x11的数组。
接下来就开始正式编写程序吧。

//char mine[11][11];//存放布置好的雷的信息,这个数组需要全部初始化为‘0’
//char show[11][11];//存放排查出的雷的信息,这个棋盘需要全部初始化为‘*’
//设置11x11的数组,但是实际上不这样写,因为这样之后更改棋盘大小的时候会很麻烦
//这时候就可以在头文件里面去定义行和列,方便之后的修改

game.h中声明棋盘行和列

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘的函数声明
void InitBoard(char board[ROWS][COLS], int rows, int cols);

test.c利用声明的行和列来完成代码的编写

void game()
{char mine[ROWS][COLS];char show[ROWS][COLS];//初始化棋盘InitBoard(mine,ROWS,COLS);InitBoard(show, ROWS, COLS);}

初始化棋盘相当于是游戏的开始,于是就将这个函数的实现写进game.c里面

//定义初始化棋盘的函数
void InitBoard(char board[ROWS][COLS], int rows, int cols)
{//如何初始化呢?进行二维数组的遍历int i = 0;int j = 0;for(i=0;i<rows;i++)for (j = 0; j < cols; j++){board[i][j] == ' ';//由于这个函数要有适配性,即适合mine数组又适合show数组,到底是让这个格子处等于字符0呢,还是等于字符*呢//干脆在传参的时候多给一个参数,想让数组初始化为什么就将什么作为参数传过去}
}

将函数的声明、函数的定义以及传参部分的代码逐一进行修改,修改后的代码如下所示:

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set );
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set )
{//如何初始化呢?进行二维数组的遍历int i = 0;int j = 0;for(i=0;i<rows;i++)for (j = 0; j < cols; j++){board[i][j] == set;}
}
InitBoard(mine,ROWS,COLS,'0');
InitBoard(show, ROWS, COLS,'*');

打印棋盘

打印棋盘的时候,想要只显示中间的9x9个方格,这个时候就得注意该函数的实现中坐标的范围。11x11的格子它的横纵坐标的范围都是从0开始,至10结束,那么中间的9x9个方格的坐标就应该是横纵坐标均从1开始,至9结束。
先在game.h头文件中声明该打印棋盘函数, 传进去的棋盘是11x11的棋盘,但是要显示的横纵坐标是9x9的横纵坐标,为了与头文件保持一致(头文件game.h中ROW/COL分别代表的是9x9棋盘的行和列),将其横纵坐标的参数设置为row以及col。

void DisplayBoard(char board[ROWS][COLS], int row, int col);

其次在game.c中定义打印棋盘的函数,

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("---------扫雷游戏----------\n");for (i = 1; i <= row; i++){for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}printf("---------扫雷游戏----------\n");
}

最后在test.c文件里面调用编写好的打印棋盘函数

//打印棋盘DisplayBoard(mine,ROW,COL);DisplayBoard(show, ROW,COL);//只打印中间的9x9的格子,格子外面的一圈是为了辅助才加的

到此刻,测试效果如下

***********************
*********1.play********
*********0.exit********
***********************
请选择:》1
---------扫雷游戏----------
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
---------扫雷游戏----------
---------扫雷游戏----------
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
---------扫雷游戏----------

这个棋盘打印虽然能够实现它所需求的功能了,但是,它还不够完美,怎么说呢?如果任意选中一个元素,问这个元素是第几行第几列的,是不能一眼就清楚地观察到的。如果在最开始的时候给棋盘显示加上行号以及列号,这个元素所在的坐标就一目了然了。
如何显示行号呢?在每次打印行之前就打印行号;那么如何打印列号呢?列号是显示在最上方的,要想实现显示列号,就可以使用一个for循环。
代码如下:

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("---------扫雷游戏----------\n");//打印列号for (i = 1; i <= col; i++){printf("%d ",i);}for (i = 1; i <= row; i++){printf("%d ",i);//打印行号,在每一行打印之前先打印行号for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}printf("---------扫雷游戏----------\n");
}

测试一下这样的代码是否能够实现想要的功能:

***********************
*********1.play********
*********0.exit********
***********************
请选择:》1
---------扫雷游戏----------
1 2 3 4 5 6 7 8 9 1 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 0 0
---------扫雷游戏----------
---------扫雷游戏----------
1 2 3 4 5 6 7 8 9 1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
---------扫雷游戏----------

显然,代码是有问题的。棋盘第一行的显示跟列号的显示混到一行去了,在打印列号的代码后面加一句换行语句printf("\n");再测试一下,测试效果如下:

---------扫雷游戏----------
1 2 3 4 5 6 7 8 9
1 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 0 0
---------扫雷游戏----------
---------扫雷游戏----------
1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
---------扫雷游戏----------

代码还是有问题的,它将显示行号的那一列也算作了一列,所以想要正确显示列号,应该使得从0开始,这样就可以使得显示行号的那一列算作0,而第一列的列号是1。

//打印列号的代码如下:
for (i = 0; i <= col; i++){printf("%d ",i);}printf("\n");
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 0 0
---------扫雷游戏----------
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
---------扫雷游戏----------

有一点需要注意,在真正开始这个游戏的时候,第一个关于雷所在位置的信息是不会打印的,只会打印排雷信息。

布置雷

test.c中对布置雷函数的调用

//布置雷//布置雷其实就是在9x9的棋盘上随机找10个坐标把雷放进去SetMine(mine,ROW,COL);//传进去9x9的棋盘以及该9x9棋盘的行和列

接下来在game.h文件中对该函数进行声明

void SetMine(char mine[ROWS][COLS], int row, int col);

game.c中对该函数进行定义和功能实现

void SetMine(char mine[ROWS][COLS], int row, int col)
{//布置10个雷int count = 10;while (count){//生成随机的下标int x = rand()%row+1;int y = rand()%col+1;//横纵坐标都是1-9,就可以采用“%10(10是COL+1,也是ROW+1)”或者“%9的结果再加一”的办法来达到目的//rand函数的使用依靠srand函数,将其在test.c中调用//还要做一件事情,就是这个位置如果布置过雷就不能重复在此处布置了,非雷的位置才可以放雷if (mine[x][y] == '0'){mine[x][y] == '1';count--;}}
}

测试代码,会看到每次随机生成的雷的位置确实是随机的。

排查雷

FindMine(mine,show,ROW,COL);//排查雷是将mine的信息放到show,且还是9行9列的棋盘
//排查雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{//1、输入排查的坐标//2、检车该排查坐标是否是雷,如果是雷,打印“很遗憾”//如果非雷,统计坐标周围有几个雷--存储排查雷的信息到show数组,游戏继续int x = 0;int y = 0;while (1){printf("请输入要排查的坐标:》");scanf("%d%d",&x,&y);//要求x与y的取值范围都是1-9//接下来判断坐标的合法性if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine[x][y] == '1'){printf("很遗憾,被炸死了\n");DisplayBoard(mine, ROW, COL);break;}else{//不是雷的话,统计x、y周围有几个雷int count = get_mine_count(mine, x, y);//mine数组的(x,y)周围有几个雷//当统计好有几个雷之后,就将统计好的这个数字返回来放在show棋盘的相应的坐标那里//还有一点需要注意,要将返回的数字放进show里面,但是show里面的元素是char字符型的//所以此处要怎么办呢?利用ASCII码值//在ASCII码值中//0--》'0'的ASCII码值是48//1--》'1'的ASCII码值是49//2--》'2'的ASCII码值是50   数字0如何编程字符'0'呢?加上48就可以 其它数字想变成相应的字符就也加上48//3+'0'='3'  也就是count+'0'就转换成了对应的字符countshow[x][y] = count + '0';//显示排查出来的信息DisplayBoard(show, ROW, COL);}}else{printf("坐标不合法,请重新输入\n");}}
}

接下来就编写get_mine_count函数,寻找某坐标周围雷的个数,遍历它周围的八个坐标即可(x,y)周围的坐标分别是:

(x-1,y-1)  (x-1,y)  (x-1,y+1)
(x,y-1)     (x,y)    (x,y+1)
(x+1,y-1)   (x+1,y) (x+1,y+1)

最笨拙的办法是8个if语句分别判断这8个坐标上是否有雷(是否是字符’1’);但是这样确实麻烦。怎么办呢?令该坐标周围的这些元素分别减去字符’0’,然后将结果相加,这样得到的就是坐标处的数字的和了。

int get_mine_count(char mine[ROWS][COLS],int x,int y)
{//寻找某坐标周围雷的个数,遍历它周围的八个坐标即可return mine[x - 1][y] +mine[x - 1][y - 1] +mine[x - 1][y + 1] +mine[x][y - 1] +mine[x][y + 1] +mine[x + 1][y - 1] +mine[x + 1][y] +mine[x + 1][y + 1] - 8 * '0';}

还可将get_mine_count的类型设置为
static int get_mine_count(char mine[ROWS][COLS],int x,int y)
static修饰函数的时候,就会让这个函数只能在自己所在的源文件内部看到,其它地方看不到。因为这个get_mine_count函数实现出来只是为排查雷的函数FindMine服务的,这样做的话这个函数就不会跟其它源文件内部的函数冲突了。
测试效果:

***********************
*********1.play********
*********0.exit********
***********************
请选择:》1
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
---------扫雷游戏----------
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 1
3 0 0 0 0 0 0 1 0 0
4 0 0 0 0 1 0 0 0 0
5 0 0 0 0 0 0 0 0 1
6 0 0 0 0 0 0 1 1 0
7 0 1 0 0 0 0 0 0 0
8 0 1 0 0 0 0 0 1 0
9 0 0 0 0 0 0 0 1 0
---------扫雷游戏----------
请输入要排查的坐标:》9 7
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * 2 * *
---------扫雷游戏----------
请输入要排查的坐标:》9 8
很遗憾,被炸死了
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 1
3 0 0 0 0 0 0 1 0 0
4 0 0 0 0 1 0 0 0 0
5 0 0 0 0 0 0 0 0 1
6 0 0 0 0 0 0 1 1 0
7 0 1 0 0 0 0 0 0 0
8 0 1 0 0 0 0 0 1 0
9 0 0 0 0 0 0 0 1 0
---------扫雷游戏----------

现在写的这个代码是存在一个问题的,因为上述代码写的是while(1)成立就执行“输入坐标”的操作,这个条件是会一直成立的,所以就会出现即使雷全部排完了也还是会让输入坐标的现象。应该在程序中判断一下什么时候游戏结束,每次进入下面的代码就排查一个坐标处相邻的坐标的情况。

else{//不是雷的话,统计x、y周围有几个雷int count = get_mine_count(mine, x, y);//mine数组的(x,y)周围有几个雷show[x][y] = count + '0';DisplayBoard(show, ROW, COL);}

如果是9x9的棋盘,就有81个坐标,除去雷的10个位置,剩下的就是71个位置,如果能排出来这71个位置,游戏就应该结束了。
定义一个变量win,只要进一次上面那段代码,就win++。while语句里面的条件就可以是(win<row*col-10)
在布置雷的代码中,也写到了一个数字10,这里将雷的个数也给它写进game.h头文件里面去#define EASY_COUNT 10。在最后判断排雷排了71次都未被炸死,那就输出打印“恭喜排雷成功。”缺少了这个判断的话,在输出打印“被炸死了”之后跳出循环会直接打印“排雷成功”,这就是程序的问题了。

if (win == row * col - EASY_COUNT){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);}

为了方便测试代码是否还存在问题,将雷的个数设置为80个,并且在游戏开始的时候就显示一下雷的位置。测试结果如下:

***********************
*********1.play********
*********0.exit********
***********************
请选择:》1
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * * * * * * *
9 * * * * * * * * *
---------扫雷游戏----------
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1 1 1
5 1 1 1 1 1 1 1 1 1
6 1 1 1 1 1 1 1 1 1
7 1 1 1 1 1 1 1 1 1
8 1 1 1 0 1 1 1 1 1
9 1 1 1 1 1 1 1 1 1
---------扫雷游戏----------
请输入要排查的坐标:》8 4
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 * * * * * * * * *
2 * * * * * * * * *
3 * * * * * * * * *
4 * * * * * * * * *
5 * * * * * * * * *
6 * * * * * * * * *
7 * * * * * * * * *
8 * * * 8 * * * * *
9 * * * * * * * * *
---------扫雷游戏----------
恭喜你,排雷成功
---------扫雷游戏----------
0 1 2 3 4 5 6 7 8 9
1 1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1 1 1
5 1 1 1 1 1 1 1 1 1
6 1 1 1 1 1 1 1 1 1
7 1 1 1 1 1 1 1 1 1
8 1 1 1 0 1 1 1 1 1
9 1 1 1 1 1 1 1 1 1
---------扫雷游戏----------

在网页玩这个游戏的时候,发现

  • 点开没有雷的地方,人家这个会把没雷的附近的八个坐标附近分别有几个雷也给写进去(可以尝试用递归来实现)
  • 排查到一个地方是雷,想要右键标记一下,如何标记呢?
    所以现在的代码之后还可以进行优化。

代码

game.h

#pragma once
#include <stdio.h>#define EASY_COUNT 80
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2//初始化棋盘的函数声明
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set );//打印棋盘的声明
void DisplayBoard(char board[ROWS][COLS], int row, int col);//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);//排查雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);

game.c

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"//定义初始化棋盘的函数
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{//如何初始化呢?进行二维数组的遍历int i = 0;int j = 0;for(i=0;i<rows;i++)for (j = 0; j < cols; j++){board[i][j] = set;}
}//打印棋盘的函数实现
//注意这里变成了打印9x9的格子,就得注意一下这个行和列的范围,都是1-9
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("---------扫雷游戏----------\n");//打印列号//for (i = 1; i <= col; i++)for (i = 0; i <= col; i++){printf("%d ",i);}printf("\n");for (i = 1; i <= row; i++){printf("%d ",i);//打印行号,在每一行打印之前先打印行号for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}printf("---------扫雷游戏----------\n");
}//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;while (count){//生成随机的下标int x = rand()%row+1;int y = rand()%col+1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}
}//int get_mine_count(char mine[ROWS][COLS],int x,int y)
//static可以修饰局部变量、全局变量以及函数
static int get_mine_count(char mine[ROWS][COLS], int x, int y)
{//寻找某坐标周围雷的个数,遍历它周围的八个坐标即可return mine[x - 1][y] +mine[x - 1][y - 1] +mine[x - 1][y + 1] +mine[x][y - 1] +mine[x][y + 1] +mine[x + 1][y - 1] +mine[x + 1][y] +mine[x + 1][y + 1] - 8 * '0';}//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{//1、输入排查的坐标//2、检车该排查坐标是否是雷,如果是雷,打印“很遗憾”//如果非雷,统计坐标周围有几个雷--存储排查雷的信息到show数组,游戏继续int x = 0;int y = 0;//判断游戏结束的变量int win = 0;//while (1)while (win < row * col - EASY_COUNT){printf("请输入要排查的坐标:》");scanf("%d%d", &x, &y);//要求x与y的取值范围都是1-9//接下来判断坐标的合法性if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine[x][y] == '1'){printf("很遗憾,被炸死了\n");DisplayBoard(mine, ROW, COL);break;}else{//不是雷的话,统计x、y周围有几个雷int count = get_mine_count(mine, x, y);//mine数组的(x,y)周围有几个雷show[x][y] = count + '0';//显示排查出来的信息DisplayBoard(show, ROW, COL);win++;}}else{printf("坐标不合法,请重新输入\n");}}if (win == row * col - EASY_COUNT){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);}}

test.c

#include<stdio.h>
#include "game.h"
#include<stdlib.h>
#include<time.h>
void menu()
{printf("***********************\n");printf("*********1.play********\n");printf("*********0.exit********\n");printf("***********************\n");}void game()
{char mine[ROWS][COLS];char show[ROWS][COLS];//初始化棋盘InitBoard(mine,ROWS,COLS,'0');InitBoard(show, ROWS, COLS,'*');//打印棋盘DisplayBoard(show, ROW,COL);//布置雷SetMine(mine,ROW,COL);//传进去9x9的棋盘以及该9x9棋盘的行和列DisplayBoard(mine, ROW, COL);//排查雷FindMine(mine,show,ROW,COL);
}int main()
{int input = 0;srand((unsigned int)time(NULL));do{menu();printf("请选择:》");scanf("%d", &input);switch (input){case 1://printf("扫雷游戏\n");game();//扫雷游戏break;case 0:printf("退出游戏\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);return 0;
}

c语言---25 扫雷游戏相关推荐

  1. 用c语言编写最大最小值_C语言学习教程,用C语言编写扫雷游戏

    本文实例为大家分享了C语言实现扫雷游戏及其优化的具体代码,供大家参考,具体内容如下 关于扫雷优化 1.核心思想:使用两个二维数组进行设计,一个用于显示,一个用于后台雷的布置. 2.使用宏常量,后期可以 ...

  2. c++扫雷游戏代码_C语言学习教程,用C语言编写扫雷游戏

    本文实例为大家分享了C语言实现扫雷游戏及其优化的具体代码,供大家参考,具体内容如下 关于扫雷优化 1.核心思想:使用两个二维数组进行设计,一个用于显示,一个用于后台雷的布置. 2.使用宏常量,后期可以 ...

  3. 超详细分解c 语言——实现扫雷游戏(详解)

    之前利用三子棋程序,介绍探讨了 c语言简单游戏编写主要模块及使用方法. 今天,我们就利用这个经典扫雷游戏,来加强对于程序思路的编写及思路. 目录 前引 游戏规则介绍 一.基本游戏思路(游戏实现方法) ...

  4. c语言扫雷游戏计时功能_C语言实现扫雷游戏(可以自动展开)

    前言 本篇博客主要介绍如何使用C语言实现扫雷游戏. 一.游戏规则 在一张ROW行COL列的地图上存在MINE_COUNT个地雷.玩家输入坐标翻开格子,若没有踩雷,则计算此格子周围8个格子的地雷总数,并 ...

  5. c语言—实现扫雷游戏

    文章目录 什么是扫雷游戏 一.实现思路 二.头文件 三.主函数文件 1.菜单函数 2.主函数 四.游戏文件 1.地图初始化 2.展示地图 3.埋雷函数 4.判断该位置附近雷的个数 5.主游戏函数 五. ...

  6. 用C语言实现扫雷游戏

    用C语言实现扫雷游戏 -扫雷游戏的基本思路 1.打印游戏的菜单 2.为了便于后面排查周围雷的个数,初始化两个二维数组,一个作为向玩家显示的面板,一个作为布雷的面板.两个数组嵌套在一起.如下图所示: 3 ...

  7. C语言编写扫雷游戏,超简单

    C语言编写扫雷游戏,超简单 1.扫雷游戏的流程 2.代码编写 3.总结 通过学习C语言的基础知识,基本上是理解了大部分内容,现在就通过所学的知识,写个简单的扫雷游戏,加深对基础知识的理解,正所谓实践是 ...

  8. C语言实现扫雷游戏(超详细讲解+全部源码)

    电子信息 工科男 一点一点努力! 文章目录 前言 一.游戏介绍 二.游戏设计思路 二.具体步骤 1.创建test.c和game.c源文件以及 game.h头文件 2.创建菜单 3.创建雷盘 4.初始化 ...

  9. c语言程序设计扫雷游戏实验报告,C语言程序设计扫雷游戏实验报告.doc

    C语言程序设计扫雷游戏实验报告 中南大学 程序设计基础实践报告 题 目 设计一个和window系统类似的小游戏[挖地雷] 学生姓名 张兰兰 学 院 信息科学与工程学院 专业班级 物联网工程1301班 ...

  10. c语言扫雷程序设计流程图,c语言程序设计扫雷游戏实验报告

    c语言程序设计扫雷游戏实验报告 中南大学 程序设计基础实践报告 题 目 设计一个和window系统类似的小游戏[挖地雷]学生姓名 张兰兰 学 院 信息科学与工程学院 专业班级 物联网工程1301班 完 ...

最新文章

  1. 如何编写可测试的代码 哈利勒的方法论
  2. 使用NPOI时ICSharpCode.SharpZipLib版本冲突问题解决
  3. 用init-connect+binlog实现用户操作追踪【转】
  4. 武汉python培训哪一家好一些-武汉Python培训机构哪家好?要怎么选才靠谱?
  5. java mysql 操作类_Java 数据库简单操作类
  6. debian linux 安装smb 配置
  7. c# list集合根据某个字段去重_Python list、dataframe去重
  8. 用Flash和XML构建论坛实例(3)
  9. vue 路由传参 params 与 query两种方式的区别
  10. stm32单片机OLED取字模软件使用 PCtoLCD2002
  11. matlab如果不想立即在,科学计算与MATLAB 1.5
  12. 【FFMEPG】windows下编译ffmpeg2.5——使用VS2013,ARMLINUX,ANDORID编译ffmpeg
  13. 男子因惧内欲退还iPad 2苹果免费赠送
  14. Atitit 源码语句解析结构 目录 1.1. 栈帧(stack frame).每个独立的栈帧一般包括: 1 1.2. 局部变量表(Local Variable Table) 2 2. ref 2
  15. SpringBoot2集成Quartz配置独立数据源
  16. 使用IBM ServerGuide安装操作系统
  17. python之类和对象
  18. C# 对文件进行MD5计算
  19. 快速学习Groovy
  20. 好女人是一所学校- -

热门文章

  1. 软考中级软件设计师易错点整理
  2. 扣哒世界入选第33届国际信息学奥赛IOI专项赛
  3. 学习React Native必看的几个开源项目
  4. 高校先行,科技部公示10个国家级区块链重点项目 | 产业区块链发展周报
  5. javascript 获取邮箱的后缀
  6. 如何关闭伽卡他卡的开机自启
  7. 23考研需要准备哪些学习资料?
  8. HDU1034C++
  9. 洛谷1315 观光公交(贪心)
  10. Manjaro安装教程