【TML丨104】命令方块关于兰顿蚂蚁的算法实现与研究



图片与演示视频镇楼
视频来自:优酷

楼主 1041159637  发布于 2015-11-08 14:32:00 +0800 CST  
Hello,大家好,我是命令方块吧的小吧主104。今天给大家带来的是在Minecraft中用命令方块实现关于兰顿蚂蚁的算法的介绍,以及在Minecraft中对兰顿蚂蚁进行的一些小研究。
灵感来源:http://www.bilibili.com/video/av3013188/
建议对兰顿蚂蚁不了解的同学先看看

楼主 1041159637  发布于 2015-11-08 14:35:00 +0800 CST  
一、什么是兰顿蚂蚁?
相信有不少同学听说过“生命游戏”,就是一群细胞在一个平面中不断重复生与死的过程的零玩家游戏(即不需要任何操作,全自动运行)。兰顿蚂蚁也是一个零玩家游戏,并且与生命游戏有着许多相似点。它的游戏规则是:
有一个无限大的二维平面,被分为无数个形状相同的正方形。这些正方形被涂成白色或黑色。在其中一格上有一只“蚂蚁”,其初始朝向为上下左右任意一方。这只蚂蚁会按照如下规则移动:如果蚂蚁脚下是白格,则左转90度,反转该格颜色为黑色后,向前移动一步;如果蚂蚁脚下是黑格,则右转90度,反转该格颜色为白色后,向前移动一步;如此循环。
兰顿蚂蚁起初由克里斯托夫·兰顿提出,与生命游戏一样是细胞自动机的一种。
(这张gif图摘自英文wikipedia,它显示了蚂蚁最初的200步运动)


楼主 1041159637  发布于 2015-11-08 14:56:00 +0800 CST  
二、兰顿蚂蚁的算法
关于构建元素---------------------
兰顿蚂蚁的规则很容易让人联想到在Minecraft中的超平坦世界,因为这个世界的表面几乎只有一种方块,并且是一个无限大的平面。于是我们只需要再引入两个元素,也就是另一种方块以及一只“蚂蚁”了。
为了方便理解,我们选择创建一个只有一层的超平坦世界,表面为白色羊毛。超平坦生成代码为3;minecraft:wool;37;


是不是和规则所述的平面有点像?接下来我们只需要引入一个黑色方块就可以构成一个完整的平面了。这里我选择的另一种方块是黑色羊毛,但是先不用着急,在此之前我们得请出我们的主角“蚂蚁”


Emm……当然Minecraft里可没有蚂蚁这种生物233。不过蚂蚁这个设定本身就是抽象的,所以我们可以用别的东西来代替,这里我选择了一只猪(@WilliamPig{斜眼})
当然我们得让猪听话,所以我们得弄一只特殊的猪:
/summon Pig ~ 2.5 ~ {Equipment:[{},{},{},{},{}],Invulnerable:1b,CustomName:"langton_ant",Silent:0b,NoAI:1b,CustomNameVisible:1b}
召唤一只名为langton_ant,无AI无声音无敌并且显示名字的猪。这样这只猪就不会到处乱跑了。


然后就是创建两个记分板,分别名为“facing”和“B”,这两个记分板的用途在之后的步骤会用到。



楼主 1041159637  发布于 2015-11-08 15:00:00 +0800 CST  
第一步 判断并转向----------------------
蚂蚁的运动有四个步骤:判断、转向、变色、移动。这些步骤是依次进行的,并且都是相对于蚂蚁来进行的。所以首先我们得先判断蚂蚁脚下的方块的颜色,以蚂蚁为中心的话,就是判断蚂蚁脚下的方块的颜色。
这里就要用到“facing”记分板了,这个记分板用来控制蚂蚁的朝向
所以两个指令就是:/execute@e[type=Pig,name=langton_ant] ~ ~ ~ detect ~ ~-2 ~ minecraft:wool 0 /scoreboardplayers add @e[type=Pig,name=langton_ant] facing 1

