一:扫雷游戏的思路
1.棋盘的打印
首先我们想到可以使用二维数组来打印棋盘,数组元素使用0和1表示该位置是否为雷,考虑到后续在排雷阶段与周围雷的数量产生混淆,所以我们使用两个数组分别容纳这两个信息,分别表示棋盘的雷的布置和该位置周围雷的数量。
但是在棋盘的边缘位置时,计算该位置周围的雷的数量显然会越界访问,所以我们可以在原有规模的棋盘的基础上,在外围加上一圈,也即是二维数组的行列都加一,为了后续排雷时更加简便,可以将添加的一行一列补为数字,使后续排雷时更加简便。
2.两数组的初始化和作用
现在,我们要明确两个数组的作用,mine数组用来存储雷的布置情况,我们将它的元素初始为符号‘0’,在后续的布置雷的步骤后,表示雷的元素我们将其赋值为符号‘1’,show数组我们将其全部元素初始为符号‘*’,在保持游戏的神秘感的同时,也使两个数组的初始化更加简便(初始化赋值都为字符),show数组也是我们游戏过程中必要打印的数组,也即是我们的棋盘,每排查一次雷后都会打印一次show数组,而排查的位置在排查后应被赋值我这个位置周围的雷的个数,这样,我们基本实现了排雷游戏的基本逻辑。
综上,扫雷游戏的实现逻辑基本可以被分为①布置雷(分装到mine数组中)②计算每一个位置周围的雷(数据存放在show数组中)③排查雷(根据二维数组以坐标的形式排查你的目标位置)④根据排查的结果继续你的排雷直到游戏结束。
二:扫雷游戏的具体实现
1.打印棋盘
由前文可知,我们要在需要打印的棋盘上多增加两行两列以确保在计算数组边缘位置周围的雷个数时不会产生越界访问,并且有利于排雷步骤,以需要9*9的棋盘为例,我们需要的结果如下图:
这里我们看不出增加了两行两列,实质上其中的一行一列是作为空白存在被打印出,在布置雷时只在中间的9*9星号中实现。值得一提的是这里产生了初始化棋盘和打印棋盘这两个函数传参时的差异:
2.布置雷
我们在mine这个二维数组中布置雷,布置雷的位置(元素)被赋值为字符‘1’,非雷处则仍为字符‘0’,雷的布置必须是随机的,由于是二维数组,我们用坐标来表示一个元素的位置(x,y),所以我们要随机出两个数字,这两个数字的范围也要在我们需求的棋盘范围内,以9*9棋盘为例:
很明显,x,y的范围要在1~9之间,随机数产生的实现,C语言提供rand函数,用来初始化随机数生成数,但是rand函数依靠算法生成随机数,它产生的随机数是一个范围内会重复出现的伪随机数,C语言还提供一个函数srand用来初始化随机数的生成器,在调用rand函数之前先调用srand函数,通过srand函数的参数seed(种子)来设置rand函数生成随机数时的种子,但是这又要求srand的种子是随机的,这似乎很矛盾,我们需要随机地生成一个数,但是又需要我们提供一个随机的种子,但可以换一个角度,我们可以提供个永不重复(不断变化)的数,把它作为srand函数的种子,这样我们就可以得到一个“随机”的数,一个不断变化且没有规律的数字不就是一个随机的数字嘛!C语言提供一个库函数名为time,这个库函数的参数是指针类型,当这个指针为非空指针时,time函数将返回一个差值(1970年1月1日至今程序运行的时间的差)放在参数指向的内存,但是当time库函数的参数是空指针(NULL)时,它将只返回这个差值(也称时间戳),这个差值不断变化且不会重复,将它作为srand的种子,这样设置出的rand函数也将产生真正的随机数:
我们将生成两个这样的随机数 x和y,他们的组合就可以覆盖整个数组,假设我们要布置10个雷,就需要重复10次,10次之后结束布雷。
3.计算每个位置周围雷的数量和排查雷
完成了雷的布置之后,我们就需要排查,因为雷的布置玩家不清楚,不打印mine数组(棋盘)我们也不会清楚,在随机选择一个位置排查时,如果这个位置被埋雷,那么游戏也就结束,我们还可以这个时候打印mine数组(棋盘),给玩家明示雷的布置情况,如果该位置没有雷,该位置(元素)需要赋值为周围雷的个数,游戏继续。
这时,我们就需要实现计算每个位置周围的雷的数量,这会产生一整个的二维数组,我们需要将数据存储在show数组(棋盘)中,在排查后一一显现。那么,如何计算出每一个位置周围的雷的数量呢?
我们只需要计算周围八个元素的值,我们一开始讲到就将为所有的元素赋值为字符‘0’,将为雷的元素赋值为字符‘1’,所以我们只需要计算出八个元素为字符‘1’的个数:
如果玩家成功排除出10个雷,在我们这个较为初级的版本中也就是玩家将9*9数组中的除10个为雷的元素外,其余的71个非雷的元素全部排查一遍 ,这时玩家才在赢得游戏的情况下结束了游戏
(这只是最初级的扫雷理论基础,只满足操作者选择位置排雷,胜利完成游戏的可能性和游戏的可玩性都较低,在我们所熟知的排雷游戏中,玩家不仅可以将确定的雷的位置标记,还能选择游戏的困难程度,你是否注意到有时会出现点击一下出现大片空白的情况,这是程序直接将周围雷的数量为零的元素直接跳过排查,这极大的提高了游戏的可玩性,当然以我目前的知识储备还不能实现这些功能,毕竟这只涉及到了C语言函数和数组的知识,希望能够帮到你)