前言:扫雷这个游戏相信大家都玩过,小时候条件好一点的家里有电脑的,电脑上都是自带的游戏,《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。

游戏说明与准备

游戏如下:

我用c语言实现一个比较简单的扫雷

如下:

首先我们创建三个文件:分别为 game.h game.c test.c

一个头文件两个源文件,文件的名字无所谓,最后加个.c或.h的后缀自己知道即可

打开 vs2019或者vs 2022版本,当然使用不同编译器也是可以的

这里说明一下各个文件的作用:

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

game.c ⽂件中写游戏中函数的实现等

game.h ⽂件中写游戏需要的数据类型和函数声明等

讲一个游戏模块化,这样便于后面的游戏的调整,别人看着也一目了然。

我们先讲一下游戏的思路,玩法大家想必是很了解了,用代码如何实现它

我们拿简单版本的举例:

扫雷的棋盘是9*9的格⼦ 默认随机布置10个雷可以排查雷 。如果位置不是雷,就显⽰周围有⼏个雷 。如果位置是雷,就炸死游戏结束 。把除10个雷之外的所有⾮雷都找出来,排雷成功,游戏结束

分析和设计:

扫雷的过程中,布置的雷和排查出的雷的信息都需要存储,所以我们需要⼀定的数据结构来存储这些信息。

因为我们要用类似阵列的方式来展现一个简单的游戏界面,这里当然我们要采用二维数组最合适不过了。我们需要在9*9的棋盘上布置雷的信息和排查雷,我们⾸先想到的就是创建⼀个9*9的数组来存放 信息。

如果这个位置存放雷,我们就设置为1,不是雷设置为0。

假设我们输入坐标(4,6)它就会访问周围八个方框的雷数,统计周围雷的个数3,但是假设我们输入(9,9)最右下角的行列坐标就会越界,解决的最好方法就是创建的数组为11*11,这样能够解决越界的问题。

继续,我们在棋盘上布置了雷,棋盘上雷的信息(1)和⾮雷的信息(0),假设我们排查了某 ⼀个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录 存储,并打印出来,作为排雷的重要参考信息的。那这个雷的个数信息存放在哪⾥呢?如果存放在布 置雷的数组中,这样雷的信息和雷的个数信息就可能或产⽣混淆和打印上的困难。

这里采取一种解决办法,我们不妨在一开始就创建两个数组一个数组命名mine全部初始化为0,一个数组命名为show全部初始化为*,当然命名什么都可以,这⾥我们肯定有办法解决,⽐如:雷和⾮雷的信息不要使⽤数字,使⽤某些字符就⾏,这样就避免冲 突了,但是这样做棋盘上有雷和⾮雷的信息,还有排查出的雷的个数信息,就⽐较混杂,不够⽅便。 这⾥我们采⽤另外⼀种⽅案,我们不妨在一开始就创建两个数组一个数组命名mine全部初始化为0,存放布置好的雷的信息,一个数组命名为show全部初始化为*,当然命名什么都可以,存放排查出的雷的信息。这样就互不⼲扰了,把雷布置到 mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期 排查参考。mine数组如果是雷改成1,不是雷的还是0,周围雷的个数赋值给对应的show数组

mine show

假设我们在输入坐标 (6,2)和(4,6)与之对应的show数组对应就是0与3

游戏代码

test.c

这里用do……whlie循环是因为进行上来就执行一句自定义meun()函数打印游戏菜单,循环通过键盘输入的input值来决定,switch也是通过input来选择游戏的开始与结束,输入1进入上面的游戏,0结束游戏,每个分值语句后面跟一个break养成好习惯。

game()游戏函数里写游戏运行的代码

1.先初始化两个数组

2.打印出来看看是否符合自己的预期

3.在mine数组上布置雷随机布置,可以打印出来看看是否符合预期

4最后就是排雷

game.c

这里是函数的自定义,就是说明这个函数的功能

在设置雷的那里用了rand这个库函数函数这个函数一般是要与库函数srand结合的,引用头文件#include ,这个函数的作用就是会随机生成一个数字范围是0-32767但是单独的用rand每次产生的随机数是固定的就相当于一个伪随机值,srand的作用是设置了一个起始值如果单独的输入100 200等常数还是不能达到那种随机的效果,于是就在上面用了一个时间戳的概念因为时间是随机变化的,就能保证起始值是随机变化的,这样产生的随机值就会不同。

在排雷的过程中,如果这个不是雷想要统计周围雷的个数假设这个坐标为(x,y)那它的周围坐标

如下:

初始化为字符0,它的Ascll值对应的数值为48,减去就是数字0,这样赋值给对应相同坐标的show数组,然后打印出来

运行如下

game.h

这里是对自定义函数的生命,相当于自己做了一个库函数,前面两个文件引用的头文件#include ”game.h”

对应#define定义的数赋值以便于后面玩家想要调难度,相较于程序中一个个的找去修改方便许多