本系列博文最终将实现一个MFC版的“智能寻路贪吃蛇”。
前面的三篇博文我们已经实现了一个基于单一的BFS算法的智能贪吃蛇.
美中不足的是,这条蛇虽然能够欢快的跑一段时间,但是因为吃食物的过程中不顾后果,导致蛇跑不了多久就挂掉了.
这篇博文,我们就来解决这个问题.
上篇中说道当前算法中存在的不足之处:
0.由于每次都是吃到食物之后才执行一下Bfs函数,所以,得到的路径就是那一瞬间的最短路径,但是可能在蛇移动的过程中,当前的格局发生了变化,可能会有更短的路径出现,虽然这个问题不是致命的,但是也浪费了蛇吃东西的时间.
1.随着蛇身的增长,蛇的身体很可能将地图分为互不相通的几个部分,所以,当食物和蛇的头部出现在不同的部分时,Bfs算法就没辙了,这个问题是致命的!
那么如何解决这个问题呢?
其实说来也很简单,原来的策略是每次吃完食物后,就使用BFS算法重新计算一遍路径.
其实这样计算出来的路径是过时的,蛇每移动一步,当前的格局都会发生变化,如果还是按照老路走,就很有可能绕了远路.
所以只要换一下策略,每走一步,就做一次BFS,实时更新路径,前面的问题就不复存在了.
这个的改动是非常小的,只要简单的改变一下函数的执行位置即可,不多说.
经过我的测试,这样改动之后的蛇的确走的路径每次都是最短的,而且存活的时间也更长了,只是执行寻路算法的次数大大增加,时间复杂度也更大了.
虽然这样解决了一定的问题,但是最根本的还是没有解决(看图)
当蛇头和食物不在一个次元的时候,蛇就会一头撞死.
而这种情况是经常发生的,尤其是蛇身比较长之后..
那么如何解决这个问题呢?
蛇是因为吃了某块食物之后才使自己陷入困境的,我们要做的就是避免蛇陷入这种困境.
这就需要每次在走位之前,都要判断一下当前的路径是否是安全的.
如何判断路径是否安全呢?
在第一篇博文中引用的Hawstein大神的文章中提到,只要蛇头和蛇尾之间存在路径,则认为当前的路径是安全的~
所以,如果是安全的,那么蛇就安安心心的去吃食物,如果不安全怎么办呢?
我们再来看一眼第一篇博文中那只销魂的蛇~
仔细观察就会发现,当这只蛇陷入困境时(路径不安全),就一直在空白的地方"遛弯",知道新的路径出现为止.
而且,遛弯的时候蛇走位的规律性也是极强的.
就是朝着尾巴所在的那一端不断地做S运动
搞清楚了基本的方法,就可以开始编写代码了..
代码的主要更新之处就是写了一个IsSafe()函数来判定当前状态是否安全,如果不安全,就按照一个特定的方法走几步,这个方法的缺点就是有的时候随便走几步结果却把自己走到了更危险的处境上.
虽然整体的算法比刚开始有了很大的改进,但是最终的效果还是达不到上面的图片那样把整个地图填满,主要原因是我想不通怎么来追着蛇尾跑~如果您有好的方法,望不吝赐教 !
这个版本的源代码我已经上传到CSDN了,有兴趣的可以下载看一下~
程序使用VS2012编写,低版本的VS可以自行修改sln文件中的版本信息,具体方法请百度.