/execute@e[type=Pig,name=langton_ant] ~ ~ ~ detect ~ ~-2 ~ minecraft:wool 15/scoreboard players remove @e[type=Pig,name=langton_ant] facing 1
这里用到了execute指令的判断方块的功能。第一个指令是以“蚂蚁”为中心判断其脚下两格方块是不是白色羊毛,如果是,那么就给蚂蚁的facing记分板加一分;相反地,如果其脚下是黑色羊毛,那么就减一分。
聪明的人应该可以看出来了,这个facing记分板的用途是用来控制蚂蚁的方向的。所以0到3就是蚂蚁分别向着北、东、南、西(不过必须是有顺序的)。这样就可以实现判断然后转向了,比如加一分相当于向右转90度,减一分相当于向左转90度。
但是问题来了,这样下去迟早会把分数加超过3或者减到小于0的情况。所以我们需要让它能在0到3之间循环(有点类似补码):
/execute@e[type=Pig,name=langton_ant,score_facing_min=-1,score_facing=-1] ~ ~ ~/scoreboard players set @e[type=Pig,name=langton_ant] facing 3

/execute@e[type=Pig,name=langton_ant,score_facing_min=4,score_facing=4] ~ ~ ~/scoreboard players set @e[type=Pig,name=langton_ant] facing 0
因为0减去1分就变成-1,所以我们只需要探测蚂蚁的分数有没有到-1,如果有那么就把分数-1变成3;后面也同理。这样就相当于0减去1等于3,3加上1等于0。
现在这个转向操作还仅仅只是分数而已,等到后面蚂蚁移动时,我们会用上这些分数。

楼主 1041159637  发布于 2015-11-08 15:21:00 +0800 CST  
第二步 变换方块颜色-----------------------------
根据规则,实际上也是先判断脚底方块的颜色再替换,所以和之前类似。
但是这里要用上一个B记分板用来绕过另一个判断颜色并替换的步骤。具体先看指令:
/execute @e[type=Pig,name=langton_ant] ~ ~ ~detect ~ ~-2 ~ minecraft:wool 0 /scoreboard players set@e[type=Pig,name=langton_ant] B 1

/execute@e[type=Pig,name=langton_ant,score_B_min=1,score_B=1] ~ ~ ~ /setblock ~ ~-2 ~minecraft:wool 15

/execute@e[type=Pig,name=langton_ant,score_B_min=0,score_B=0] ~ ~ ~ detect ~ ~-2 ~minecraft:wool 15 /setblock ~ ~-2 ~ minecraft:wool 0
这些指令是依次触发的。第一个指令是先判断蚂蚁脚下是不是白色方块,如果是则设置蚂蚁的B记分板为1分。接下来第二个指令是把分数为1的蚂蚁的脚下替换成黑色。此时变色这一步已经完成了,所以需要绕过第三个判断黑色的指令,不然的话相当于颜色没换。
第三个指令的意思是判断B记分板分数为0的蚂蚁的脚底方块,是黑色则替换成白色。由于第一个指令把B记分板设置成1分了,所以第三个指令不会执行。而如果一开始蚂蚁脚底方块是黑色,那么蚂蚁分数就会是0,因此第二个指令不会执行,转而执行第三个指令。
(当然还有更加简便的算法,我的并不是最简便的,因此运行时效率会低一点,因为记分板,但也无伤大雅)
最后把B记分板重新设置成0分
/scoreboard players set@e[type=Pig,name=langton_ant] B 0
(这里科普一下set 0分和reset的区别。如果你仔细观察可以发现如果设置成0分那么记分板仍会显示你的分数是0,但是如果是reset那么就不会显示。所以区别是一个是把分数设置成0,另一个是把某个实体的分数从记分板中移除。而后者会影响选择器选定实体和运算。)

楼主 1041159637  发布于 2015-11-08 15:21:00 +0800 CST  
第三步 移动--------------
因为蚂蚁有四个朝向所以我们只需穷举四步。这里就要用上步骤一中的facing分数了。
/tp@e[type=Pig,name=langton_ant,score_facing_min=0,score_facing=0] ~ ~ ~-1 180 0

