贪吃蛇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 ...
随机推荐
- 微博发布效果jq版
大家都看过新浪微博的发状态功能,我模拟了一下类似的效果,包括发布时间,删除效果等.代码如下: <!DOCTYPE HTML> <html> <head> <m ...
- HTML5 canvas易错点
一.画布的默认宽高 <canvas id="myCanvas" style="border:1px solid black;"> 你的浏览器不支持h ...
- jquery学习(3)--高级选择器
自己手写的学习笔记.常规选择器: /****************学习--高级选择器(1)****************/---高级选择器:ie7+ 层次选择器: 后代选择器 ul li ...
- Cortex-M3 动态加载一(地址无关代码实现)
这篇文章是自己疑惑究竟地址无关性是如何实现,然后查看汇编和CPU指令手册,最后分析解除自己疑惑的,高手不要鄙视,哈哈. 编译C代码时候需要制定--acps/ropi选项,如下例子: void Syst ...
- linux修改文本模式下的分辨率(CentOS6.4)
root登录 vi /boot/grub/menu.lst 看到如下界面: 红框全出位置为分辨率设置,设置参数如下: 保存 shutdown -r now
- rsyslog 日志格式和输出
日志格式: $EscapeControlCharactersOnReceive off #关闭rsyslog默认转译ASCII<32的所有怪异字符,包括换行符等 $template nginx- ...
- [Leetcode][Python]23: Merge k Sorted Lists
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 23: Merge k Sorted Listshttps://oj.leet ...
- jQuery $.each用法比较详细了
以下内容非原创,来自百度文库http://wenku.baidu.com/view/4796b6145f0e7cd18425368e.html 通过它,你可以遍历对象.数组的属性值并进行处理. 使用说 ...
- 代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性
做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线.真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程( ...
- Objective-C 类属性和方法的訪问权限
OC中提供了4种訪问权限.@private, @public, @protected这三种和其它的C++, Java是一样的,@package这个訪问权限并非Java里的包訪问权限,OC中没有包的概念 ...