1.游戏可以通过菜单实现继续玩或退出游戏
2.扫雷棋盘先按9*9的格子实现
3.默认随机布置10个雷
4.在排雷过程中,如果位置不是雷,就显示周围有几个雷,如果位置是雷,就炸死结束,把除10个雷之外所有的位置都找出来,游戏结束
1.准备工作
首先创建1个头文件和2个源文件,分别是game.h和game.c,test.c
geme.h主要作为函数声明,常变量的赋值
game.c作为函数功能实现的文件,主要对不同函数进行编写
test.c主要作用是通过各个函数相结合,以及对头文件的包含,实现扫雷程序
为了主函数内部简洁,方便后续增删查改,我们将在test函数内部实现。
1.1程序运行的基本框架
首先在test.c中把菜单打印出来,并运用do...while语句对输入的数做一次判断,为0则while判断为假,根据菜单则视为退出游戏。
之后我们在case1:中添加game()函数具体执行排雷过程
1.2两个字符数组的编写
我们需要11*11二维数组来当作棋盘,实现9*9的扫雷游戏,在9*9的棋盘中每一个元素,’0‘(字符)为空位置,‘1’(字符)为雷,在排查时直接把一圈的元素加起来就是该位置周围雷的数量,
为什么要创建11*11的数组呢?
我们考虑到排雷过程中遇到边缘的情况,例如 创建9*9的二维数组(棋盘)排查第8行第8列的位置时(数组元素下标从0开始),其位置是正方形棋盘的右下角,应显示周围一圈雷的数量,但发现第7行第9列,第9行第9列......等,这些位置超出了范围。因此我们索性创建11*11的二维数组,上下左右多出一圈并把里面所有元素初始化为0
但这还不够
我们需要两个二维数组来完成,一个放布置好雷的信息(取名为mine),也就是里面每个元素都由‘0’或‘1’组成的数组,另一个二维数组存放排查出雷的信息(就叫他show),也就是玩家输入坐标后显示周围一圈有多少雷的二维数组(棋盘)
为了我们之后可以轻易该改变棋盘大小,增加可玩性,我们用define在头文件里定义ROW为行,为9;COL为列,为9
再定义ROWS等于ROW+2为11;COLS等于COL+2为11。这样我们在改动时只改ROW和COL就行了。
2.初始化函数的编写
初始化mine数组为字符'0',初始化show数组为‘*’ 。因此我们需要写一个初始化函数InitBoard()
并在game.h中声明,game.c中包含game.h并实现,test.c中使用。
此函数可以在使用时可把数组初始化为,什么字符或什么数字,为此我们可以用它分别初始化两个数组。
3.打印数组(棋盘)函数的实现
接下来我们可以编写数组打印函数DisplayBoard()。顺便看看数组初始化怎么样。依旧头文件声明,game.c文件实现,test.c文件使用
在编写函数时无需把原9*9棋盘外的一圈(11*11的数组)打印出来 。
但为了方便玩家看清坐标,我们可以为其加上行号和列号
发现和我们预想的一样后先注释掉,后边还会用到。
4.放置雷的函数的实现
接下来我们通过SetMine(),在9*9的棋盘上随机布置10个雷,依旧同文件声名,test使用,game.c中编写,把雷放在mine数组中,只放在9*9的棋盘中因此要用ROW和COL传参。
在放置雷的过程中我们需要再用define定义一个常变量 EASY_COUNT 方便我们更改雷的数量,这里先设为10。
包含头文件time.h和stdlib.h
通过生成随机数x和y在9*9的棋盘里充当随机坐标放置雷(‘1’),为使随机数在范围内我们让rand()生成的数取模row或col(也就是9),得数在0到8之间,在加1,便可控制在1到8的范围内,对应棋盘的坐标。
rand在使用时要调用srand,所以我们把srand放在,放置雷函数使用前。也就是test.c中。
但是在生成坐标时有可能重复,我们要提前进行判断他是否是‘0’,为没放雷的地方
此时,再把show数组打印一遍告诉玩家还有那些地方没有排查
接下来进入排查雷的操作。
5.排雷过程的实现
5.1声明
5.2使用
5.3实现
5.3.1判断输入坐标是否为雷
首先要判断玩家输入的坐标是否在范围内,因此先进行判断
如果判断为有效坐标则判断该坐标对应mine数组中是否为雷(‘1’),如果是则游戏失败,并把布置雷的信息打印出来(也就是用之前编过的打印函数把mine数组打印出来)
5.3.2统计输入坐标一圈雷的数量
接下来我们判断如果输入的坐标不是雷,那就得统计该坐标周围一圈8个位置有几个雷(也就是有几个字符1)。为了方便排错,我们把统计雷的工作单独编写一个函数 GetMineCount() 这个函数要去mine数组里找有几个雷。此函数仅仅为了排雷,所以直接在game.c里实现就行,现在我们先把框架摆在这里
GetMineCount()在FindMine()中的使用情况
实现GetMineCount()
第一步:我们通过x,y坐标来获取周围一圈的坐标,例如x-1,y-1;x+1,y+1等等进行统计,那个坐标对应的数组元素是‘0’还是‘1’
第二步:字符 ‘1’ 的ASCII码值是49,字符 ‘0’ 的ASCII码值是48,我们在统计时只需将对应坐标的字符‘0’或‘1’,减去‘0’(也就是48 - 48或49 - 48),再把周围一圈分别减去‘0’的得数相加,便可知雷的数量
之后我们把返回雷数量的值放在show数组对应位置,注意show数组是char型,因此我们还需把得数加上字符‘0’,得到对应数字字符,再放到对应show数组坐标中,之后把show数组打印一遍呈现给玩家
针对GetMineCount()函数我们也有不同方法实现
利用两个for循环嵌套,把9个元素遍历减去字符‘0’再相加
5.3.3胜利的条件
接下来我们设置胜利条件(也就是把除雷的地方全部排完)row*col(也就是9*9)减去雷的数量EASY_COUNT 得没有雷的位置,的数量。 在程序中我们排一个雷变量win就自加1,直到不满足循环条件。
当不满足while循环条件时,win的数值就等于除雷之外所有位置的总和,这是我们就可以判断为胜利了。
6.简单优化一下
我们还可以最后优化一下,如果输入的坐标被排查过,则重新输入
如果输入的坐标是*号,那么就可以进行排查
如果输入坐标不是*号,则证明该位置已经被排查过了
该程序目前基本功能就编写完了,当然还有许多优化和添加的方向,目前就先到这了。