贪吃蛇AI吃满屏的经验之谈
作者:互联网
一:先提供效果图
二:分析流程
1.基本版贪吃蛇
首先,我们需要完成一个基本贪吃蛇游戏。
2.加入bfs完成基础搜索
基本的贪吃蛇游戏框架上加入bfs,bfs算法就不过多介绍了(后面会放出整个项目代码),说说思路,首先肯定是跑bfs从蛇头到蛇尾,其中所有遍历过的坐标都会存在一个坐标栈( 假设 que[] ):
这是栈的结构,本来想用链表,奈何太久没有用C++了,都是的JAVA,不熟悉了就用数组熟悉一点,这里的x、y是储存搜索过的坐标位置,headnum是什么,head用来bfs后从坐标栈(que[])反推出最短路径的关键比变量,head如果换成链表就是指向上一个出发的位置,我们放个图来说明
图片是丑了点,手动画的能说明就行,假设蛇头是(4,4),食物是(2,10),那首先肯定是bfs到食物位置停止,第一个坐标肯定是蛇头(我们把蛇头的head设为-1就行),最后一个点存的一定是食物位置,head记录的是:到达这个点(比如:食物)的上一个点的坐标 在坐标栈(que[])的下标,利用head就能得到上一个点的坐标(比如:食物上一个点就是 que[que[end].head].x ,que[que[end].head].y),利用循环就能从食物的位置反推出最短路径,这也是很多同学会用bfs但是不懂怎么去找路径的问题,贪吃蛇不是简简单单计算一共多少步能到达就可以了,还需要反推路径,随后就跟着反推的路径走(坐标点之间计算方向就行),最终吃到食物。(说实话用数组有点乱很多时候自己都弄晕自己,应该用链表的会好很多)。
到这里,简单版的贪吃蛇AI就做出来了,它会直接径直往食物去,而且路径是最短路径,但是你会发现有如果食物生成在蛇头找不到的地方,就会失效了,为了我们的AI更加智能,我们需要加入一些策略。
3.加入AI策略让贪吃蛇满屏
在有了基本的寻路之后,开始思考检测策略了,首先会遇到几种情况:
(1)能找到食物
(2)找不到食物找得到蛇尾巴
(3)找不到蛇尾巴也找不到食物
首先一点点出发,思考一下能满足(1)之后并前往后,如果出现另外两种情况,又该如何解决。
如果跑完(1)后出现(2),那么跟随尾巴走就好了,想一想,因为蛇头如果一直跟着尾巴蛇是不会死的。
如果跑完(1)后出现(3),那么无路可循,有一种方法是随机走一步空位,但是偶尔会出现走进自己绕的死糊涂当中,结论就是这个情况一出现基本是死局(当然可以计算权重方向等等来避免进死胡同,不过效率不高,会伴随着大量乱走空位,麻烦难实现),那如果出现这种情况会大概率死局,我们就避免这种情况发生。
解决思路:在要执行(1)的时候加上一个检测,从食物点出发,把食物点当做蛇头,然后在que[]中拿出的最短路径往真正蛇头遍历计算好长度,实现假设蛇头已经吃了食物后的位置
这是我的数据打印, 上面地图是真是地图,下面着是模拟吃了食物后的地图(4是蛇头,2是蛇身,3是食物,7是最短路径),可以从看到完成时按照最短的路径去排列剩下的蛇身,这里有个点要注意,蛇一旦吃了食物是会多一段出来,所以可以从图看到,上图蛇一共3个点,下图是4个点(包括蛇头)。
那么解决了模拟出(1)后的位置后,我们加上判断,判断(1)后(模拟蛇位置)能正常的(2),则我们会跟随(1)跑。(简单来说:如果我们吃了食物,蛇头能找到蛇尾,则说明吃了食物后不会出现(3)的情况,所以说是绝对的安全那么我们吃食物)。
那么基本思路完成:
先(1),如果(1)返回true,着出动虚拟蛇,在虚拟蛇的位置执行(2),如果满足,着执行(1),否者不执行(1), 如果(1)不能执行该怎么做,那么就会去执行(2),跟随尾巴走就好,每走一步去进行一次(1)的判断,直到能(1),一直重复。
到这里中级版的AI算法完成,测试的时候基本上能跑出很高的分数了,但是离满屏还差一个策略。
你会发现一种情况,
可以看到,完成上诉的策略之后,会出现一种情况,跟随尾巴的时候,是以最短路径去跟随,尾巴绕得太长,就有被蛇头追上的情况发生。
解决思路:把bfs尾巴的路径弄成最远路径的那个方向走就好了这样就会跑着远路去找尾巴,就不会出现追上尾巴的情况发生。(而且可以在跟随尾巴的过程中尽可能的填补多余空位)。
三:总结
至此,一个高级版的贪吃蛇吃满屏算法就完成了。地图越大成功率越低,因为填补空位的过程中,如果能找到食物就会以最短路径跑前 食物,其中有少数空位没能填补,容易出现空洞现象。
上图可以看到,如果跟随尾巴过程中,食物出现,并且检测吃了食物之后还能找到尾巴的话,就会直接最短路径跑去吃食物,你会发现过程中有点空位本可以填补,就因为食物的出现漏掉了几个填补,这种空洞极容易造成卡死状态(就是食物如果出现在那个洞中,洞一个空位没有,并且你紧紧跟随着尾巴吃掉后尾巴长度加以蛇就会死掉,就会造成这种循环,永远都跑不到那个洞的情况),可以自己去画图看看,就算没有食物,你往那个洞走了还是会出现另一个洞,这种空洞是导致不能吃满屏的最后因素了,我现在还没有弄出另一个策略,不过在地图不大的情况下空洞生成的概率还是小的,所以成功了还是挺高的。
不过找到了问题就有解决方案,欢迎各位大佬给小弟一点思路,下面附上github链接https://github.com/hjj869924024/snake.git,供大家学习交流(贪吃蛇本是别人发我的,后来自己整合了算法,本入代码写得有点乱,建议安装上诉思路自己去写,C我是太久没碰了,很多逻辑乱七八糟)
标签:蛇头,AI,路径,尾巴,满屏,bfs,贪吃蛇,食物 来源: https://blog.csdn.net/qq_30315977/article/details/115082783