C语言之旅-函数及数组运用 简易扫雷

  相信大家都玩过扫雷游戏~那么今天就来说说用之前的一些知识来用C语言写一个简单9*9的扫雷小游戏吧。(我学习的还不够深入,所以小游戏还有很多不成熟的地方(/ω\))

  分多个文件

  写这个游戏和之前编的代码的最大的区别就是这个游戏要分文件去写。那么份文件会给我们带来什么好处呢?

  第一它会使我们代码的层次更加分明,更加清晰明了,方便进行后续的调试和维护;第二分多个文件会更加方便我们隐藏我们的代码。

  这次我选择把代码分装到三个文件中分别是test.c(用于写游戏的大框架,游戏的主体就在这个文件中)、game.c(实现自定义函数,用于细化的实现游戏的各个分块)和game.h(用于声明test.c中用到的,在game.c中实现的自定义函数)。好接下来让我们进入实践的环节吧(•̀㉨•́)و!

  游戏主体-test.c

  通过对扫雷游戏的观察我们可以看出扫雷是在一个棋盘上选择要扫的地点,进行排雷,如果踩雷则被炸死失败,如果不是则显示他周围雷的个数,直到把所有的非雷区都找到了则获胜。

  虽然在扫雷游戏中没有目录的存在,但在我们的简易扫雷中可以设计一个(这个可以分装成一个void的函数,比较简单,看下代码就好了~)

  f36f407363db428fa63f16f3c1375cb6.jpg

   当然游戏是可以多次玩的,所以整体要放在循环之中,游戏首先有运行一次后在进行是否进行下一次的判断,所以我们要选择do while循环。

  首先肯定是打印目录,然后进行输入选择,之后用 switch case 语句来分情况讨论是否进行游戏,具体实现如下

414815516ad34c339f90c93b59a52591.jpg

  之后就到了game的大纲阶段在game中主要实现什么。首先游戏是在棋盘上进行的,所以我们要搞一个棋盘的大致样式,而二维数组刚好和棋盘样式类似,所以用二维数组来实现这个棋盘。并且我们要对这个棋盘进行一个初始化,这里要自定义第一个函数来实现这个功能。

  扫雷扫雷最重要的是的有雷,所以再有了棋盘后我们要初始化雷的位置,这里要定义第二个函数,我们可以把有累雷的地方设置为1,没有雷的初始化时定为0。但这样在返回周围有1个雷时会产生歧义,所以我们可以在开始时创建两个数组用,用不同的字符初始化来解决这个问题。

  之后要把二维数组打印出来,这里要自定义第三个函数,用于整个游戏的数组打印。

  然后便是输入坐标来排雷了,输入坐标后检查的是他周围8个元素是否为雷,然后反复进行,直到游戏结束。但在最边上那一周检查时就会发现数组越界访问了。我们可以通过在每次检查时都先进行判断来解决这个问题,但这种方法的工作量太大。所以我们选择把原有都数组扩大两行两列,这样在检查时就不会再发生越界现象啦。如下图

65cfc826de674ade9ec9ee8a4909441d.jpg

   好,以上就是大纲,对应的代码大致如下

33a0dd49ebb64e70bbbbe9ff93270ac2.jpg

  游戏函数声明-game.h

  上面代码中使用的所有函数都要声明,这个在game.h中完成,同时在其中还要引这几个文件中用到的头文件并且进行宏定义(如数组的列,行,和雷的个数,进行宏定义后更加方便对代码中一些常量的修改),这样另两个文件只需引用一个game.h就可以了~它的代码大致如下

b3e89024636848f39c2a342e3c0d3daf.jpg

  游戏核心-game.c

  然后就到了游戏的主要实现,那些自定义函数的实现。

  首先是初始化,初始化在调用数组方面和打印数组差不多,只是把打印处的代码换做了赋值,因为要初始化两个不同的数组,只好定义为char类型的数组并在函数传参时要把初始化成什么字符也传入。

09523698bfa4470ab3b57065268eeec5.jpg

   然后是打印数组,这个方法和平常打印数组一样,运用两个for循环,分行打印每行中每列的元素然后换行进行下一行的打印。要注意的是这里打印的不是初始化的那个大一圈的数组而是9*9的小数组,所以行和列都要从1开始打到9停止。听起来不错,但这么打印出来后是下面的样子

402367b2b72b4e2ab7cc7068d408992e.jpg

 让人眼花,根本不知道自己想要查那个坐标,稍微优化一下,在它的上面和左侧都打上对应的行标和列标,行标可以在进入行循环之前用for循环单独打出,列标则在打印每行是的前面加上即可。如果想要更美观也可以在上面加上一个表头~

 fac14257657a4b1fb9500cba39bc9ad4.jpg

 经过这样优化后打印出来的就是下面的样子啦

  ffac9bdc8be44114875240cab4fb8344.jpg

  之后是设置雷,在这里我们要用到随机数rand(),并且将它用srand()函数用时间戳初始化(初始化放在了主函数中)。雷要存放在1到9中所以用随机数模上9再加1就搞定了。这里要说一下在初始化雷前一定要用if判断一下一下那个位置之前是非雷占用的,不然容易出现重复初始化导致雷的个数减少。代码如下

9f38d4079a444898b80d99b9d7f3c3fb.jpg

  最后就是反复输入及排雷的过程了,首先输入你选择的位置,如果是雷就被炸死,游戏结束,并公开雷所在的位置。如果不是雷则要统计其周围的雷的个数(因为雷为1其余为0,经过统计可知,想要知道雷的个数,只需把周围8个元素相加就可以得到。但数组使用char来定义,所以在统计个数时最后要减去8个0的ASCII码值进行转换为int,然后在输出时在进行转换,将其加上一个0的ASCII码值转换为char类型输出),而且要将个数打印返回数组并打印出来。

  如果这样写,哪怕我们找到了所有非雷的位置也不会跳出循环,我们只有一种可能才会跳出循环,那就是被炸死。为了让找出所有非雷的位置后可跳出循环,我们可以设计一个计数器,把进入循环的条件设置为计数器小于等于所有有效格(81个)减雷的个数。在跳出循环后检验是否计数器的值大于有效格(81个)减雷的个数,来判断是否获胜。代码如下

cc56203d3ea341aa925df8e6c3ccdcdb.jpg

  到此,整个扫雷程序就结束了~当然这个简易的游戏还有很多可以优化升级的地方,但因我能力有限,暂时只能达到这样。

  最后,让我们都再加一点点油,一起成为不负众望的人吧(๑•̀ㅂ•́)و✧

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值