贪吃蛇AI
贪吃蛇AI
作者:CodeNoob 转载请标明作者和出处
序言
前几天在网上看到一张让人涨姿势的图片,这张图片我很早以前看过,当时就觉得肯定是程序实现的,只是当时还比较渣,不会算法。这次学了java也正在学算法,便打算开始实现它,说做就做,let’s do it
语言选择
Java,虽然好久不用Swing
最初版本
Make it work
首先肯定是先让程序能跑,再去想算法,开始肯定是在一个矩形里不断的随机出现食物,然后让蛇在不走出矩形的情况下去吃,蛇每吃一个食物就会变长。这时问题基本就是,给你一个起点(蛇头)和一个终点(食物),从起点找到一条可行路到达终点。这个路怎么走呢,最简单的就是走曼哈顿距离了.
如下图,绿色是蛇头蓝色是蛇尾,蛇头在去吃食物的时候是直接穿过身体的,这是最简单的方法,先运行起来。

BFS
搜索路径的算法其实有多种,分为盲目式搜索和启发式搜索。其中盲目式搜索有DFS和BFS,启发式搜索有A*和有序搜索(或者最佳优先搜索),
这里我用的BFS,首先将蛇头节点放入队列,然后循环弹出队列直到队列为空,为空返回-1,没找到路径,每弹出一个队列里的节点,判断该节点是不是食物,如果不是食物,把该节点添加到vis表说明已经走过,并且把该节点相邻的上下左右四个节点添加到队列里并记录下节点的父节点(我用的HashMap),添加时如果节点在vis表或者出了墙或者是身体节点,就不添加到队列里。如果是食物,返回去食物的第一步的方向,因为我是线程每刷新一次,蛇走一步。这样每走一步就BFS找最优路径。

调了下速度所以比较快,当蛇吃完食物后发现自己没路去吃另外出现的食物时就会GG了
所以不能出现食物就立马去吃,得先判断吃完后能否吃下一个,这里其实可以在随机食物的位置时把下一个食物的位置提前随机出来,不过这样就有点算作弊的感觉。。
高级版
make it right
当我们不知道下一个食物的位置时就只能模拟一条蛇去吃了,我们派一条虚拟蛇(不画在屏幕上)去吃,虚拟蛇吃后生成的食物也是虚拟的所以我们不知道真实食物吃完又会在哪出现,吃完怎么判断是否能去吃下一个呢?
我们可以看最上面的吃完全图的可以发现,当它吃完后能跟着尾巴走就表明是安全的,于是策略是
if(能吃到食物)
派虚拟蛇去吃,
if(吃完能跟着蛇尾走) 真蛇去吃
if(吃完不能跟着蛇尾) 真蛇跟着蛇尾走
else
真蛇跟着蛇尾
if(不能吃食物也不能跟着蛇尾)随便逛逛,

高级进阶版
解决办法还是得从原图来,(原图不知道被我看了多少遍。。)发现蛇头在追蛇尾时我总是走的最短路径,其实应该还可以不那么快走到蛇尾可以到绕下弯去,这就不能用BFS了。于是本不愿意写A*算法的,只好用A*算比较远的路径了。(为什么A*不是最远路径因为这个怎么判断多远我是用曼哈顿距离的大小判断远近,实际是可以不停绕弯走才是最远的,不过这样就不好写算法了。)
A*其实本质就是BFS加贪心,怎么贪就是给当前节点周围的四个节点先估计下哪个离目标(食物)远一点或近一点(我们要找最远路肯定想远一点),权值表示这个(远或近的)程度,权值越大越远,越小越近,不用像BFS那样四个都走一遍,我们只走权值最大的那个,就可能离远一点。
具体A*算法步骤如下
//将开始节点放入open表
while(opne表不为空){
0.在open表找F值最大的(说明离目标最远),如果有相同我们选的排在后面的也就是最新添加的。
1.把当前节点从开放列表删除, 加入到封闭列表;
2.遍历四个方向的相邻节点
(0)如果该相邻节点不可通行或者该相邻节点已经在封闭列表中,则什么操作也不执行,继续检验下一个节点;
(1)如果该相邻节点不在开放列表中,则将该节点添加到开放列表中,并将该相邻节点的父节点设为当前节点,同时保存该相邻节点的G和H值
[0]当终点节点被加入到开放列表作为待检验节点时, 表示路径被找到,此时终止循环,返回方向;
(2)如果该相邻节点在开放列表中,则判断若经由当前节点到达该相邻节点的G值是否大于或小于(这里找最远用大于)原来保存的G值,若大于或小于,则将该相邻节点的父节点设为当前节点,并重新设置该相邻节点的G和H值
}
//当开放列表为空,表明已无可以添加的新节点,而已检验的节点中没有终点节点则意味着路径无法被找到,此时也结束循环返回-1;
然后我们换个策略
吃食物时走最近路径
追尾巴时走最远路径


