贪吃蛇 AI 的实现 snake AI

2023-05-16

1.首先看下这个非常在微博上很火的贪吃蛇gif



这次我们尝试用代码来模拟下,说不定上面这个图就是计算机搞的。


2.讲贪吃蛇AI之前,我们先看下贪吃蛇移动的特点

物理上给人的感觉是整个贪吃蛇往右移了一步,在贪吃蛇非常长的情况下给人的感觉移一步要做很多事情。但是在计算机中我们可以简单的考虑贪吃蛇的移动,假设用一个数组来存储所有组成贪吃蛇的格子,那么移动一步,就是把将来的格子插入到这个数组的头部,然后再去掉这个数组的最后一个元素。我们只做两件事情,就完成了一整条蛇的移动!往下看之前,再仔细考虑下移动这个问题。

在说贪吃蛇AI之前,我们要考虑一个问题:怎样保证贪吃蛇永远不死?我们知道无论往那个方向前进一步,尾巴的格子都会空出来,那么追着贪吃蛇的尾巴移动,就能保证贪吃蛇永远不死!


3.寻路算法之A Star


贪吃蛇一般情况下要找一个最短路线去吃苹果,这个时候A star寻路算法就派上用场了,如果你对A Star 算法还不了解,可以先看下这篇文章:《Cocos2d-x 寻路算法之三 A Star》 。这里用A Star 需要特别注意两个问题:1.整个蛇的身体是不可接触的格子的,要排除掉。2.因为贪吃蛇移动是一个动态的过程,所以每走一步,要重新进行寻路,而不是一次寻路完,走完路线,因为尾巴的位置会不断的空出来。


4.单纯使用寻路算法遇到的问题


4.1会进入死胡同



黄色的是贪吃蛇的头部,红色是我们要吃的东西,根据寻路算法,黑色的就是最短路线,可以在脑子里脑补下,吃完这个东西,贪吃蛇就挂了!


4.2 找不到路线



在贪吃蛇足够长的情况下,苹果可能会在蛇身体包围的圈中,看上图,黄色表示头部,那么蛇就找不到路线了!


4.3 一味的最短路线吃东西,留下太多洞



我们看下这张图,红色的表示现在出现的苹果,橙色的表示吃完红色的苹果后,苹果可能出现的位置,如果我们简单的用最短路线去吃红色的,即无脑往左走,那么橙色的就在会出现在蛇的包围圈中,将来要吃这个就非常不利,要走很多步。


这个时候比较好的走法是下图:



尽可能的多绕,尽可能地把空白地方填完,而不是以最短路线去吃,要为将来打算。


5. 贪吃蛇的最佳无脑模式


一想到4.3的问题,我就觉得贪吃蛇AI是非常难的一个问题,难道还是设及到“一笔画问题”,那就太难了。不过还好,玩了这么多局的贪吃蛇,我发现一个无脑模式,可以填满整个游戏区域。见下图:



就是在最后一行空出来,留做逃生的路线,然后像弹簧一样无脑向右推进,吃完后,从底部绕回最左边,继续这样的策略,直到填满整个游戏区域。不知道读者懂不懂这样的策略。


6.开始讲我的贪吃蛇AI实现了


一定要先理解上面的东西,才好继续往下看。我们知道追着尾巴跑,蛇就不会死,所以我们以最短路线去吃苹果时,要给自己留条后路,策略1.如果吃完苹果还可以找到到自己尾巴路线的话,才去吃苹果。

下面给出的是伪代码:


var canFindPath= false;                              //可以找到吃苹果的路线
var canFindTail = false;                             //可以找到自己尾巴的路线
canFindPath = startPathFinding();                    //开始寻找路线
        if(canFindPath){                             //如果可以找到吃苹果的路线
            moveSnake()                              //移动一条看不见的贪吃蛇去吃
            canFindTail = startPathFinding();        //尝试找自己尾巴路线
            if(canFindTail){                         //如果可以找到自己尾巴路线
                return safePathCell;                 //返回吃苹果路线的第一步
            }
        }

策略2.如果找不到吃苹果路线或者吃完苹果后,会发生找不到自己尾巴路线的话,那么就在头部的周围找一个格子,这个格子要满足两个条件,条件1,走完这个格子要能找到到尾巴的路线,条件2,这个格子到苹果的距离是最远的。


策略2中的条件1,我们肯定是能找的到的,因为我们的AI的基础都是基于策略1。

策略2的伪代码如下:

