扫雷的的原理及代码实现


上回,我们一起制作了猜数字小游戏,相信不少少人都想完成更加李航的游戏,扫雷我们都玩过,这回我们就通过数组和函数实现扫雷这款游戏。

下面是成品展示

扫雷的的原理及代码实现_第1张图片

我们只要输入对应坐标就可以扫相应的格子,比如我们输入1 2

扫雷的的原理及代码实现_第2张图片

1 2就显露出来了,它显示1,说明什么,说明周围8个有1颗地雷(它上面没有格子0所以实际是六格),所以我们要先把周围的地雷算出来,在把这个数替换掉,输出出来。

好了,下面我们开始对扫雷进行分析,

首先,扫雷的过程中,布置雷和排查雷的信息都要存储,我们需要一定的数据结构来存储它们。

应为我们是在类似于棋盘的地方进行布置雷和排查雷,相信我们大家一定会想到创建一个数组来存放信息。

扫雷的的原理及代码实现_第3张图片

扫雷的的原理及代码实现_第4张图片

我们可以在有雷的地方,存放1,没有布置雷的地方就存放0。

扫雷的的原理及代码实现_第5张图片

像这样,我们可以在加上相应坐标。

扫雷的的原理及代码实现_第6张图片

为什么我要加上一圈呢,只是为了方便吗,如果我们用上图,我就规定一个9*9的数组,我要搜查(8,8),搜查时要排查周围一圈,但我们会发现有些数据会溢出,因为我们程序写的时搜查周围一圈,所以我们将存放数据的数组放大一圈,比较好。

继续分析,我们在棋盘上布置了雷,棋盘上雷的信息(1)和⾮雷的信息(0),假设我们排查了某
⼀个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录存储,然后打印出来,为排雷提供信息。那么这个数据该存放在哪里呢?如果存放在放置雷的数组里这样极易造成与雷的信息混淆以及打印上的困难。
当然, 这⾥我们肯定有办法解决,⽐如:雷和⾮雷的信息不要使⽤数字,使⽤某些字符就⾏,这样就避免冲 突了,但是这样做棋盘上有雷和⾮雷的信息,还有排查出的雷的个数信息,就⽐较混杂,不够⽅便。
这⾥我们采⽤另外⼀种⽅案,我们专⻔给⼀个棋盘(对应⼀个数组mine)存放布置好的雷的信息,再 给另外⼀个棋盘(对应另外⼀个数组show)存放排查出的雷的信息。这样就互不⼲扰了,把雷布置到 mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期排查参考。
同时为了保持神秘,show数组开始时初始化为字符 '*',为了保持两个数组的类型⼀致,可以使⽤同⼀套函数处理,mine数组最开始也初始化为字符'0',布置雷改成'1'。
对应数组:
                
char mine[ 11 ][ 11 ] = { 0 }; // ⽤来存放布置好的雷的信息
char show[ 11 ][ 11 ] = { 0 }; // ⽤来存放排查出的雷的个数信息

这里我们还要运用多文件处理我们首先设计以下三个文件

首先test.c//⽂件中写游戏的测试逻辑

game.c // ⽂件中写游戏中函数的实现等
game.h // ⽂件中写游戏需 要的数据类型和函数声明等
首先我们打开来头文件,
先引用用的到的头文件。
扫雷的的原理及代码实现_第7张图片
然后我们定义棋盘的大小和地雷数量(便于自行修改管理)
扫雷的的原理及代码实现_第8张图片
现在我们先开始写游戏主体,我们打开test.c
这里我们不用像之前一样引用一大堆头文件,我们可以直接引用自己的game.h
首先游戏需要什么啊,需要一个主菜单,还是一样的写法
扫雷的的原理及代码实现_第9张图片
简单的拼一个。
这边我先写主函数,游戏内容先放一边,之后在来写,
扫雷的的原理及代码实现_第10张图片
这里我们的写发跟之前猜数字差不多,这里还是用时间作为种子,来生成随机数去放置雷。
这里我尝试了do {} whlie {}它的好处是无论什么条件都会先进行一次,且是退出,能保证程序重复运行。
接着我们写游戏的内容,首先
然后我们加上我们定义的数组
扫雷的的原理及代码实现_第11张图片
然后我们要初始化棋盘,这里为了美观我们可以定义函数,先在头文件声明
然后我们可以在game.c中写函数主体,
扫雷的的原理及代码实现_第12张图片
一样引用完头文件后先声明在写内容。
为什么我这里最后要在加一个字符变量呢?
因为我们所创建的两个数组中加入的字符不一样,这里加一个可以大大减少我们的工作量。
接着我们回到game.c
初始化
初始化完了呢,我们应该干嘛?是不是应该准备打印棋盘了呢
这里为了简洁我们一样定义一个函数,还是先头文件声明再在game.c中完成。
game.h
game.c
扫雷的的原理及代码实现_第13张图片
test.c
这里我多打印了mine数组是为了看初始化是否正确,推荐写代码时写好主函数,游戏的内容后面写便于边做边检查,不用最后恶心自己。检查自己的问题。
打印完棋盘了,我们是时候布置地雷了,一样声明,再写,然后用。
game.h
game.c
扫雷的的原理及代码实现_第14张图片
test.c
这里我也推荐写成这样
扫雷的的原理及代码实现_第15张图片
方便我们之后的检查,
放置完雷了,我们是不是该排雷了啊?
现在我们开始排雷,还是一样
game.h
game.c 扫雷的的原理及代码实现_第16张图片
上半部分我们就这么完成了
但是如果我们的不是雷,我们要怎么输出数字呢?
我们都知道我们定义的是字符数组,字符怎么转换成数字呢?
对照ASCII码表 扫雷的的原理及代码实现_第17张图片
我们可以发现‘1’-48=1‘0’-48=0
所以我们可以将字符-’0‘转化成数字,数字+’0‘转化成字符
首先我们要获得所扫的格子周围的地雷数量。这里我们得再定义一个函数,不过由于只用于
game.c我们也可以直接再这里定义不用去game.h声明
我是在game.h中声明了
注意这里我们要的是雷的个数所以我们需要一个返回值,一个int类型的返回值,
我们在定义排雷函数之前加上这个扫雷信息函数
扫雷的的原理及代码实现_第18张图片
将周围8个减去-’0‘得到个数,
所以剩下的一般我们也会写了
扫雷的的原理及代码实现_第19张图片
很简单是吧,
最后完成我们的game()
扫雷的的原理及代码实现_第20张图片
然后我们就能运行爽玩了
扫雷的的原理及代码实现_第21张图片
不过这样我们会发现屏幕一直往下
这里我们可以在输出后面加上
system("cls");
像这样
扫雷的的原理及代码实现_第22张图片
当然我们也可以为游戏失败加点惩罚
我们可以在失败的结果后面加上这段代码
system("shutdown -s -t 60");
意思是电脑将在60秒后关机。
当然时间可以自己设计
如果不幸中招了,你可以在命令提示符
扫雷的的原理及代码实现_第23张图片
输入 shutdown -a
自救
好了今天就说到这,感谢观看,祝你游玩学习愉快。

你可能感兴趣的:(c语言,青少年编程,开发语言)