愉快的开始
最近在修一门叫Python基础的课,然后匆忙之中做了这个AI贪吃蛇想交个大作业,结果老师的结课作业是给定了题目,我真是……
首先说明一点哈,此AI非彼AI。今天要讲的AI贪吃蛇还是传统意义上遍历图的找路算法编写的,并不是利用机器学习进行学习控制的哈。
关于贪吃蛇
Python编写贪吃蛇的教程此前已经写过了,相关的传送门可以戳:
那么今天的AI贪吃蛇就是在此基础上完成的,加了AI相关的功能。具体的相关演示图如下:
当然了,AI部分是在一位大神@Charles的代码中整合过来的。总体还是采用广度优先搜索遍历+虚拟走一次(不知道这样算不算作弊呢,欢迎各位在留言区讨论)的方式进行,目前看来还是有些许问题:
- 可能吃不到满屏,最后的效果可能会空几个(下面会放图),依小编之见应该是找不到路到食物时随机走一步造成的,随机性导致了最后可能陷入死循环而吃不到满屏。
- 运行速度比较慢,一来可能是小编这个地图比较大,每次找路BFS搜索的时候是需要一点时间的,二来嘛Python确实是个速度比较慢的语言,算法速度上自然是比不上C++这种的。
关于C++的AI贪吃蛇,可以参照此前小编用C++写的一个不怎么完善的AI贪吃蛇,也算基于BFS,但是整个跑起来的速度快得多:
传送门: 10分钟教你用C++写一个贪吃蛇附带AI功能(史上最详细最入门的贪吃蛇教程)附源代码下载
然后再放上一张吃不满屏的图吧,┭┮﹏┭┮我跑了一个早上。结果你让我看这个?
哈哈,看不到头尾了,反正代码会放出来,有需要的小伙伴可以给他加个头,这样看起来辨识度更高。
AI部分
好了,现在介绍完了。我们来介绍一下AI部分的原理+算法吧。
地图
我们之前说了,算法是用BFS找路的。那么相应的地图就是整个的游戏区域了。其实整个游戏区域可以分成一个个的像素格子,每个格子就可以看成一张地图中的点(有xy坐标),只不过这些点只与相邻的点连通,这样就形成了一个图。
有了图以后,蛇身所在的位置就是障碍了,不能通过的。然后蛇的移动不能超出图所在的范围。一个点无法就这几种状态:
- 食物所在的位置(状态码为FOOD)
- 空位置(状态码为FREE_PLACE)
- 蛇所在的位置(状态码为SNAKE_PLACE)
我们用width表示地图的宽度,height表示地图的高度。在程序中,该状态用一个一维数组board[width * height]
进行标识:比如点(x,y)的状态就可以用board[x + width*y]
的具体取值表示(FOOD表示食物等)。
找路
找路的算法流程这里直接引用@Charles大神博客上写的流程:
主要思路
(1)蛇每走一步,就使用BFS计算游戏界面中每个位置(蛇身除外)到达食物的最短路径长;
(2)将蛇的安全定义为蛇是否可以跟着蛇尾运动,即蛇头和蛇尾间是否存在路径;
(3)蛇每次行动前先利用虚拟的蛇进行探路,若虚拟的蛇吃完食物后是安全的,真蛇才行动;
(4)若蛇和食物之间不存在路径或者吃完食物后并不安全,就跟着蛇尾走;
(5)若蛇和食物之间、蛇和蛇尾之间均不存在路径,就随便挑一步可行的来走;
(6)保证目标是食物时蛇走最短路径,目标是蛇尾时蛇走最长路径。
不足之处
由于食物是随机出现的,若虚拟的蛇跑一遍发现去吃食物是不安全的,真蛇就不会去吃食物,而是选择追着蛇尾跑,若一直如此,就陷入了死循环,蛇一直追着蛇尾跑跑跑。。。直到你终止游戏为止。。。