var canFindPath= false;                              //可以找到吃苹果的路线
var canFindTail = false;                             //可以找到自己尾巴的路线
canFindPath = startPathFinding();                    //开始寻找路线
        if(canFindPath){                             //如果可以找到吃苹果的路线
            moveSnake()                              //移动一条看不见的贪吃蛇去吃
            canFindTail = startPathFinding();        //尝试找自己尾巴路线
            if(canFindTail){                         //如果可以找到自己尾巴路线
                return safePathCell;                 //返回吃苹果路线的第一步
            }
        }
if(canFindPath == false || canFindTail == false ){
            return getACellThatIsFarthestToGoal();
   }

注意下策略2中的条件2,我们没有用什么高深的算法,我们仅仅是把蛇往一个到苹果最远的格子移动,运行起我们的贪吃蛇,我们发现贪吃蛇AI可以工作了!!这个就有点哲学的味道了,看似在往远离目标的方向上行动,没有想到蛇刚好自己在绕了,绕掉了大部分的身体后,就可以用策略1找到路线了。


看了好几遍自己贪吃蛇AI的移动,不可避免的会有4.3提到的这个问题,后期留下太多洞了,贪吃蛇要追随自己尾巴,移动很久才能吃到一个苹果,我们知道有标题5 提到的无脑模式,我们在想,要不后期就不要以最短路线去吃苹果,而是无脑绕,来吃,这样反而会快些!


怎样才能产生无脑绕的效果呢?我们发现策略2中的条件2会产生这样的效果,在后期,我们就走离苹果最远的格子且这个格子能有到达尾巴的路线,我们发现这样走无意中就会产生这样的无脑绕效果!有点像圆。圆心就是目标,最终还算会不断地接近目标的!


这样算是贪吃蛇游戏的后期呢?我这里就简单如果蛇的长度等于整个游戏格子数量的一半,就算到后期了。


7.最终贪吃蛇AI效果图:



8.贪吃蛇AI在线试玩地址

用Cocos2d html5实现的。

http://www.waitingfy.com/html5/snake

http://www.waitingfy.com/archives/951

9.贪吃蛇snake html5 下载

http://www.waitingfy.com/?attachment_id=962

github: https://github.com/waitingfy/snake


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