通过最后一个结果可以看出,由于是随机产生的食物,还是有吃不到的时候,这时就只能优化食物的出现算法或调整寻路算法了。(想要吃满全图,可以一直走S路就可以了,不过这样没意思了)。
最后
如果对源代码感兴趣请戳我
如果有需要优化的地方的话,我想可能BFS太慢了,还是直接全用A*或许能减少点CPU的压力,哈哈。
贪吃蛇AI的更多相关文章
- 浅析初等贪吃蛇AI算法
作为小学期程序设计训练大作业的一部分,也是自己之前思考过的一个问题,终于利用小学期完成了贪吃蛇AI的一次尝试,下作一总结. 背景介绍: 首先,我针对贪吃蛇AI这一关键词在百度和google上尽心了检索 ...
- 如何用Python写一个贪吃蛇AI
前言 这两天在网上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过.但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了. 问题的关键在于,图片中的贪吃蛇真的很贪吃XD, ...
- AI贪吃蛇(二)
前言 之前写过一篇关于贪吃蛇AI的博客,当时虽然取得了一些成果,但是也存在许多问题,所以最近又花了三天时间重新思考了一下.以下是之前博客存在的一些问题: 策略不对,只要存在找不到尾巴的情况就可能失败, ...
- AI贪吃蛇前瞻——基于Dijkstra算法的最短路径问题
在贪吃蛇流程结构优化之后,我又不满足于亲自操刀控制这条蠢蠢的蛇,干脆就让它升级成AI,我来看程序自己玩,哈哈. 一.Dijkstra算法原理 作为一种广为人知的单源最短路径算法,Dijkstra用于求 ...
- 如何用python制作贪吃蛇以及AI版贪吃蛇
用python制作普通贪吃蛇 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...
- Python制作AI贪吃蛇
前提:本文实现AI贪吃蛇自行对战,加上人机对战,文章末尾附上源代码以及各位大佬的链接,还有一些实现步骤,读者可再次基础上自行添加电脑VS电脑和玩家VS玩家(其实把人机对战写完,这2个都没什么了,思路都 ...
- 【C/C++】10分钟教你用C++写一个贪吃蛇附带AI功能(附源代码详解和下载)
C++编写贪吃蛇小游戏快速入门 刚学完C++.一时兴起,就花几天时间手动做了个贪吃蛇,后来觉得不过瘾,于是又加入了AI功能.希望大家Enjoy It. 效果图示 AI模式演示 imageimage 整 ...
- Python制作AI贪吃蛇,很多很多细节、思路都写下来了!
前提:本文实现AI贪吃蛇自行对战,加上人机对战,读者可再次基础上自行添加电脑VS电脑和玩家VS玩家(其实把人机对战写完,这2个都没什么了,思路都一样) 实现效果: 很多人学习python,不知道从何学 ...
- Python-pygame案例AI贪吃蛇
# coding: utf-8 import pygame,sys,time,random from pygame.locals import * # 定义颜色变量 redColour = pygam ...
随机推荐
- Twisted No module named win32api
安装twisted成功后,使用时抛错: No module named win32api 解决方案,需要安装 pywin32 下载地址: https://sourceforge.net/project ...
- CSS Hack代码与浏览兼容总结
关于CSS Hack的东西能少尽量少吧.发现这篇文章我写得太复杂了,所以重新精简了一下,把代码粘贴到jsfiddle上,方面修改代码和维护. 1, IE条件注释法,微软官方推荐的hack方式. 只在I ...
- Unicode字符列表
注:除非有特别指明,否则以下符号皆属“半角”而非“全角”. 代码 显示 描述 U+0020 空格 U+0021 ! 叹号 U+0022 " 双引号 U+0023 # 井号 U+0024 $ ...
- .net mvc下的Areas和小写Url
首先是一个站点有前台后台两部分,这个要怎么来做.可以在mvc项目中添加区域(Areas)来实现,当添加一个名为Admin的区域时,项目下多了一个Areas/Admin目录,里边有Controllers ...
- HTML5学习笔记之客户端存储数据方法:localStorage(),sessionStorage()
HTML5提供了两种在客户端存储数据的新方法: localStorage():没有时间限制的数据存储 sessionStorage():针对一个session的数据存储 下面的一个例子用localSt ...
- 使用MIDAS访问远程Access数据库
使用MIDAS访问远程Access数据库 Allen Tao(http://blog.csdn.net/allentao/) 2005-5-3 本文源码下载 访问远程数据库常用的办法是 ...
- C语言入门(9)——局部变量与全局变量
变量有效性的范围称变量的作用域.C语言中所有的量都有自己的作用域.变量说明的方式不同,其作用域也不同. C语言中的变量,按作用域范围可分为两种,即局部变量和全局变量. 局部变量 局部变量也称为内部 ...
- POJ1185 炮兵阵地 状态压缩
因为不知道不同的博客怎么转,就把别人的复制过来了,这个题解写的非常好,原地址为: http://hi.baidu.com/wangxustf/item/9138f80ce2292b8903ce1bc7 ...
- ActiveMQ使用STOMP协议的一个错误问题:Unexpected ACK received for message-id
使用某些语言环境下的stomp包(比如php python ruby),可能会出现如下问题: Unexpected ACK received for message-id 这一般可能有两个原因. 1. ...
- 通过案例练习掌握SSH 的整合
1. SSH整合_方案01 ** 整合方案01 Struts2框架 Spring框架 在Spring框架中整合了Hibernate(JDBC亦可) 一些业务组件(Service组件)也可以放入 ...