C语言扫雷的实现2(优化功能)

c语言扫雷的实现-CSDN博客

1.上期答案

接上期博客

在Getminenum中为什么不多设置一个参数char show[Row][Col],代码改成show[x][y]=代码改前return的值?

让我们对比下这两个代码

1

2.

第一种写法(正确写法)返回一个int型的雷的数目,用一个int型变量num接收,接着用字符0加上num,使得雷的数目由int型转变为char型(因为show数组是char类型),最后将更新后的数据打印出来

第二种写法(错误写法)直接将show数组的值改变为雷的数目,看起来也可以,为什么会出现以下情况呢?

先猜测接下来程序运行结果,也许你会有更深的体会

运行结果如下

所以第二种写法计算的结果会以%c的形式打印,例如计算的结果是两个雷,以%c打印会返回2的ascll码(不可见),所以会打印出如此奇怪的字符

2.提示行列

我们不难发现随着行列的增加不利于玩家判断坐标,因此我们更改showboard()函数可以增加行列提示

效果如下

3.递归实现

每当我们输入一个坐标,只能查看当前这个坐标的周围雷的个数,不能像扫雷一样一次开辟一片区域,因此我们要实现这个功能

1.主要思想

1.判断周围雷的个数是否为0,如果为0,计算并显示四个方向所在位置雷的个数,如果周围的位置雷的个数为0,继续递归下去,知道超出x和y的范围

2.代码实现

我们可以分装一个函数Caculate()来实现递归功能,然后递归完成后showboard()来显示到屏幕上

关键便是递归功能的实现

当我们运行起来时,并没有达到我们的预期

程序似乎崩了,让我们调试一下

编译器给出stack overflow(栈溢出)的报错信息,让我们想一下哪里学到过这个知识?对了在递归部分学到过,这恰巧说明我们调用函数的次数太多了

想象一下在理想情况下假设四个方向都能递归成功,那么第n次递归一共需要调用pow(4,n)次函数,而每次调用函数都将向栈区申请空间,调用次数过多后栈区空间不足,便报出相应错误

3.递归改进

按照我们的设想,如果没有递归,我们需要Row*Col-number次输入坐标才能达到游戏胜利,因此最多只需要调用函数Row*Col-number-1次就能达到游戏胜利,那么如何减少递归次数呢?

很显然需要满足一定条件才能递归,因此我们可以实现逻辑:如果没有递归过,进行递归,否则不进行递归,代码如下:

这么做大大减少了递归的次数,使得程序得以运行

4.胜利条件改进

之前我们每输入一个坐标,如果没被雷炸死,win--,直到win=0跳出while循环,因为现在实现了递归功能,现在的逻辑应是每递归一次win--

经过多次尝试,因为c语言编译器是自上而下逐语句进行的,递归有先后顺序,递归传参以及返回值的确定变得不确定,难以达到想要的结果,因此我们可以对胜利条件进行改进

不难发现雷的个数加上显示出来的数字个数就是Row*Col,因此我们可以定义一个Check_win函数遍历数组来判断是否达到胜利条件

并完善Findmine中的代码

这样就避免了在复杂的一次又一次递归中迷失了方向

5.结语

我很高兴用将近三千多字将c语言扫雷大致描绘清楚,由于作者知识水平的浅薄,文中相关内容可能不够专业,甚至存在错误,欢迎大家批评指正!

在近两个星期的探索中,在编译器疯狂报错中,在一次次的调试中,我深刻感受到了什么是痛苦,但最终看着自己亲手做出来的作品,一切都是值得的!

最后作者制作不易,希望大家积极点赞评论转发,如果喜欢作者的作品,可以点点关注,你的鼓励将是我创作的最大动力!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值