浅析初等贪吃蛇AI算法

  作为小学期程序设计训练大作业的一部分,也是自己之前思考过的一个问题,终于利用小学期完成了贪吃蛇AI的一次尝试,下作一总结。

  背景介绍:

  首先,我针对贪吃蛇AI这一关键词在百度和google上尽心了检索,大致获得了一下信息

  1、A*寻路算法是人工智能中的一个经典算法,很多AI利用这个算法提高性能。

  2、在alphaGo一战成名,人工智能家喻户晓之后,有一个贪吃蛇AI吃满全屏的GIF图已读在微博疯转。

  3、这个GIF图早在2013年就已经出现了(其实比alphaGo早)。

  4、国内过于贪吃蛇AI(也就是百度得到的信息)的文章中比较有参考价值的只有两篇:如何用Python写一个贪吃蛇AI 以及 贪吃蛇 AI 的实现 snake AI。但感觉这两篇的算法还是很初级的,我认为不能保证每次都吃满全屏。

  5、那张吃满全屏的GIF是一个俄罗斯人实现的(最后一段还出现了俄文),联想俄罗斯方块,大概俄罗斯程序员就喜欢写这些东西自娱自乐吧。

  6、仔细观察那张GIF,可以断定绝对不是简单的盲目搜索算法,肯定使用了比较高级的AI算法(从蛇吃食物的路径可窥探一二)。

  7、没有可以直接参考的代码,虽然有份python代码,但已经基本看不懂了。。。。

  我的设计:

  首先,我的出发点是希望尽可能利用数据结构课上学到的知识解决这个问题,所以我没用A*(运行之后的效率还是很可观的),更没用其他高级的AI算法。其次,我希望尽量把问题集中在算法设计上(后来证明这个想法还是很明智的),所以放弃了用Java的Swing以及Java2D做图形界面的打算,直接控制台编程,使用C/C++编写代码(后来证明这个想法太愚蠢了)。

  这里直接写我的思路,如果看过上面两个链接的文章理解下面内容肯定更容易。如果没看,就记住两句话,蛇追着自己的尾巴走肯定就不会死,因为尾巴永远在留出空间。蛇每次只移动一步,因为局势时刻在变化。

  首先,分析蛇的状态无非以下三种:

    1、能吃食物,吃完食物后还能找到尾巴,这时候就直接去吃食物。

    

    2、蛇不能吃食物,或者吃食物后找不到尾巴(找不到尾巴还去吃是不允许的,这回导致吃完后无路可走),这时候就跟着蛇尾巴走,走到能去吃食物为止(为什么能走到下面解释)。

    

    3、在状态2的前提下,尾巴都找不到,这时候只能随便走一步了(Wander,其实wander策略时这类游戏很重要的一种思想,我也是看过一些书之后才明白)。

    

  以上,也是我检索到的AI算法的核心部分,但是,在实践中,我发现很多细节这些文章都没有说清楚,实践起来是不允许有一点差错的,所以,结合自己的实践,对这几种情况做一下更详细的分析:

    1、能吃食物,并且吃完之后能找到尾巴。这种情况只在蛇身较短的时候出现,而且这里吃完之后能找到尾巴,指的是沿最短路径去吃。或许,走最短路吃完食物找不到尾巴了,而走一条较长的路径能找到,但还是认为后一种不属于状态一,否则,编写代码将变得十分复杂。但是有时候,可能不止一个方向到食物的路径最短,这时候可以用类似蒙特卡洛法随机选择方向,可以提高吃完食物后找到尾巴的可能性,实践证明也确实如此。

    2、追着尾巴走,也是又讲究的,首先,要保证走完这一步后还能继续找到尾巴,这是基本前提,其次,如果两个方向都能找到尾巴,应该选择离食物较远的方向(注意不是离食物较近或者离尾巴较近),应为只有这样,才能保证留出了足够空间给蛇去吃食物。

    3、在我查阅的文章中Wander的策略都是比较简单的随机,但是,我觉得用DFS找出一条比较深的路,按这条路走比较好,但是注意不能贴着墙完全按最深路走,否则会导致蛇无法回头,像这样。

    

  这样,这个算法就可以写成一下伪代码:

 1 if 可以吃食物
 2         if 虚拟蛇沿规则最短路吃食物后能找到尾巴
 3                 真实蛇移动一步
 4                 重新判断
 5         else if 虚拟蛇沿不规则最短路去吃食物能找到尾巴
 6                 真实蛇移动一步
 7                 重新判断
 8 else if 可知到达自己的尾巴并且移动一步已让可以到达自己尾巴
 9         选择离食物最远的位置移动
10         重新判断
11 else
12         DFS向最深的路径移动一步

  纸上得来终觉浅,理解这个算法最好的方式还是实践!实践之后才发现,吃满全屏并不是想象的那么容易,从博弈的角度来看,蛇的信息始终是不完全的,所以,必须有更优秀的算法,才能解决这一问题,除非到一定长度开始沿一条可以遍历所有位置的路径循环反复的绕,但这样太没意思了。记得貌似就有一个比赛是关于AI贪吃蛇的,但确实没检索到太多信息。希望以后还有机会研究出更优的算法。

  demo:

  

  源代码获取:

  点这里

时间: 2024-10-12 19:56:19

浅析初等贪吃蛇AI算法的相关文章

贪吃蛇AI

