相信大家小时候肯定玩过扫雷游戏吧,现在我们学习了c语言,那么该如何实现呢?
一.扫雷游戏拥有的功能
(1)我们今天要使用vs2022来实现扫雷游戏
(2)扫雷游戏可以通过菜单选项来判断是否要继续玩
(3)扫雷的棋盘是9×9
(4)布置10个雷
(5)可以排除雷
输入要排除雷的坐标即是可以排查此位置是否为雷,如果不是雷那么会显示周围有几个雷,如果是那么游戏结束。
如上图.
二.扫雷代码实现
1.无论要完成的游戏多么复杂,我们最初要完成的工作是创建项目。这里我们使用多文件创建形式。
如上图我们要创建三部分
test.c实现游戏逻辑测试
game.c和game.h完成游戏逻辑
2.在test.c中我们要实现游戏逻辑测试,但我们不想把所有代码都在主函数内完成,因为这样会显得非常乱。所以我们自定义一个函数,在这个函数内完成。
如上图.
接下来我们要完成游戏的菜单,实现输入1进入游戏,输入2退出游戏,输入其他则提示则输入错误。所以我们使用自定义函数创造菜单,另外为了好看我们给菜单做一点装饰。
然后我们在void test中引用menu函数,使用do while循环(为了让游戏玩完还能继续下一把,所以使用循环)
我们输入1代表开始游戏,输入0是退出游戏,输入其他为输入错误,所以有三种情况,我们使用switch语句
接下来要开始完成扫雷游戏
首先是棋盘问题,我们要设置一个9×9的棋盘,所以在头文件中我们要如下设置
然后我们需要创建一个棋盘用来放雷,用二维数组来创建(char【x】【y】),x表示行,y表示列。
另外再来说一下排雷,我们想要查询某个点时就输入坐标,如果该点不是雷,那么就会显示周围八个点的总雷数
如上图所示。
但要是我们想要查询的坐标在棋盘的边上,那么就会超出范围
如上图,所以在设置棋盘的时候我们要将棋盘的范围设置的大一些,将9×9棋盘扩到11×11棋盘,char【11】【11】
如上图所示。我们布置好雷之后,用1代表雷,不是雷则是0,在我们查询一个坐标的时候,坐标周围有雷,我们需要将雷数量存储下来,然后打印给玩家,但是在放雷的地方已经有数据占据了,再存雷会导致混乱,分辨不清,所以我们要设置两个棋盘,一个是放雷信息的棋盘show,一个是雷的棋盘mine,把雷放到mine里,然后排查出雷后,将雷的信息存放到show里,然后打印信息,这样就不会混乱
在棋盘设置好之后,应该给棋盘初始化了,让mine棋盘全部初始化为字符‘0’,show棋盘初始化为‘*’。如下图
在初始化棋盘之后,我们要开始打印棋盘。最外围的一圈我们不用打印,只是为了防止越界才存在。所以我们再test.c里设置一个函数displayboard,传mine cow col参数,
并在game.h里声明函数
为了玩游戏的人方便观察坐标,我们把行号和列号也打印出来,代码如下
现在我们能打印我们的棋盘,接下来要做的是把雷布置在棋盘里。我们再在test.c里设置一个自定义函数setmine,并传参(mine,row,col)虽然传mine数组是11×11,但是传参row和col是9×9的格子,我们访问的也是9×9的格子
我们先简单布置10个雷,但后期也许我们要改雷的个数,所以我们先定义雷的个数(game.h)
并在game.c里给上一个count变量,上来我们就是十个雷
由于我们要随机布置雷,所以我们要使用
rand函数(),但rand函数生成的随机数有可能不是完全随机的,而是伪随机数,伪随机数是用确定性的算法计算出来自[0,1]均匀分布的随机数序列。并不真正的随机数。是以他的种子为基准生成数,但种子一般不会随机改变,这时候我们就需要用srand()函数来改变rand()函数的种子以改变rand()生成的随机数,从而使生成真正的随机数。(在使用rand函数需要包含stdlib.h头文件)
srand() 是 C语言的一个标准库函数,定义在<stdlib.h>头文件中。srand() 函数用于改变随机数生成器的初始状态,通过为随机数生成器设置不同的种子,从而对随机数生成器进行初始化或者重新初始化。由于时间是无时无刻变化的,所以使用time()函数(当前时间)来作为srand函数的种子。
time( )是指返回自 Unix 纪元(January 1 1970 00:00:00 GMT)起的当前时间的秒数的函数,主要用来获取当前的系统时间,返回的结果是一个time_t类型。(使用时需要包含头文件time.h)
把他们结合起来就可以生成一个真正随机数。
但rand生成随机数的范围是不固定的,我们需要布置雷在9×9棋盘上,所以可以将这个棋盘长宽+1
接下来可以布置雷了,使用while循环,用count作为变量,每次布置一个雷之后,就count--,雷都布置之后,count=0,循环结束
布置好雷之后,我们可以进行最后一项了,排查雷。我们要在mine数组里排查然后放到show数组里,所以传参的时候我们两个数组都要传,排查的过程中我们只关心9×9格子。所以
然后在game.h里声明函数
在输入需要排查坐标的时候,玩家只知道9×9的棋盘,但如果有玩家输入的坐标超出了棋盘范围,那就输入错误,所以我们需要判断坐标的有效性,如果坐标错误我们就显示坐标非法重新输入,重新上来继续输入,所以这个地方就是一个循环。x,y坐标如果输入有效的情况下,那就进入if语句了,所以我们要判断这个坐标是不是雷,所以如果mine(x)(y)=='1',那就打印很遗憾你被炸死了,当然在死之前也会告诉你雷在哪。如果你输入的坐标不是雷,那就是该坐标不是雷,统计坐标周围有几个雷。自定义一个函数来去统计mine数组的xy坐标周围有几个雷,并且需要求出一个count值告诉我们有几个雷。
那么我们怎么知道xy周围有几个雷呢,以x为行,y为列,那么周围就是x-1行,x+1行,,y-1列,y+1列,八个坐标就都出来了
如果为字符0,那么count不变,如果为字符1那么count++
还有一种方法是,把周围八个坐标值加起来,里面只有一个1,那么加起来就是1,也能统计出来。但是坐标是字符0和字符1,所以不能简单的加起来,字符1的ascll值是49,字符0的ascll值是48,字符1减去字符0的ascll值就是数字1,字符2ascll值是50,那么字符2ascll值减去字符0ascll值就是数字2,字符1减去字符0就能转换成对应的数字1。所以所有的位置先减去字符0再加起来就完事了
如上图所示实现代码
做完以上步骤现在我们就把count算出来,如果count算3,那么应该放在show数组里,排查之后应该显示一下雷。
接下来就是如何结束游戏,设置一个变量win,win要小于所有坐标减去雷的个数,然后只要输入一个坐标不是雷,那么win++,总有一次win不在小于所有坐标减去雷的个数,那么就跳出来,游戏结束,打印恭喜你,排雷成功
到这里,扫雷代码全部完成。下面是总代码。
game.h
game.c
test.c
以上就是扫雷游戏的全部代码,鄙人写博客经验不多,初学计算机小白,如有错误请指出,我一定会改,不喜勿喷,谢谢大家理解🙏🙏