用户:
Mellin_Amp查看:32 回复:55 评论:32 创建时间:2020-07-30T07:46:42
大家好,我是慕斯

“我有一个梦想,就是要成为编程猫的Code Star!”

(往期传送门)
https://shequ.codemao.cn/wiki/forum/320472
https://shequ.codemao.cn/community/324246
经过前两期丧心病狂的操作,在标完数字之后就可进行愉快地正式进行扫雷了
我们先总结一下我们目前的成果:
用一个16*16的地图存储雷
如果格子是0 代表自己和四周都没有雷
是1-8代表了四周的雷数
是9代表自己就是雷
接下来要做的,就是怎么实现“把雷点开”
这还不简单吗?
如果是雷 就失败 如果不是 就啥也不发生啊!

过于喵率()
我们在正式编写代码之前,不妨先想想“点开雷”的规则
可以总结出以下几条:
看起来刚才的积木,好歹实现了第一条:
如果格子是雷,就会炸
那么第二条想必大家也会轻松实现:
为了标记格子有没有被点开,不妨再建立一个列表来储存格子的状态

如果这个格子没点开,点击才会有效,在点击之后将它标记为“点开”
设没点开是0 点开了是1
我们就可以把上面的喵率积木进行一下下的修改得出

这下规则的12条就制作完成了
继续思考,如果格子上有数字1-8 它点开就是单纯的点开
没有任何其它的效果 如果有114514个格子 你就得点个114514次
但是你玩的扫雷呢?
如果运气足够好就能“一点一大片”转瞬之间“风平浪静 海阔天空”
真的是非常amazing啊

哪个训练师不想做出这么高级的功能呢?
可能有的训练师对此毫无头绪
在这时我们就能引出今天的主角“递归函数”

递归这名字听起来很高大上
但实际上可以总结成两个字:套娃
编程语言中,函数如果直接或间接调用函数本身,则该函数称为递归函数。
递归函数的套娃其实很简单
举一个例子,我们要制作一个计算阶乘的函数
n!=n*(n-1)*(n-2)……*3*2*1
它也可以表示成:
当n>1时 n!=n*(n-1)!
当n=1时 1!=1
仿照这个式子 我们就可以写出这样的递归函数
只要我们知道“相邻两项”的关系
就能够用递归函数简单造出
递归在许多时候能够起到重要作用
只要避免“无限循环”(即自己调用自己没有终止)
就能造出非常amazing的效果
回到正题
在点完一个空白格子后,再去以同样的操作点击相邻的格子
这样不就没有问题了吗?
对于空白的格子就点击周围一圈
因为能进行“套娃”操作的格子只有空白格子
而空白格子没有数字,即周围一圈没有雷,所以不用担心踩雷问题
相信各位训练师经过上一个帖子的学习
都应该能知道下一步应该加什么
没错,就是“边上格子”的判断
(详情移步第二期)
经过亿点点的修改 也就成了下图的德行

虽然这个积木有亿点点长,但是大家都能看出
这个和上期标数字时的注意事项 其实是换汤不换药的
以上,点开格子的规则3就被实现了
递归函数就是这样强大,在非常简短的代码里实现出复杂的效果
我们本期的教程也就愉快地结束(水完)了
学习扫雷的制作不是我们唯一的目的
我们需要着重记忆的,也不是那几块积木的堆砌
而是其背后反映出的重要思想
递归函数在之后的编程生活中会非常常见
不仅可以解决常见的数学问题
还能够在对数据的处理上发挥作用
接下来是慕斯给各位留的作业
(注:斐波那契数列的前两项为1 此后第n项等于第n-1和第n-2项的和)
有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,要把所有盘子一个一个移动到柱子B上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方,请问至少需要多少次移动?
