c语言扫雷的简单制作

  零.前言

        这次做的扫雷,自己感觉有些冗长,有些地方没有去想算法(就是好多地方用了穷举哈哈)

虽然不精简吧,但是实现了游戏的主要功能,也支持多次游玩。

PS:我是初学c语言的大一学生,多多包涵哈,写错的或者不好的地方也欢迎来讨论。

 一.制作思路

        本次制作呢采用的编译器为Visual Studio 2022,为了模拟软件工程的效果,这次依然采用了三个文件进行完成。game.c和game.h两个做为主要功能实现的文件。如图

 

我的设计思路如下:

        ①准备两个棋盘,一个棋盘放雷,一个棋盘放玩家扫描的坐标。也就是用两个二维数组

(mine数组里放雷,show数组里放扫描坐标)

        ②玩家输入坐标后,排查自身以及周围的坐标,然后输出数字0-8(0就是周围没有雷,8就是周围八个雷)为了游戏的可玩性,最好做到排查到周围没有雷时,可以自动排查周围的八个格子,就是实现下图的效果。

         ③因为做出雷的标记需要更大的工程,我就偷懒没做这个功能。胜利条件呢,就是把除了雷以外的地方全部排查,失败条件自然就是扫到雷了。

二.代码实现。

        首先就是创建三个文件,一个是test.c作为测试的文件,一个是game.h用来声明函数、最后一个是game.c用来写自定义函数。

        接下来就是编写主函数,因为这次要把函数的主要内容都用自定义函数实现,所以主函数里就放了一个自定义函数,和一个用来产生随机数的函数(这里还是用time函数来产生伪随机哈)

接下来就是代码主体啦

        ①先打印一个简易的游戏菜单以及游戏说明,让游戏有一定的观赏性,这里就不废话了直接上代码

 

 为什么不能输入多个数字呢,因为我用的是scanf读入数据,输入多个数字会造成一定的bug,所以做一个说明。

写好这个两个函数后放入主体的test中

        这里解释一下do while语句的作用,用do-while可以先让程序执行一遍,也就是说menu的打印就不需要输入数字了。下面的while(n)的作用就是进行多次游戏,因为while在语句的判断中0为false,非0为true,所以玩家输入0后就会退出while,输入其他的数字则不会退出这个while循环,输入1则进入game函数,所以我打算在这个game函数中实现主要功能。 

②初始化棋盘并且放入雷。

        这里呢,要准备两个二维数组,我这里准备打印一个9*9的棋盘,但是我用开了两个11*11的二维数组,这个我解释一下

这里假设黑色圆为玩家输入的坐标,黑框大小为11*11,红色大小为9*9,在排查雷的过程中,黑色圈的位置要输出周围八个雷的数量,

在排查情况1的时候不会有问题,但是排查情况2的时候就会产生问题,这里可以看出排查周围八个时,排查的范围超出了红框,所以我这里用了一个11*11的数组来进行存储,但是实际的雷盘在中间的9*9上。

 初始化的代码如下:

 

这里初始化,我的想法是玩家看到的棋盘,没排查的坐标是*,排查过的为数字。雷盘里字符1为雷,字符0为空白。 

        为了优化玩家体验,所以需要游戏开始后先打印玩家看到的棋盘,也就是初始的show棋盘。当然为了让玩家更容易看出几行几列,我就在棋盘外输出行和列号。

代码和效果如下

 

 当然这个只能适配9*9所以我做了以下的优化

接下就是放雷了。

这里用rand函数来放。看下图可以看到红色的坐标是从,[1][1]开始[10][10]结束,所以雷生成范围要在1-10之间。 

 

 代码如下:

 num里面放的是成功生成雷的数量,这里随机两个坐标,然后排查一下随机的位置有没有放过雷,如果没有雷,就放入雷,然后成功生成雷的数量加一,直到生成的雷的数量等于需要的数量,退出循环。

③玩家排查雷

        先放代码。

        

 

         这里读入两个坐标x,y。既然是玩家输入的,那就会有错误,所以要先排查一下玩家输入的坐标是不是在红色框的范围内。如果不是的话,就需要重新输入。

        当然正确读入坐标后也要判断该坐标是否已经被排查过了。因为show的数组里一开始放的是*所以不是*的位置都是排查过的位置。这里就用了两个if解决。

        如果正确输入坐标就排查该位置或者该位置的周围有几个雷。

④排查雷的代码

        这里的代码比较冗长,我先做一个说明,就是用穷举将周围一圈数组的ascll值全部相加,然后减去8个字符0,然后再加上1个字符0(也就是减去7个字符0),就得到了该位置需要放的字符数字。

代码如下:

但是这样只能排查一个位置,为了实现下面这个效果,我做了一个递归。(也是穷举哈)

 

 也就是将周围的八个当成一个节点进行爆炸式搜索。

 

 这条语句就是确保搜索的位置周围没有雷,以及搜索的范围不会超出红框。

类似于这样的语句,是用来排除已经排查过的格子,避免了死递归导致程序崩溃。 

 

当然大家会注意到这里我调用了一个整形地址

这个就是我用来判断胜利的中介,每次成功排除一个坐标(包括电脑自动排除的),win就加一,如果win加到71

PS:一个9*9的棋盘,有20个雷。如果win等于71也就是说将除了雷以外的格子全部排除了,游戏胜利。

当然点到雷了,也要结束游戏

 

点到雷后,就打印一下雷盘,然后给这个函数返回0

再将返回值赋给f(如果f是0则退出循环) 

        

 当然踩雷了,win一定是小于71的

所以做一个判断,宣告游戏结束。

 

代码到这里就讲解完毕。

三.代码概览

 

 

 

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值