贪吃蛇 AI 的实现 snake AI 的相关文章

  • golang之路--时间格式化

    有人问了问go的时间格式化问题 xff0c 于是乎自己尝试了下 xff0c 发现巨坑爹 xff0c 不按常理出牌啊 format的竟然模版必须如下面的每个数字 fuck t 61 time Unix 1362984425 0 nt 61 t
  • 生产者消费者模式C++程序模拟实现

    关于生产者和消费者的分析可以参考 xff1a http blog csdn net kenden23 article details 16340673 这里是利用C 43 43 简单模拟一个生产者消费者的工作模式 没有考虑到同步问题 操作了
  • Active MQ C++实现通讯

    Active MQ C 43 43 实现通讯 Kagula 2011 9 13 简介 在参考资料 2 的基础上介绍如何用C 43 43 调用Active MQ的客户端API 环境 xff1a 1 Windows XP SP3 2 Visua
  • OA工作流设计思路——请大神点评啊

    lt p gt OA工作流设计思路 请大神点评啊 xff0c 很多可能想的不是很到位 lt p gt lt p gt 此设计思路暂时没有包含详细的设计 xff0c 就是一个方向 xff0c 请大神指正下 xff0c 然方案更加完善 xff0
  • 解决Spring AOP 事务 配置 失效原因

    采用AOP配置声明式事务有5种方式 xff0c 下面只说关于采用TransactionInterceptor事务拦截器的方式 xff0c 配置程序如下 xff1a transactionManager xff1a lt bean id 61
  • 兼容chrome与firefox使用offsetWidth得到不同值的问题

    Ext3 x Ext MessageBox alert 在chrome与firefox显示的宽度不一致问题 究其原因是因为msgEl getWidth 得到的值不一致导致的 修正宽度应方法 xff1a chrome xff1a rect 6
  • 内嵌标志表达式

    对应的内嵌标志表达式是 i xff0c 它有四种形式 xff1a 1 xff0c i 2 xff0c i 3 xff0c i X 4 xff0c i X 不带有 的是开标志 xff0c 带有 的是关标志 把上面的代码改成这样 xff1a J
  • LoadRunner 90 Percent设置

    90 Percent 的设置 xff1a tools xff08 工具 xff09 options xff08 选项 xff09 General选项卡最下面有个Summary Report
  • 高通8155平台YOCTO CMAKE 编译问题解决方法

    硬件平台 xff1a 高通8155 软件平台 xff1a yocoto linux 43 ubuntu16 04 最近开始接触8155平台 xff0c 发现编译阶段出现cmake编译失败 xff0c 网上搜了一下没有相关的解决方案 xff0
  • 解决Ext.Grid单元格不能被选择

    ExtJs3 x版本 xff0c Ext grid GridPanel单元格数据不能被选择 xff0c 在不同浏览器环境下的解决方法不同 xff1a 1 Chrome Safari xff1a ext webkit x grid panel
  • Hadoop-1.2 单机部署

    准备相关资源环境 运行环境工具 Linux Centos 6 3 JDK 1 7 0 51 SSH Secure Shell 1 下载Hadoop1 2 http mirrors cnnic cn apache hadoop common
  • Hbase-0.94.19 单机部署

    准备相关环境 运行环境工具 Linux Centos 6 3 JDK 1 7 0 60 Hadoop 1 2 1 SSH Secure Shell Hbase需建立在Hadoop环境之上运行 xff0c 参考Hadoop1 2 1单机部署
  • Android Beam:引领未来的NFC数据交换

    还记得吗 xff1f 惠普曾经将TouchPad平板电脑与Pre 3接触就实现了网页交换 也许那时大家都在想 xff1a 太酷啦 xff0c 要是我有TouchPad和pre3就好了 昨天新发布的Android 4 0Ice Cream S
  • TabHost设置选项卡被选中时背景颜色

    TabHost设置选项卡被选中时背景颜色 xff0c 通过给每个选项卡的Button设置背景样式实现 文件名 xff1a bottom btn first bg billboard xml 内容如下 xff1a lt xml version
  • 如何从文件中检索关键字出现的次数

    首先得到文件的完整路径 然后从流中读取每个字符 如果读出的字符和关键字的第一个字符相同 xff0c 则按照关键字长度读取相同个数的字符 分别判断是否相同 xff0c 若有一个不相同则break 否则计数器count 43 43 xff0c
  • 被其他Activity覆盖不触发onStop的情况

    被其他Activity覆盖不触发onStop的情况 xff1a 一般情况下当一个Activity被其他Activity覆盖时 被覆盖的Activity都会调用onStop xff08 xff09 方法 但是有两种情况除外 一个是上层Acti
  • 如何找到一个数组中第三大数字并输出它所在的位置

    面试题 如何找到一个数组中第三大数字并输出它所在的位置 延伸问题 xff1a 如何找到一个数组中第N大元素并输出它所在的位置 br public class FindThirdLarge br public static void getT
  • 输出出一个数组中出现次数最多的数字以及它出现的次数

    查找一个数组中出现次数最多的数字以及它出现的次数并输出出来 br public class FindMostAppearTime br public static void getMostAppearNumber int array br

