【MCBE-命令教程】连锁挖矿/砍树

引言:虽然B站上有很多的“连锁挖矿/砍树”的教程,但是都不尽人意。如果使用那种连锁挖矿,如果矿物过长,很多时候连锁到一半就中断了。除了这个问题以外,在连锁后产生的矿物掉落物旁边放置相同类型的掉落物,仍然会被连锁(理论上连锁已经结束了...)
为了解决上述问题,我写了这篇专栏,可以有效地解决这些问题,但是时运的问题还是无法解决...
望三连啊,点个免费的赞也可以~

要解决中断的问题,我们首先就要了解为何会出现这种问题...
以地狱石英举例,我挖完后,它的掉落物是这样掉落的(如图 1)

然后我又挖了一个,它是这样掉落的(如图 2)

所以我们可以初步的判断,地狱石英被开采后,它的掉落物的掉落方向是不固定的。然后我又多开采了一些不同类型的方块,结果也是如此。
但是这和连锁中断有何关系呢?
其实答案已经出来了。因为开采后,掉落物的掉落方向是不固定的,而传统的算法是以掉落物为单位进行连锁,而掉落方向的不固定,导致最终的掉落位置偏移了预期的位置,导致连锁中断,类似图 3的情形,地狱石英本应该在矿石的前面,但是由于偏移,导致无法落到预期位置。
传统算法(以钻石矿举例):
execute @e[type=item,name=钻石,ry=0,rym=0] ~1~~detect~~~diamond_ore -1 setblock~~~air 0 destroy
execute @e[type=item,name=钻石,ry=0,rym=0] ~-1~~detect~~~diamond_ore -1 setblock~~~air 0 destroy
execute @e[type=item,name=钻石,ry=0,rym=0] ~~1~detect~~~diamond_ore -1 setblock~~~air 0 destroy
execute @e[type=item,name=钻石,ry=0,rym=0] ~~-1~detect~~~diamond_ore -1 setblock~~~air 0 destroy
execute @e[type=item,name=钻石,ry=0,rym=0] ~~~1 detect~~~diamond_ore -1 setblock~~~air 0 destroy
execute @e[type=item,name=钻石,ry=0,rym=0] ~~~-1 detect~~~diamond_ore -1 setblock~~~air 0 destroy

不过有人就说了,命令方块的执行间隔很短(1游戏刻),那么掉落物的掉落方向所产生的误差可以忽略不计。但是根据多组实验,这种系统是无法运行的。大家也可以自己亲自试一试。
P.S. 即使修复了这个问题,第二个问题(在掉落物旁放同类矿石也会被连锁,即使理论上连锁已经结束)也仍然无法修复。因为传统算法是以掉落物为目标进行追踪,所以要同时修复这两个bug,我们得从另一方面入手(不以掉落物为单位进行检测)。
修正方法:
所以我们在玩家挖矿后,用经验球和掉落物同时检测(某些矿物挖了后不掉经验除外)。如果同时检测到了这2个实体,我们则给这个掉落物添加一个标签。然后以这个掉落物为单位,检测前后上下左右是否有同类方块。如果有,则在前/后/上/下/左/右的位置处生成一个实体(下称“栓绳”),给生成的栓绳添加另一个标签(下称这些实体为tag=b)。然后移除刚刚那个掉落物的标签,并更改它的rx轴/ry轴旋转值,以保证命令方块下一次循环的时候,不会再以该掉落物为单位进行连锁,这也就解决了在连锁结束后,放置同类方块还是会连锁的问题。
执行这些操作后,现在地图上只剩 tag=b 和没有被连锁的方块了。那么我们给这些栓绳添加另一个标签(下称这些实体为tag=c),然后以 tag=c 为单位,检测前后上下左右是否有可以连锁的方块。如果有,则在对应位置生成一个实体,并为其添加一个标签(给他们添加的标签还是b)。
现在来梳理一下思路:地图上现在还有一些 tag=b(刚刚生成的,没有标签c) 和一些 tag=c (最早生成的,也有标签b)。那么我们现在以 tag=c 为单位,检测其位置处是否是可以被连锁的方块,如果是,则打碎自己位置的方块并清除自己,现在只剩下 tag=b 了。然后重复以上操作,直到最后, tag=c 无法在前后上下左右找到可以被连锁的方块,也就无法生成 tag=b ,则整个连锁宣告结束(因为最后 tag=c 都会被kill,所以如果不在kill之前生成 tag=b ,则就没有 tag=c 或 tag=b 了)。
那么就是这样了,不管矿物有多长都可以被连锁到(矿物必须在加载区块内)
不过还是有一些小问题,比如 tag=b 可能会被重复生成。为了解决这个问题,建议使用递归,即给全部由命令方块生成的栓绳添加一个标签d,然后从带有这些标签的栓绳中随机选择一个,检测当前位置处是否有多个同类连锁方块的实体。如果有,则删除多出来的那些,然后去除自身的标签d,然后从随机抽取的列表中移除。如果还有带有标签d的栓绳,则递归下去,直到没有,递归被打破。

END.附上我写的连锁钻石块的指令组,如图 4(玩家持有标签lswk:player即可使用,function more是检测是否有重复生成的实体,这里就不给这个function的图了)。

其实还可以继续简化,看你们的啦~
P.S. 不会把指令发到评论区,请自己理解消化后自己再写一个。复制粘贴是没有意义的,别人的东西终究是别人的。连锁砍树同理也可以做的哦~