基本功能
游戏目的:输入坐标检查该坐标周围的雷的数量,并返回一个数字在该坐标上。如果检查到炸弹就退出游戏,如果出了炸弹都被检查完了就胜利。
功能实现
添加所需头文件:
在game.h添加所需要的头文件(后面会讲)
分别在game.c和test.c中添加game.h,这样无论需要改什么或者添加什么功能只需要改game.h中的内容就行。
游戏功能菜单的打印(这个就不多赘述了吧):
初始化棋盘
分析所需要的行和列:
如图,我们需要在一个9*9大小的棋盘排查雷,由于我们需要排查每一个雷的周围的雷的数量,所以当在边界的情况下,可能会查出棋盘的界限(如下图所示):
下图是我们想要排查雷的周围的坐标示意图:
如图如果我们排查的雷的坐标如上图的(1,1)的话,那么我们肯定会超出界限的,所以我们初始化棋盘的时候,就应改多初始化一点.
如下图,在初始化棋盘时,我们分别在上下左右四个方向增加一行(一列)这样我们在排查像(1,1)这个坐标的周围时就不用担心超出界限了。
代码如下:
此时处于测试阶段,所以放置雷的棋盘我还是打印出来了,为了方便区分,增加'----扫雷游戏-------'这个 分割线。
如图所示,放置雷的棋盘我初始化为字符0,待会用字符1来表示炸弹,因为是char类型的数组。所以用字符数字,排查雷的棋盘初始化为'*',来表示未被排查。
放置雷
首先,放置雷是随机放置的,所以需要用到rand()函数。
以下个人理解:
头文件:
rand()-->#include<stdlib.h>
time()-->#include<time.h>
官方说明:
代码如下:
此时,放置雷的棋盘随机出现了十个字符1表示炸弹。
排查雷
排查雷我们定义一个FindMine()函数来表示 ,get_mine_count()来表示你要排查的坐标的周围的雷的数量,返回一个int整数。上图表示我们要检查周围的坐标,(x,y)是输入坐标。
注意:这里我们的每个元素都是字符,所以我们把这周围8个坐标的值加起来(不是'1'就是'0'),因为字符1-字符0就是1,所以我们再减去8个'0'(字符0),这样周围有几个雷,它就会返回几(列:有一个雷就 return 1),这里的是int类型但是我们存放到棋盘中的是字符,所以如果周围有雷我们就把这个返回数字再加上一个字符0,这样我们就可以把周围雷的数量存进去了,不加上字符0的话,就显示空白。
代码如下:
如何排查的坐标是字符1,就被炸死,退出游戏。
赢
此时,我们还不能赢,下面添加赢得条件:
如果排查的雷等于我们各自的个数-炸弹的个数,我们就赢了。
红线部分就是添加的win(排查雷的数量),EASY_COUNT-->炸弹数量,row*col-->格子的总数
最后把红线这个显示雷的位置函数注释,开始游戏,效果如图。
至此基本扫雷完毕。
添加展开一片与标记功能(可取消)
类似这个效果
标记,就是这样子,我们用别的符号代替,每次排查完后,输入1进行标记,符号为!,输入0不进行标记,标记的总数量数量为雷的数量。
展开一片:
展开一片就是我没要检查每个炸弹的每一个方向上的每一个方向的雷的数量
如下图:
这里先说一下展开一片的前提条件:
1.该坐标不是雷
2.该坐标没有被排查过
3.该坐标周围没有雷
我们要检查(x,y)这个坐标周围的雷的数量,如果没有雷就继续检查周围每个坐标的周围,如下图的(x-1,y-1),我们继续检查他的周围如果还是没有雷就继续检查下去,同时这个(x-1,y-1)这个坐标我们用'_'来表示没有雷,如果有雷呢,我们就用上面的get_mine_count()这个函数来计算他周围的类书,并返回去,加上以'0',存放进数组中。这里就要用递归实现了。
递归的限制条件就是上面的前提条件了
代码如下:
不是雷这个条件必须加啊!!
不然就会这样:红色圈出来的部分本来是雷,莫名奇妙的就会被变为' '(这个是我出这个问题是找的别人的代码,他竟然也有这个问题,就是因为没加上这个限制条件)
标记和取消标记
这里标记的函数写成一个switch循环,输入1再进入标记实施的函数,输入0直接退出不标记
这里我把标记和取消标记写一块了,加一个flag状态,标记了flag有0->1,然后才可以取消标记,标记符号用 ! 来表示。,同时标记的时候mine_count减一,取消标记mine_count加一,mine_count就是能标记的总数量==炸弹的数量。
所以这里当mine_count>0是才能标记。
游戏效果展示:
--->
----->
加个清屏看着还是很舒服的^_^。