[C语言]实现一个简易的扫雷

前言

  想必大家都玩过Windows7系统自带的扫雷吧!我们今天用C语言实现一个简易的9x9的简易扫雷,其中涉及到函数以及函数之前的所有C语言知识,写一个扫雷程序可以巩固我们的编程基础。

编译器:VS2022

扫雷的实现所需要的功能大致如下:

1、游戏菜单的打印以及开始游戏和退出游戏的实现。(实现可以多次游玩的功能)

2、设置两个字符数组,一个放入雷的数据,另一个放入棋盘的数据。

3、地雷的放置。

4、用户排雷的实现(统计周围雷数并显示、排到雷显示游戏失败)。

代码的编写

一、文件的创建

  用编程语言写一个简易的扫雷代码量也不少,我们需要使用函数封装不同的代码来实现扫雷的不同区块的功能。

  我们需要创建三个文件来管理我们的代码,一个头文件和两个源文件:分别是main.c、game.c和game.h

  其中main.c是游戏的主体,调用函数,整体逻辑清晰可见。

  game.h来定义我们的函数,方便我们寻找函数和管理函数。

  game.c来写让我们的函数具体实现的代码,这里是整个游戏的核心。

二、打印游戏菜单、选择开始和结束游戏

  我们来到main.c游戏主体这个源文件来先进行菜单的打印。因为玩家打开扫雷就要进行开始游戏和退出游戏的选择,所以要用do-while循环实现游戏的多次游玩和退出。

具体代码如图所示:

运行结果如下:

三、初始化雷和棋盘的字符数组并通过函数实现打印

  来到这里,玩家肯定是选择了开始游戏了,所以我们把实现扫雷的代码封装在game()函数里,并在game.h里面声明该函数对函数进行管理,在game.c里面编写代码实现该函数。然后我们要创建两个字符数组,分别是mine(雷)和show(棋盘)并对其初始化(函数名:init)。mine数组里面'0'代表不是雷的方格,'1'代表是雷的方格;棋盘数组show里面‘*’表示没有排查的方格;我们还需要一个打印棋盘的函数(print),将我们的棋盘打印出来,检查我们初始化的雷数组和棋盘是否正常初始化。

那我们9x9的简易扫雷是不是要创建两个9x9的二维数组呢?不是!

如果我们点击了某个坐标的方块,我们需要对其周围8个方块对雷的数量进行统计,如果我们只将数组设置为9x9的大小,那么我们选择对第一行、第一列、最后一行、最后一列上的方块进行排雷时,我们统计周围的8个方块就会出现数组越界的情况。

数组越界:(阴影部分为越界()

那么我们如何解决上面的问题呢?答案是设置一个更大的11x11的数组,让其雷和棋盘只放置在其9x9的区块上,这样的话我们对第一行、第一列、最后一行、最后一列上的方块进行排雷时就不会出现数组越界的情况。

我们在玩扫雷时需要输入坐标 x和y,他们大小都是1~9;而我们的数组下标都是0~10,为了更好的管理数据,我们引用VS的功能,宏定义来管理数据!

ROW代表行数 COL代表列数。

具体代码实现如下:

运行结果:

这个时候我们可以看到雷数组和棋盘数组都已经初始化完毕,为了游玩的方便性,我们对打印函数进行修改,对棋盘打印的排版进行调整,我们在打印棋盘的时候打印出坐标轴来方便玩家进行坐标的选择,同时对应的坐标位置的字符坐标和数组的下标对应相同:

代码修改和运行结果:

四、在mine数组里面放置10个雷

我们在将字符'1'存储在mine里面代表雷,我们需要写一个放置雷的函数(setmine)

需要进行的代码操作是生成一个随机的坐标并将雷放入这个坐标,当放置的雷数量达到10时停止放置,所以我们需要生成随机数来生成随机坐标。而且我们需要用if函数判断这个坐标是没有放过雷的才放置雷,不然重复随机生成的坐标可能会重复,而导致同一个坐标放置多次的雷,导致最后结果雷的数量少于10,放完雷后我们可以利用前面写过的打印函数print将雷数组打印一下看看雷的排布是否正常。

具体代码如下:

运行结果如下:

五:玩家排雷/统计雷/用户获胜与失败

当我们放置好雷后,我们需要写一个排雷的函数(findmine)来响应玩家的排雷。我们需要创建一个循环,读取一个坐标,先判断坐标是否有雷,如果有雷则宣布游戏失败并跳出循环。如果不是雷,则对坐标周围八个坐标的雷数进行统计,我们需要一个函数获取坐标周围雷的个数(getmines)并且打印在棋盘上,供玩家获取雷的信息。我们还要设置玩家获胜的条件。我们在读取玩家坐标时,还要用if语句判断一下输入的坐标是否非法,如果是,要玩家重新输入正确坐标。

getmines函数获取周围雷的个数的方法:

我们都知道字符都有对应的ASCII码值 比如'0'的值为48 '1'的值为49

我们可以将字符的ASCII码值转化为整数,通过 '1'-'0'=1来获得周围雷的个数,同理,当我们知道周围雷的个数后,我们可以通过 '0'+n(雷的个数)来转化为字符数字。

假设箭头所示位置为玩家输入的坐标对应的位置(x,y),则我们可以用上述方法将(x,y)坐标周围八个位置的字符数字各自减去字符零的和来获取周围雷的个数,.即:mine[x-1][y-1] - '0' + mine[x-1][y] - '0' + mine[x-1][y+1] - '0' + mine[x][y-1] - '0'+ mine[x][y+1] - '0' + mine[x+1][y-1] - '0' + mine[x+1][y] - '0' + mine[x+1][y+1] - '0'

我们还以在打印新的棋盘前用system("cls");将原来的棋盘清屏,增加游戏体验感。

具体代码如下:

运行结果:

就这样我们这个简易的扫雷就做好了!

总结

这是个简易的扫雷,非常简易,而且有很多的不足之处。

1、

其中最大的不足之处就是判断胜利的方式,虽然有10个雷,玩家排查71次后就可以获得胜利,但实际上如果玩家不小心在排雷过程中排查了相同的坐标,那么离胜利的次数也是会减少的,也就是说玩家很有可能没有把雷拍完就获得了胜利。可以通过统计棋盘中*的数量来判断玩家是否胜利,如棋盘中只剩下10个星号(星号都是雷),那么玩家胜利。也可能有更好的判断胜利的方式。

2、   不能够将排查的位置不是雷,周围也没有雷的情况下将棋盘展开一片,所以玩家要苦逼的展开71次才能获得胜利。由于编者能力有限,这个功能还不能够实现。

3、拓展:还可以加上标记雷和显示排雷时间的设计。

以上就是编者带给大家的C语言实现简易扫雷的方法,如有错误请指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值