/tp@e[type=Pig,name=langton_ant,score_facing_min=1,score_facing=1] ~1 ~ ~ -90 0

/tp@e[type=Pig,name=langton_ant,score_facing_min=2,score_facing=2] ~ ~ ~1 0 0

/tp@e[type=Pig,name=langton_ant,score_facing_min=3,score_facing=3] ~-1 ~ ~ 90 0
第一个指令是如果蚂蚁转向后朝北,则把蚂蚁的z轴坐标减去1;其他分别是蚂蚁面向东南西时的移动,与第一个指令同理。不过这4个指令中,只有一个指令会运行。

至此蚂蚁的一步运动的算法就完成了,一共12个命令方块,每组4个。只需要按照顺序从头到尾用高频激活,那么蚂蚁就会不停地按照这个规则运动。

楼主 1041159637  发布于 2015-11-08 15:22:00 +0800 CST  
三、兰顿蚂蚁的研究
以初始场景为全白为例,兰顿蚂蚁起初的几步运动出的图象会呈现对称形状等。但是蚂蚁移动数百步之后,蚂蚁的运动图象就看似没有任何规律了。


但是当蚂蚁运行约11000步后,蚂蚁的轨迹会突然出现一个非常有规律的图案,这个图案被称为高速公路:



(利用fill高频激活之前的算法,可以在8分12秒左右出现高速公路)
全黑的背景也是如此,只不过图案是反过来的:


这条高速公路会以每104步为一个循环,蚂蚁会一直持续不断地画下去。
(真的是104步然而和我id没有半毛钱关系)

楼主 1041159637  发布于 2015-11-08 21:54:00 +0800 CST  
但是兰顿蚂蚁最奇特的性质除了在纯色的平面上出现外,其他的初始图案最终也会让蚂蚁出现高速公路,但是出现的时间不尽相同。下面是几个例子

4*4的黑白相间的点阵(蚂蚁初始位置在右下角)

大概40秒后就会出现高速公路




爬行者的脸(蚂蚁初始位置在最左上角)


一分钟之后……


回形(蚂蚁初始位置为爬行者头处)


大约3分50秒后




233



大约2分20秒后


还有许多可能等待大家探索

楼主 1041159637  发布于 2015-11-08 22:00:00 +0800 CST  
最后,我根据我的算法写了一个单指令兰顿蚂蚁模拟器,只需要在白色羊毛(或者黑色)的超平坦世界使用即可。这个是指令的链接(推荐版本1.8.8):http://pan.baidu.com/s/1mgJAvbU
白色羊毛超平坦世界的生成代码3;minecraft:wool;37;
OCS安装完毕后,你只需要打开“遥控器”,点击“开始运动”,蚂蚁就会运动了,亦可暂停。

楼主 1041159637  发布于 2015-11-08 22:02:00 +0800 CST  
另外让我们看看蚂蚁的一步是如何移动的:
这是蚂蚁的初始状态(起初蚂蚁方向为南,也就是facing分数为2):


运行第一组指令后,分数变为3:


运行第二组指令后,蚂蚁脚底下的方块变成黑色


运行第三组指令后,蚂蚁向右(相对于蚂蚁自己)移动了一格


如果蚂蚁起初脚底下是黑色方块:


那么像上面那样运行一步,蚂蚁会把原来方块颜色变成白色,然后向左转


楼主 1041159637  发布于 2015-11-08 22:05:00 +0800 CST  
----------------------------完---------------------------------


最后at人:
@魔修尔4@乾坤轩辕1@丶H2F2@zrdzhenshuai@1311600732孙
@虾米黄Sammy@fuze1007@魔修尔4 @GoldJo金佐 @填写信息用h
@pca006132

楼主 1041159637  发布于 2015-11-08 22:08:00 +0800 CST  

楼主:1041159637

字数:4632

发表时间:2015-11-08 22:32:00 +0800 CST

更新时间:2016-03-15 11:40:41 +0800 CST

评论数:99条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看