欢迎光临散文网 会员登陆 & 注册

吃满全图?实现全自动贪吃蛇的一种可能(基于Python Turtle)

2021-10-24 23:07 作者:Moodie810  | 我要投稿

【本文富含GIF,请作好准备】

刚学会做贪吃蛇游戏时,B站就向我推了这个:

吃满全图的贪吃蛇

细腻的操作、精准的计算,每一步穿插避让都如此完美,想必是由程序控制。

也不知哪来的勇气,我决定自己学着写一个……


v0.0:广度优先搜索实现寻路

查阅了几个自动贪吃蛇的实现思路后,无一例外提及了“搜索算法”,所以第一天的任务确定:学会一种能用于贪吃蛇寻路的“搜索算法”!

利用B站知识区丰富的资源,我首先使用广度优先搜索算法(BFS)实现了寻路(其实是只学了这一种后就怠惰了),当天成果如下:

手工绘制迷宫,自动寻找通路


v0.1:生搬硬套BFS的笨蛇

在真正开始前,有必要明确一下贪吃蛇游戏的规则:

    1. 蛇分为多节,每吃到一次食物增加一节

    2. 蛇头可以向前、向左、向右行进,后面的蛇身跟随之

    3. 蛇头行进方向上撞到围墙或自身身体,即为游戏失败;遇到食物,则身体加一节

画一个10*10的地图,把起点和终点改为蛇头和食物,套用BFS算法,即实现如下效果:

能吃,但只能吃一点点

贪吃蛇动起来了!然而,当身体变长,它很快就挂了。可见,无尽的贪婪终将把自己逼上绝路

进行几次实验后,我发现了贪吃蛇的两大致死原因:

    1. 蛇身过长,将地图分为至少两个封闭图形,蛇头与食物间无通路(如下图a,我愿称这种情况为“生存状态”)

    2. 食物出现在了刁钻的位置,蛇吃到后将走入死路(如下图b,我称之为“迷茫状态”)

#能吃到食物且吃到食物后,还能追到蛇尾的状态,我称之为“快乐状态”    [手动滑稽]

图a 蛇头与食物间无通路
图b 蛇头将走入死胡同

于是有两个对应的解决策略:

    1. 因为蛇每往前走一格,蛇尾就会空一格出来,所以蛇头跟着蛇尾方向走肯定不会死;

    2. 如果食物出现在死路里,就不应该去吃它。但如何判断?其实,“食物在死路里”的一个充分条件是“吃了这块食物后,蛇头与蛇尾没有通路”。所以,要让蛇学会“三思而后行”,在奔向食物前想想,吃了这块“毒苹果”后是不是再走向蛇尾,如果不能,就只好去追赶蛇尾,以伺良机(指进入能够安全吃食的“快乐状态”)。


v0.2 学会了“追尾”的憨憨蛇

增加了上述两个策略后,贪吃蛇进入“生存状态”和“迷茫状态”后仍能继续行进并有效地生长,寿命明显提高,甚至在进行了50余次实验后表演了一波“吃满全图”:

人类早期驯化贪吃蛇实录

只简单增加了一次BFS寻找蛇头到蛇尾的通路,就取得如此明显的效果,简直是把我明天的欧气都耗尽了。其实这时我才开始遭遇贪吃蛇真正的难题。

学会追蛇尾的贪吃蛇,再也不会轻易地死掉,但它大部分时候会进入某种死循环,像这样:

还有特别气人的这样……

也就是当食物出现在某个位置时,蛇再也找不到安全的路线去吃它,而自身形成了一个曲折的回路,无法破解。

冥思苦想+翻找博客之后,我稍稍改变了“生存状态”或“迷茫状态”下蛇的行进策略……


v0.3 比较聪明的成年蛇

“你已经是一只成年蛇了,要学会自己找出路。”

如果蛇总是以最短路径向食物靠近,蛇身不可能全部贴合,势必产生许多小洞,留下死循环的隐患。让我们回到本文最开头的GIF,不难发现那条贪吃蛇似乎从一开始就没有走最短路径,而是常常贴着自身走,并且绕各种S形弯,保证了行进的可持续。

这启发我改变“生存状态”或“迷茫状态”下蛇的行进策略:蛇应该远离食物,直至回到“快乐状态”。进入“生存状态”或“迷茫状态”后,需要先寻找蛇头周边的空位,并选择一个走过去。其中有两个要点:

    1. 蛇走进这个位置后,蛇头与蛇尾间仍要有通路;

    2. 在所有符合条件1的空位中,选择离食物最远的一个。

利用这两个条件,贪吃蛇就会自发地贴着自身走并绕一些S弯了。

以上图为例,蛇处于“生存状态”。蛇头左边是墙,不可走;走右边和前方都可到达蛇尾,但前方离食物更远,故向前走。


现在,重新捋一下思路:

最终效果如下:

最终效果

实验发现,吃满全屏的概率似乎已经从1/50上升到了60%以上,算是有一定的提高了。

而最后一个未解决的问题如下:

最后的死循环

仍然是死循环的问题,常常在剩余1格未填满时陷入死循环,极少数时候还出现过剩余3格未填满的情况。


写在最后

对于最后的死循环,既有的改进思路是:在蛇身达到一定长度时,就开始S形绕弯,预防“最后几个洞”的出现。

但应该在蛇身达到多少时改换策略呢?填满70%的地图时?50%?或是蛇达到能绕地图一周的长度时就要开始绕S形,就像本文最开头的GIF那样?我暂时没有能力探索下去……


如果只是为了做到“吃满全图”,其实早已有完美的解决方案,即不停地S形绕弯(用不自交的封闭曲线填满地图),就像这样:

无脑绕弯大法

难道应该基于这种最“无脑”的S形吃法,去改进它的效率?

我猜想这个视频中的蛇正是如此,因此前期显得“有点不太聪明的亚子”。简单粗暴,但保证有效:2分钟看完贪吃蛇全集


S形吃法并非唯一保稳的操作,参见这个视频中贪吃蛇的华丽走位:人工智能AI挑战贪吃蛇,这就是人工智能的艺术!


还有一种十分接近人类的走法:贪吃蛇理论最高分

这是一个13*8的地图,走法直接了当,前期转向很少,后期也是绕最小的S形弯。如果说这是真人操作我也愿意相信。


最后的一点点想法都放在这里了。有朝一日做出能100%成功吃满全图的贪吃蛇,再来更新v1.0吧……


思路主要参考

https://blog.csdn.net/fox64194167/article/details/19965069

编程实现自动玩贪吃蛇游戏

贪吃蛇AI—基于BFS算法+Pygame



您竟然看到了这里……悄悄引个流吧  [doge]

贪吃蛇× 蠕虫√


吃满全图?实现全自动贪吃蛇的一种可能(基于Python Turtle)的评论 (共 条)

分享到微博请遵守国家法律