有幸在鹏哥的指导下写出了扫雷游戏,相比于上一次的三子棋代码,扫雷代码更加考验一个程序员对于数组的灵活运用,也再一次激起了我对代码的兴趣和热情
在讲解扫雷代码前,先来介绍一下扫雷是个什么游戏,在没要用C语言写出扫雷之前我其实连扫雷是什么都不知道,儿时玩扫雷的时候就是一通瞎点,然后砰!的一下炸,游戏就失败了
扫雷的游戏界面是这样的:
最左边红色的数字就是这个棋盘里面埋了99个雷,右边红色的数字代表的是玩家所进行的时间
运气不好,点了两下就死掉了
调节一下游戏难度
现在这就是一个10x10的一个边框,里面含有10个雷的棋盘
这里先点击一下,出现了一个1
这个1的意思就是指,以它为中心的八个格子中有一颗地雷在附近
(因为没有找到合适的效果就重开了一把,大概就是这样)
看!这个游戏已经失败了,显示出来的雷中在1的周围只有1个地雷,数字1的意思就是在1周围的8x8的格子周围中只有一个雷(红笔所标示的)
当将所有没有雷的地方全部猜中,棋盘空间里的地方只剩下来雷的时候,就代表这个游玩玩家胜利
如图所示,8个1里围着一块空间,那这个空间的就只能是雷,棋盘已经除了是雷的地方已经全部被占满了,系统也提示了“you win!”的提示
那讲到这,扫雷的大致游戏原理我们就已经差不多明白了,接下来就开始实现它
首先引用头文件,输入主函数,自定义函数SAOLEI(我是学西班牙语的,英语菜的和屎一样)
#include<stdio.h>
int main()
{
SAOLEI();
return 0;
}
在做这一款扫雷游戏前我们先要做出这个游戏的游戏菜单,用do…while循环和switch分支的写法,来达到玩家玩完游戏后再玩一次和提供玩家选择的菜单效果(具体的可以看我上一篇博客中写道的三子棋,这里简要代过)
void menu()
{
printf("扫雷游戏\n");
printf("1,开始游戏\n");
printf("0,结束游戏\n");
}
void SAOLEI()
{
int inpunt = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入数字");
scanf("%d", &inpunt);
switch (inpunt)
{
case 1:
Saolei_s();
break;
case 0:
printf("结束游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (inpunt);
}
测试一下,大概的效果就是这样
可以根据自己的需求来制定界面,接下来就在case1的选项中自定义函数Saolei_s()来开始制作游戏内容
游戏内容我们分成两个步骤来进行说明:1,制作棋盘2,开始扫雷
我们这里来制作一个10x10的棋盘,但在这之前,我们先要搞清楚棋盘到底是一个什么样子的结构,通过我一开始的扫雷游戏讲解我们不难推出,扫雷这个游戏的棋盘组成是由两个棋盘构成的,分别是玩家输入的棋盘还有埋雷的棋盘
换一种理解方式的话,我们可以理解为:普通的笑脸是一个棋盘,而哭脸也是一个棋盘,我们把这两个棋盘都设置为数组,当输入的坐标是哭脸的雷的时候,我们就把它反映在笑脸的这个棋盘上,转成哭脸棋盘,就显示了失败的样子
同时我们还要注意的是,这个格子虽然看上去只有10x10,但要注意我们每输入一个坐标,就要显示周围的地雷数,如果就会显示出周围的地雷数,可如果我们输入的边框的坐标,就像这样:
那这里计算的也是他附近8x8的坐标,可是由于是边框位置的受限,它只计算了附近三个坐标的地雷数,实际上它计算的还是8个
因此我们不难推出,这个棋盘实际的模样是这样的:
一个9x9的棋盘,我们需要一个11x11的棋盘来作为内棋盘(用来放置地雷和计算周围地雷数),还需要一个9x9的棋盘用来给玩家进行操作
首先再一次定义主函数
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
为了方便打印和更改数字,我们就将其提前定义,同理既然是在原莱的树上进行扩大,我们也在原来的数字上加2即可
接下来在刚刚菜单分支一中自定义函数Saolei_s
void Saolei_s()
{
printf("开始游戏\n");
//布置好棋盘
char board[ROWS][COLS] = {
0 };
//布置好棋盘
char show[ROWS][COLS] = {
0 };
boards(board, ROWS, COLS, '0');//初始化棋盘
boards(show, ROWS, COLS, '*');
//打印棋盘
//DLYs_board(board, ROW, COL);这一个是内置雷区,用来布置雷
DLYs(show, ROW, COL);//只需要打印中间的那一圈(9X9)
//布置地雷
BUZHILEI(board, ROW, COL);
/*DLYs(board, ROW, COL);*///打印确认一下是否已经布置完毕
//扫描地雷
POOMPOOMPOOM(board, show, ROW, COL);}
}
定义里面布满地雷的棋盘(下面简称为雷盘,board)和玩家游玩的棋盘(接下来称为玩盘,show),然后开始棋盘的初始化,我们将雷盘放满0,玩盘放满1
void boards(char board[ROWS][COLS], int rows, int cols, char ret)
{
int i = 0;
int j = 0;
for (i = 0; i