一,扫雷游戏游戏规则介绍
点击一个方格若该方格是雷,游戏结束,若该方格不是雷则显示最靠近他它八个方格有多少雷。 例如
你点到一个数字,如果是3,那就说明最靠近他它周围的8个格里有3个雷。. 然后通过相邻或者相间的数字之间的交集来判断哪些是雷
二,游戏设计思路
首先考虑棋盘,因为需要一个二维矩阵,所以我们创立一个二维数组来模拟棋盘。如果我们创建一个二维数组,那么,这个二维数组需要包含,棋盘外观,非雷空,雷的空格,等较多元素,不容易进行代码的实现,所以我们这里需要创建两个二维数组,一个上面存放棋盘的外观,以及排查的雷的信息,用来被用户观看以及操作,一个上面存放雷的信息,实现雷的放置以及判断一个格子周围有几个雷。
棋盘的大小可以先设置成9×9,然后需要提前,确定各种元素所对应的符号。小编这里,使用符号`0`表示非雷的空格,使用符号`1`来表示有雷的空格,这样设计有以下好处,便于区分有雷区域和无雷区域,并且在后面计算一个空格周围有几个雷的时候比较方便。棋盘上用*号,来表示没有被排查的区域,标记则是#。然后我们需要思考怎么实现,判断一个非雷空格,周围有几个雷?不过在这里可能有的小伙伴们会有疑惑,设置棋盘为9×9,那么,如果在排查边上的空格时,判断其周围八个空格有几颗雷,就会有几个空格是在我们的棋盘之外,比如如果我们翻开左上角的格子,如果这个格子不是雷,那么就会查找它周围八个格子存在雷的个数,但是这个格子的上面和左边没有格子了,也就是会存在数组越界访问,所以我们需要将数组扩大,变成11×11的大小,这样就可以很好的保证我们在遍历的时候不会出现数组越界访问。如图
三,代码实现
首先,需要创建文件,这里我们创建三个文件text.c文件(用于测试基本函数),game.c文件(编写游戏过程),game.h头文件(用于函数的声明和头文件的引用)
1.1设计游戏的进出机制以及打印菜单
任何一个游戏都需要一个开始游戏,结束游戏的功能。代码如下
选择0作为推出按键,是因为当do while判断语句为0时,跳出循环
1.2初始化变量
这里使用define定义行(ROW)和列(COL)是为了方便以后更改棋盘大小,将mine(存放存放雷的信息)初始化为'0',将show(排查的雷的信息)初始化为'*'
1.3打印棋盘
首先,打印纵坐标,利用一个For循环,打印0到9的数字,接着需要打印棋盘,在打印棋盘的时候,需要将横坐标一起打印,只需要在棋盘的每一行的第一位,打印机对应的纵坐标就可以。这里为了好看一些,小编还加上了上下界,来将棋盘隔离开来。注意不要忘打印换行符。
这里不仅要打印棋盘外观,还要把坐标打印上去
1.4设置雷
首先需要用迪范定义一个常量,用来表示所设置的雷的个数,然后因为设置的雷的信息需要放在mine数组里,所以我们这里将mine数组传进去,定义横纵坐标x和y,利用随机数生成函数rand(这里不要忘记设置时间戳),取模x加一,就可以随机生成1到9的横坐标,取模一个y就可以生成1到9的纵坐标。然后需要判断生成的这个随机坐标是否已经被安置了雷,如果没有被安置雷,那么,令该坐标为'1',表示成功安放雷,如果已经被安放过雷,则重新再生成一个随机坐标,循环往复直到雷的数量达到预期目标。
1.5排查雷和胜利条件
首先给用户进行选择,是进行排雷操作还是标记操作,选择排雷操作以后,定义要排查的坐标的横坐标x和纵坐标y。因为这个扫雷游戏,需要用户手动输入坐标,所以难免会出现输入错误的情况,所以接着需要判断输入的坐标的合法性。接着需要判断所输入的这个坐标是否已经被排查过。用户可以排查的情况有两种,一种是没有被操作过的,*号格子,一种是被标记过的#号格子,所以这里只需要判断该格子是否为*号格子或者#号格子。接着就是判断,用户输入的这个坐标是否是雷,如果是雷则被炸死,游戏结束并且需要打印mine数组让用户知道所放置的雷的位置,如果不是雷,那么该格子显示周围最近的八个格子的雷的个数。这里我们只需要判断该坐标所对应的mine数组的元素是否等于'1',如果等于则是雷,不等于则不是雷。
胜利条件:定义一个变量win表示非雷的数量,每当找到一个非雷的格子,就令win--,当win==0时就说明雷全部被排完了。
1.5.1显示一个非雷格子周围最近的八个格子的雷的个数
若判断后,该格子不是雷,那么需要让该格子显示周围雷的个数,小编这里给大家提供的两种方法。
第一种是,首先定义一个count用来表示所找到的雷的个数,然后利用放循环遍历周围的八个格子,如果有格子,所对应的二维数组的元素等于'1',那么就宁count++来储存所找到的雷的个数,然后return count给Show数组所对应的坐标,然后win--表示非雷格子减一。
因为我们所需要查找的元素不多,所以可以一一列举出来。直接让其周围的八个格子里的元素相加,因为格子里的元素只能是'1'或'0','0'所对应的ASCLL值是48符号零所对应的ASCLL是49相加之后再减去八乘以'0',就得到了周围的雷的个数。这就是上文要把'1'代表雷的原因。
最后还需要打印show数组。
//因为调用的函数返回值类型是int,所以要加一个'0'将类型转变为char型
1.6标记雷
当用户选择标记操作时,输入要标记的坐标,横坐标x,纵坐标y。然后和排查操作一样,需要先判断坐标的合法性,因为我们要标记的目标,只能是没有被超过的星号格子,所以我们还需要再判断,我们所操作的格子是否是新号。你若判断是*,则令该坐标所对应的Show数组元素为#,然后打印show数组。
1.7爆炸式展开
首先我们要将坐标的横坐标,纵坐标,Mine数组,show数组,以及win的地址给传进去(如果将win直接传进去,改变形参值并不能改变实参值,形参只是实参的一份临时拷贝)。然后要判断被排查的坐标是否合法(换句话说就是判断,该坐标是否在棋盘上),也就是该坐标是否可以进行爆炸式展开,如果不进行判断的话,数组将会一直向外扩展,造成数组越界访问导致程序崩溃。如果坐标合法的话,就需要判断,该坐标周围是否有雷,如果其周围八个空格都没有雷的话就定该空格为空(' '),然后(*win)--,接着就对其周围八个空格进行依次递归,当然,在递归前需要进行判断,传给函数的地址是否合法,并且得是没有被操作过的*坐标。如果判断其周围八个空格有雷的话,就不进行递归,另这个空格显示其周围的雷的个数,然后(*win)--。
四,源代码
五,扫雷小技巧
- 基本定式:不忘记基本的定式,这是解决问题的关键步骤。
- 稳定节奏:保持稳定的操作节奏,避免急躁导致错误。
- 顺手标雷:不要养成习惯不去标记已知的雷区。
- 无从下手时:当无法确定某个区域是否为雷区时,可以先猜测并标记,然后逐步验证。
- 遇到猜雷失误时:不必过于沮丧,保持冷静,继续分析剩余的区域。
- 猜雷猜错时:即使猜错了,也要保持镇定,不要因为失误而影响后续的游戏进程。
- 遇到好局时:不要急于求成,而是要稳扎稳打,逐渐扩大战果。
- 痛失好局时:不要气馁,因为这种情况不可避免,重要的是从中学习经验。
此外,还有一些具体的规则和技巧口诀,如:
- 九宫格:边线上的数字相加等于中间的数字,这有助于判断该区域的雷数。
- 连续数字:连续出现的数字组合(如三个一或四个一)通常表示该区域内存在雷。
- 双数点法:在开局时,先点出所有单数的格子,然后在点出偶数格的茶杯,以避开蜘蛛雷。
以上是小编根据自己的学习以及理解总结的扫雷游戏C语言代码的实现,因为本人水平有限,在讲解和语言上,可能并不标准,导致读者有些地方不理解。小编也欢迎朋友们在博客下方留言,以及指正错误及不足的地方。