作为小学期程序设计训练大作业的一部分,也是自己之前思考过的一个问题,终于利用小学期完成了贪吃蛇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找出一条比较深的路,按这条路走比较好,但是注意不能贴着墙完全按最深路走,否则会导致蛇无法回头,像这样。

    

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

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

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

  demo:

  

  源代码获取:

  点这里

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

  1. 贪吃蛇AI

    贪吃蛇AI 作者:CodeNoob 转载请标明作者和出处 序言 前几天在网上看到一张让人涨姿势的图片,这张图片我很早以前看过,当时就觉得肯定是程序实现的,只是当时还比较渣,不会算法.这次学了java也 ...

  2. 如何用Python写一个贪吃蛇AI

    前言 这两天在网上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过.但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了. 问题的关键在于,图片中的贪吃蛇真的很贪吃XD, ...

  3. AI贪吃蛇前瞻——基于Dijkstra算法的最短路径问题

    在贪吃蛇流程结构优化之后,我又不满足于亲自操刀控制这条蠢蠢的蛇,干脆就让它升级成AI,我来看程序自己玩,哈哈. 一.Dijkstra算法原理 作为一种广为人知的单源最短路径算法,Dijkstra用于求 ...

  4. AI贪吃蛇(二)

    前言 之前写过一篇关于贪吃蛇AI的博客,当时虽然取得了一些成果,但是也存在许多问题,所以最近又花了三天时间重新思考了一下.以下是之前博客存在的一些问题: 策略不对,只要存在找不到尾巴的情况就可能失败, ...

  5. 如何用python制作贪吃蛇以及AI版贪吃蛇

    用python制作普通贪吃蛇 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...

  6. python实现贪吃蛇

    贪吃蛇的算法还是比较简单的,蛇的移动我是通过不停添加一个head方块,然后判断应该加到蛇头的哪个方向,加完后删掉蛇尾就行了,如果吃到食物就不删蛇尾. 只是一个贪吃蛇只需要70行代码左右就可以了,后来又 ...

  7. Perl字符贪吃蛇

    一时兴起,想试试能不能用perl实现字符贪吃蛇,算法如下: 定义2个数组@bg.@snake,@bg用来显示整个界面,@snake从蛇头开始保存蛇的坐标点. 蛇每移动一次,新的坐标点放到@snake头 ...

  8. Python制作AI贪吃蛇

    前提:本文实现AI贪吃蛇自行对战,加上人机对战,文章末尾附上源代码以及各位大佬的链接,还有一些实现步骤,读者可再次基础上自行添加电脑VS电脑和玩家VS玩家(其实把人机对战写完,这2个都没什么了,思路都 ...

  9. Python制作AI贪吃蛇,很多很多细节、思路都写下来了!

    前提:本文实现AI贪吃蛇自行对战,加上人机对战,读者可再次基础上自行添加电脑VS电脑和玩家VS玩家(其实把人机对战写完,这2个都没什么了,思路都一样) 实现效果: 很多人学习python,不知道从何学 ...

随机推荐

  1. .NET 4.0 任务(Task)

    随着 .NET 4.0的到来,她与以前各版本的一个明显差别就是并行功能的增强,以此来适应这个多核的世界.于是引入了一个新概念---任务,作为支持并行运算的重要组成部分,同时,也作为对线程池的一个补充和 ...

  2. 我这样理解js里的this

    关于this,是很多前端面试必考的题目,有时候在网上看到这些题目,自己试了一下,额,还真的错了!在实际开发中,也会遇到 this 的问题(虽然一些类库会帮我们处理),例如在使用一些框架的时候,例如:k ...

  3. SQLServer(MSSQL)、MySQL、SQLite、Access相互迁移转换工具 DB2DB v1.1

    最近公司有一个项目,需要把原来的系统从 MSSQL 升迁到阿里云RDS(MySQL)上面.为便于测试,所以需要把原来系统的所有数据表以及测试数据转换到 MySQL 上面.在百度上找了很多方法,有通过微 ...

  4. Java:泛型

    一.序言 变化一: 在引入范型之前,Java中的类型分为原始类型.复杂类型,其中复杂类型分为数组和类:引入范型后,一个复杂类型可以细分成更多的类型. 例如,原先的List类型,现在细分成List< ...

  5. Javascript DOM操作实例

          最近在学DOM,但是还是没有办法很好的记住API,想找些例子来练习,网上的例子将一个个DOM对象方法挨个举例,并没有集合在一起用,效果不尽人意.所以自己写一份实例,顺便巩固下学到的知识. ...

  6. [译]用AngularJS构建大型ASP.NET单页应用(二)

    原文地址:http://www.codeproject.com/Articles/808213/Developing-a-Large-Scale-Application-with-a-Single 客 ...

  7. 又发现个.net framework的坑

    请找出这两个方法的区别: http://msdn.microsoft.com/en-us/library/ms584187(v=vs.110).aspx

  8. dinic模板

    procedure addedge(u,v,cap:longint); begin sid[tot].u:=u; sid[tot].v:=v; sid[tot].cap:=cap; sid[tot]. ...

  9. 64-who 简明笔记

    显示已登录用户的信息 who [options] who am i who程序显示在本地系统上登录的用户的信息.这些信息包括每个用户的用户名.终端设备.登录时间和相应的远程主机名(如果可应用) 参数 ...

  10. MySQL中的insert ignore into, replace into等的一些用法总结

    在MySQL中进行条件插入数据时,可能会用到以下语句,现小结一下.我们先建一个简单的表来作为测试: CREATE TABLE `books` ( `id` INT(11) NOT NULL AUTO_ ...