随机推荐

  • Activity的四种启动模式

    color 61 red Standard color 默认启动模式 标准模式 每次启动Activity都会创建新的Activity对象实例 color 61 red SingleInstance color 只要在当前应用中启动过该Act
  • 可装载内核模块-Loadable Kernel Module (LKM)

    0x01 可装载模块分类 设备驱动 文件系统 系统调用 0x02 版本检查 Linux 的迅速发展致使相邻版本的内核之间亦存在较大的差异 xff0c 即在版本补丁号 xff08 Patch Level xff0c 即内核版本号的第四位数 x
  • couldn't load font "宋体 9", falling back to "Sans 9", expect ugly output.

    Windows下使用Ruby GNOME2写GUI时 xff0c 会报以下错误 xff1a Pango WARNING couldn 39 t load font 34 宋体 9 34 falling back to 34 Sans 9 3
  • TCP/IP数据包结构详解

    关键词 TCP IP 数据包 结构 详解 网络 协议 一般来说 xff0c 网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作 xff0c 但是一些特殊的情况下 xff0c 就需要深入的理解 网络数据包的结构 xff0c 以
  • Ubuntu 网络配制方法(同事的blog,拿来备份.)

    etc network interfaces 打开后里面可设置DHCP或手动设置静态ip 前面auto eth0 xff0c 让网卡开机自动挂载 1 以DHCP方式配置网卡 编辑文件 etc network interfaces sudo
  • 内存池:简单的内存池的实现

    转载自 xff1a http blog sina com cn s blog 46ed82810100ch8h html 当频繁地用malloc申请内存 xff0c 然后再用free释放内存时 xff0c 会存在两个主要问题 第一个问题是频
  • 浅谈如何学习linux

    一 为什么要学linux 当然最重要是爱好和兴趣 xff01 如果你这种必要学 xff0c 或者根本不喜欢 xff0c 请不要浪费时间 xff0c 你学也学不好 xff01 二 起步 你应该为自己创造一个学习linux的环境 在电脑上装一个
  • 用PV操作 实现生产者-消费者问题(C++语言)

    作者 xff1a wwj 时间 xff1a 2012 4 12 功能 xff1a 实现生产者和消费者正常活动 题目内容 xff1a 生产者 消费者问题 xff0c 是指两组进程共享一个环形的缓冲区 一组进程被称为生产者 xff0c 另一组进
  • Java异常处理总结

    找到一个关于异常总结的很详细的文章 分享下 异常在我们编程中很重 xff0c 在适当的位置 xff0c 合理的处理或者抛出异常 xff0c 对程序来说至关重要 转 xff1a 异常处理是程序设计中一个非常重要的方面 xff0c 也是程序设计
  • HashMap,LinkedHashMap,TreeMap应用

    HashMap LinkedHashMap TreeMap应用简介 共同点 xff1a HashMap LinkedHashMap TreeMap都属于Map xff1b Map 主要用于存储键 key 值 value 对 xff0c 根据
  • 关于Java加密扩展的出口限制

    近日 xff0c 在Matrix Security版上 http www matrix org cn thread shtml topicId 61 39543 amp forumId 61 55 提出一个问题 xff0c 即他的程序不能正
  • win7 设置共享无线网络

    适用范围 xff1a 1 WIN7平台电脑 2 笔记本或带有WIFI模块的台式电脑 3 搜索不到win7新建的临时网络的M9 生成wifi网络属性 xff1a 1 WLAN是802 11g标准 2 带宽为54Mbps 开启windows 7
  • Installing newer GCC versions in Ubuntu

    Installing newer GCC versions in Ubuntu It is often useful to have installed never versions of the compiler in our syste
  • VirtualBox网络配置

    VirtualBox提供了三种联网方式 xff0c 在这里介绍前两种方式 xff08 NAT和HostInterface xff09 的配置方法 xff0c 第三种联网方式属于利用主机上的所有的虚拟机构建一个虚拟网络的方法 xff0c 较简
  • SSL/TLS安全:Schannel中WinShock漏洞及解决办法

    Schannel 是最新被发现存在 SSL TLS 安全问题的加密库 xff0c 在过去一年中 SSL TLS 协议出于各种错误的塬因占据着新闻头条 苹果的 SecureTransport OpenSSL GnuTLS 和 Mozilla
  • tomcat 报错:Error occurred during initialization of VM

    Error occurred during initialization of VM Unable to load native library Can 39 t find dependent libraries 这个是由于java的lib
  • oracle的declare声明语法

    declare cc integer begin pkg elevator ref sp elevator ref add i id 61 gt 351 i code 61 gt 39 Testregist 39 i asset 61 gt
  • 输入用户名和密码登入到服务器,却显示指定的网络密码不正确,输入了好几次都是这样,这是怎么回事? 用户名和密码没问题 ,一直用的好好地今天就不行了...

    指定的网络密码不正确 修改一下组策略就可以了 运行 组策略编辑器 gpedit msc 打开计算机配置 windows设置 安全设置 本地策略 安全选项中的 xff1a 网络安全 xff1a LAN管理器身份验证级别 xff0c 默认是 没
  • git创建仓库,并提交代码(第一次创建并提交)

    一直想学GIT xff0c 一直不曾学会 主要是GUI界面的很少 xff0c 命令行大多记不住 今天尝试提交代码 xff0c 按GIT上给的方法 xff0c 没料到既然提交成功了 于是把它记下来 xff0c 方便以后学习 代码是学习用的 x
  • 贪吃蛇 AI 的实现 snake AI

    1 首先看下这个非常在微博上很火的贪吃蛇gif 这次我们尝试用代码来模拟下 xff0c 说不定上面这个图就是计算机搞的 2 讲贪吃蛇AI之前 xff0c 我们先看下贪吃蛇移动的特点 物理上给人的感觉是整个贪吃蛇往右移了一步 xff0c 在贪