贪吃蛇AI 作者:CodeNoob 转载请标明作者和出处 序言 前几天在网上看到一张让人涨姿势的图片,这张图片我很早以前看过,当时就觉得肯定是程序实现的,只是当时还比较渣,不会算法.这次学了java也正在学算法,便打算开始实现它,说做就做,let’s do it 语言选择 Java,虽然好久不用Swing 最初版本 Make it work 首先肯定是先让程序能跑,再去想算法,开始肯定是在一个矩形里不断的随机出现食物,然后让蛇在不走出矩形的情况下去吃,蛇每吃一个食物就会变长.这时问题基本就是,给

如何用Python写一个贪吃蛇AI

前言 这两天在网上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过.但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了. 问题的关键在于,图片中的贪吃蛇真的很贪吃XD,它把矩形中出现的食物吃了个遍, 然后华丽丽地把整个矩形填满,真心是看得赏心悦目.作为一个CSer, 第一个想到的是,这东西是写程序实现的(因为,一般人干不出这事. 果断是要让程序来干的)第二个想到的是,写程序该如何实现,该用什么算法? 既然开始想了,就开始做.因为Talk is cheap,要sho

Perl字符贪吃蛇

一时兴起,想试试能不能用perl实现字符贪吃蛇,算法如下: 定义2个数组@bg.@snake,@bg用来显示整个界面,@snake从蛇头开始保存蛇的坐标点. 蛇每移动一次,新的坐标点放到@snake头部,并去除最后一个元素,再改变@bg对应坐标的值. 通过控制台窗口不断清屏再打印,使蛇“看起来在移动”. 简单的速度控制实现:每次移动后sleep 若干秒. 一个要解决的问题:无阻塞获取按键.通过度娘找到模块Term::ReadKey,新的问题产生了:批量输入方向,蛇会依次按照输入移动,暂时想不到好

python实现贪吃蛇

贪吃蛇的算法还是比较简单的,蛇的移动我是通过不停添加一个head方块,然后判断应该加到蛇头的哪个方向,加完后删掉蛇尾就行了,如果吃到食物就不删蛇尾. 只是一个贪吃蛇只需要70行代码左右就可以了,后来又加了计分,失败后重新游戏,暂停功能····结果现在代码乱成渣了.. 重新游戏部分肯定有更好的方法,我写的太乱了..求大神指教.由于没用网格,判断吃到的时候是用范围判断的,有时候有些偏差··· 代码: 1 #-*- coding: utf-8 -*- 2 import pygame, sys, ran

Python制作AI贪吃蛇

前提:本文实现AI贪吃蛇自行对战,加上人机对战,文章末尾附上源代码以及各位大佬的链接,还有一些实现步骤,读者可再次基础上自行添加电脑VS电脑和玩家VS玩家(其实把人机对战写完,这2个都没什么了,思路都一样) 大佬Coco2d制作:http://www.waitingfy.com/html5/snake/ 实现效果: 具体功能: 1.智能模式:电脑自己玩(自己吃食物) 2.人机对战:电脑和人操作(在上步的基础上加一个键盘控制的贪吃蛇即可) 实现环境: Pycharm + Python3.6 + C

贪吃蛇小游戏 (一)

贪吃蛇是一款儿时爱不释手的游戏.近日修行,想玩玩游戏开发.便简单写了个控制台版的贪吃蛇. 程序的简单框架: 建立一张固定大小的MAP,保存输出信息. 当信息有变动时,用system("cls")进行清屏操作,再重新输出实现伪动态. 重点算法在蛇身的移动,转向与增长.三者均基于链表实现. 移动与转向:通过判定移动方向,确定下一步移动的位置后,新建表头结点.将新表头结点置为表头.删除末尾结点. 增长:通过判断尾部移动方向,确定位置后在尾部添加节点. 熟练运用链表的同学,相信也是小菜一碟了.

贪吃蛇的java代码分析(一)

自我审视 最近自己学习java已经有了一个多月的时间,从一开始对变量常量的概念一无所知,到现在能勉强写几个小程序玩玩,已经有了长足的进步.今天没有去学习,学校里要进行毕业答辩和拍毕业照了,于是请了几天的假,自己也就有了一点空余的时间.回想这一个多月,自己做到好的地方是把大部分时间都用在了看书和码代码上,学习的重点放在了追求对知识的理解和内容的广度之上.书籍方面阅读了<java核心技术>和<java编程思想>,虽然说没有理解全部的内容,<编程思想>一书也只看了300多页,

Canvas贪吃蛇大作战斗实现及思考

一向比较后知后觉,上周才发现了贪吃蛇大作战这个游戏,玩了一下,居然很上瘾!应该讲是一种虐的快感和不小心死掉的遗憾和再来一盘的心态的集合! 只是当时有个思考,就是游戏如何在我切换到其他应用后依然回来可以继续对战!是将我的数据及时保存,然后从这个游戏房间把我先挂起来,然后其他的玩家就会看到我突然在这里消失了?那么再将我恢复的时候如何保障不与其他用户冲突! 同时我发现每次进来,旁边的蛇依然在原来的位置,而且一样的会躲闪我的攻击等,我想那其他玩家的历史数据是怎么做到能判断我当前切换进来的行为!当时我还思

小项目特供 贪吃蛇游戏(基于C语言)

C语言写贪吃蛇本来是打算去年暑假写的,结果因为ACM集训给耽搁了,因此借寒假的两天功夫写了这个贪吃蛇小项目,顺带把C语言重温了一次. 是发表博客的前一天开始写的,一共写了三个版本,第一天写了第一版,第二天写了第二版和第三版. 相信C语言写个小游戏或小项目是大多数计算机相关专业的学生都做的事情,但是作为一个数学专业的学生,我们教研室的老师对C语言的要求也就比较低了,大一没有让我们做个小项目实践一次.至今为止用C/C++做过的三个小项目(大作业),一个是外校同学让我帮忙写的学生信息管理系统(天呐,这