一、扫雷游戏简介
扫雷游戏作为一款家喻户晓的游戏,我相信不管是谁都玩过这款游戏。
它分为多种不同的难度,区别就是在于面板上格子的数量以及雷的数量不同而已,玩法就是不
要点到雷!比如这基础难度的,9*9的面板中隐藏着10个雷,你需要找到他们并排掉他们,再把其他的格子全部点亮,就可以获得胜利,而下面的两张图片就是游戏的两种不同结局。
二、如何用C语言简易的实现
我们可以看到这是一个十分简易的小游戏,原理也是十分易懂,接下来我们将对这个消息进行深度的剖析,看看如何能实现扫雷这个小游戏。
这篇文章知识介绍如何逐步实现这个小游戏,代码会在下一篇文章全部提供给大家滴!
1、面板
可以看到基础难度的扫雷是一个9*9的正方形,9行9列共计81个格子组成的面板。而这个面板我们可以认为他是双面的,一面是像墙一样的我们什么都看不到,还有一面则是可以看到所有的空白和所有的雷,那我们就需要实现这两个面板:
一个面板上全是空心的格子,一个面板上全是实心的格子,而实心的目的就是为了遮盖住另一面的真相。而对于面板的设计,这里主要分为两个方面:一个是对面板初始化,一个是将初始化后的面板展示出来,我相信这个对大家来说并不困难,放个for循环就可以解决!
而对于这两种面板我们都可以才用二维数组去构建,对于这两种面板,我们设置其每个元素为某个字符,为其进行初始化,值得注意的是,我们看到的是实心的面板,空心的面板是为了让我们进行后续设置用的,上图:
还有一点要注意,虽然面板是9*9的,但是二维数组可不能就这么大!为什么呢?
扫雷游戏还有规则或者说是要点,就是面板上面的数字,它代表的是以这个格子为中心,一圈内雷的数量,很好理解吧!
如果二维数组就是9行9列,一个空白格在边角上的话,他就无法计算自身的一周了,因为那样会出现下标越界的问题。比如第2行第9列(索引为1,8),他要计算周围有多少个雷,就需要牵扯到1、2、3行和8、9、10列,可是此时二维数组并没有第十列呀,那此时就会出现相应的问题。仔细思考一下,是不是有点理解我说的意思了。
所以在设置面板的二维数组时,我们就需要预留那么一点空间给那些边角上的格子,解决办法也很简单,多一行多一列即可,那此时二维数组就是11*11。
2、雷的布置
这个问题相对来说就比较简单了,还记得那个空心的面板么,它的作用来了!
我们只需要在那个个面板上利用随机数随机生成一个坐标即可,我相信大家学习到这里对于rand()方法和srand提供随机数的来源方式,已经可以熟练地运用了!
至于如何放置,随机生成两个数字,作为坐标,在判断一下此时这个坐标上的元素是不是0(因为我设置的时0,根据自己的设定编写判断语句),如果是,那我们就把这个坐标上的元素改为1,则表明这里就是一个雷,那如果不是直接跳过就好了,直到生成了10个雷为止。直接看图:
至于为什么要设置成0和1,待会在计算数字时,好处就体现出来喽!
3、计算雷的个数
这个设计也很重要,这是能不能排除掉所有雷的关键!但不要担心,这比布置雷还要简单!
上面介绍过如何计算雷的个数,在联系以上上面的0和1,有没有恍然大悟?没错,就是你想象中的那样:把那个格子周围的8个格子中的元素全部加起来不就好啦!
但是要注意了,这里的0和1可不是Integer,而是Char类型的哦。‘0’和‘1’要是不处理的话,可分别代表的是48和49,那怎么办呢?
全部加起来再减去8个‘0’不就好啦,要知道Char类型要是不指定%c形式输出,他是会自动转换成int类型的!
4、排查
游戏准备好了,那下一步就是要玩这个游戏了,布置好了雷那我们就要开始排查雷了,步骤很简单,输入你想排查的格子的坐标即可。
如果这个坐标上是雷,那直接游戏结束,你被无情的炸死了!那不是雷的话,你就可以看到这个坐标周围一圈有没有雷,然后重复,直到找到除10个雷外的71个空格,简单吧。
但是问题来了,太麻烦了吧,想要获得胜利,需要输入71个坐标,想想人家的扫雷游戏,一点一下消除了一大片,是不是省事了许多,既然人家有,那咱也得有,那如何去实现呢?
简单!没有什么困难是克服不了的。先看看原理,如果这个格子周围没有雷,并且他周围的格子的周围也没有雷,也就是说这一大片都没有雷,那么就没有必要去全部排查一下,让他自行判断即可,直到遇到周围有雷的时候才停止判断,停止空白格的扩散。
而判断的条件就是上面经计算得来的雷的个数,如果计算个数为0,那么就计算判断这个格子的周围,知道这个格子处的数字不为0时,那便停止判断。我想大家已经知道要用什么技术了,没错,函数的递归。
从最初排查的点为中心,不断地向外扩散,不断的判断,直到遇到雷才停止,这是一个不断调用同一个判断方式的方法,那函数递归就当仁不让了!
5、标记
这也是扫雷游戏最后一个特点了,其实这个标记的存在是可有可无的。当然,既然存在,就是合理的,它可以标记某一个点来标注这个点是一个雷,以防止因出现记忆偏差或手误的情况导致游戏的失败。
实现方式也不难,将某个坐标的元素改为其他的元素即可。当然,如果胡乱标记肯定是不行的,而且标记的次数也有限,只有全部标记正确才能排除掉所有的雷,才能保证排查其他的点时不会出现问题。
我是采用了switch语句将排查雷和标记雷分成了两种模式,当然我也自作主张的添加了一条游戏规则,就是如果在有限的次数下标记的每一处都为雷,也可以获得游戏的胜利。但是,要知道,如果不排查雷,标记的工作也是无法进行的,所以两者算是相辅相成的结果。
至于如何判断是不是标记了正确,很简单,和统计雷的个数的方式相同,设置两个变量:一个用来限制标记的次数(flag),一个用来暗自统计标记雷成功的个数(count)。因为‘1’代表雷,如果标记的位置在空心的面板上是‘1’,那么count就加1,同时flag-1,很好理解吧。
那如果flag次数用完,此时count等于雷的个数,就代表获得了游戏的胜利(第二种胜利方式)。
三、总结
总而言之呢,扫雷游戏的实现不算困难,问题在于我们如何抽丝剥茧般的把这个游戏剖析成多个部分,并将每个部分的原理搞清楚,在逐步的去实现每个部分,这也是养成一个良好的编程思维的方式,沉下心来好好分析一下是十分重要的。而且其中用到的知识都是大家学过的并且可以熟练掌握的,我相信所有人都可以实现这个简单好玩的游戏,具体实现代码马上为大家奉上,有不妥之处欢迎大家指出,共同进步!