1.前言
前几天我们介绍了三子棋游戏,今天我们来学习怎么制作一个简单的扫雷游戏。建议看之前先简单了解下扫雷的玩法。
2.准备
创建一个测试模块(test.c)和一个游戏模块(game.h和game.c),game.h用来声明函数,game.c用来实现函数。
3.要求
- 支持反复玩
- 给予提示
- 提高可读性(为玩家提高必要的信息)
- 不要把代码写得太死(提高代码的可移植性)
4.思路
4.1提供菜单
- 老规矩,给玩家菜单选择。
- 提醒玩家输入,并且根据玩家的选择给予不同的结果。
- 在我们学完函数后,我们一般我们就把特定的功能交给函数,比如我们就把测试功能交给test,把游戏部分的功能交给game。
- input作为while的判断表达式有好处,当你选择1为真就进入游戏,当你选择0就为假退出游戏,当你选择非0非1后还是为真,继续输入,直到输入1或0为止。
4.2创建“棋盘”
假设玩家要玩9*9格的扫雷游戏
- 首先我们就得提高一个9行9列的二维数组(MineBoard)来布置雷,另一个二维数组(ShowBoard)显示玩家扫雷的情况(即周围有多少雷)。
- 这两个二维数组的规模应该是完全一致的。因为在玩家输入坐标后,我们要在布置雷的二维数组中将情况(周围有几个雷)传递给显示雷的二维数组相同位置。如玩家输入2 2,我们就在MineBoard中2 2的位置扫描有多少雷,然后把雷的数目放到ShowBoard中2 2的位置。
- 但如果我要玩16*16模式的扫雷怎么办,难道每遇到这两二维数组就把9改为16,这未免太麻烦了,所以得在头文件中定义两个常量行和列(ROW和COL)。为什么在头文件定义?在头文件定义,然后包含下头文件,这样两个源文件就能使用这两个常量。
- 现在我们来想想在MineBoard中,雷和非雷的地方应该布置为什么?
在ShowBoard中,玩家未排查雷时应该把二维数组初始化为什么?排查后的数字1~9是整形还是字符?
因为两个数组尽量一致,所以得从需求最紧迫的那个数组下手。
我们把雷设置为‘1’(字符的1),没有雷设置为‘0’(后面会讲原因)。既然MineBoard是字符数组,那ShowBoard也得是二维数组,所以排查后的数字是字符类型的,那未排查我们就用*来初始化数组。 - 已知玩家输入坐标后就要把这个坐标周围的8个坐标中雷的数目放在这个位置。
圆圈是玩家输入的坐标,正方形是要排查的8个坐标。
那如果出现以下情况该怎么办?
如果还是先前讲的那种方法不就数组越界了吗?
这时我们就要拓宽数组的范围,如图
把9 * 9变成11*11,在数组的左右上下都增加1行(/列),然后我们就在中间的9 * 9格中操作就行了。
4.3初始化数组
老规矩,在game.h中定义函数,在game.c中实现一个函数。
因为MineBoard和ShowBoard两个都要打印出来看看,所以我们定义和实现函数时,函数的参数我们都定义为board。
但我们发现这两个数组要初始化的内容不一样,这不就意味着要一个函数无法兼顾两份需求,得重新创建一个函数来打印吗?
其实我们只要把我们要初始化的内容传过去即可。
代码实现
4.4打印数组
数组的打印是给玩家看的,所以只需打印中间9 * 9格。
但数组的规模没有改变,还是11 * 11。
代码实现
但这好像不利于玩家读取坐标啊,得慢慢数几行几列。所以我们得提供横纵坐标给读者。
接下来我们就把打印MineBoard给删掉,毕竟我们不能把雷在哪告诉玩家吧。
4.5布置雷
写一个函数来设置雷。
我们需要得到随机的坐标来设置雷,这个坐标得在中间的9*9格中(我们需要用到rand,srand,time等函数,这些在猜数字,三子棋中都有用到,感兴趣可以去看看)。
记得包含头文件(stdlib.h和time.h)
因为我们要布置的雷的数目是可改变的,所以我们就直接定义常量。
判断这个坐标是否被占用
当位置未被占用,count再减1。
这是雷的位置
4.6排查雷
把在MineBoard中得到的周围炸弹个数传给ShowBoard,放在ShowBoard相应的位置。
先写一个函数来排查雷
提示玩家输入要排查的坐标
判断该坐标是否在范围内,以及该坐标是否已被排查。
利用循环,直到输入符合要求才退出循环。
判断该坐标是否是雷,如果是,为了让玩家死得瞑目,把布置雷的二维数组打印出来;如果没被炸死,那就写一个函数,返回周围雷的数目,提示周围有几个雷。
因为函数返回的数字是整形的,而放在show数组的数字是字符的,所要加上‘0’,变成字符的数字
找到坐标周围的雷,将他们加上来,然后减去8个‘0’。
这就是将数组初始化为‘0’和‘1’的好处。
将玩家的排查情况打印出来
4.7判断输赢
当你把除了雷之外的所有坐标排查完,你就获胜。所以我们可以设置循环的条件就是一直排查坐标直到只剩下雷为止。如果雷有10个,规模为99的格子,那么需要排查99-10次,也就是循环的次数。而只有玩家排查成功(即坐标在范围内,没有被占用)才算成功。
4.8测试
5.总结
一个简单的扫雷游戏就这么完成了,后续不知道会不会有优化的版本(有时间就搞)。如果有什么地方讲的不对,请指正。感谢!