哈密顿环解决贪吃蛇问题

思路来源于GitHub上一个项目:
snake
  先给出哈密顿回路的定义:哈密顿图(哈密尔顿图)(英语:Hamiltonian graph,或Traceable graph)是一个无向图,由天文学家哈密顿提出,由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次。在图论中是指含有哈密顿回路的图,闭合的哈密顿路径称作哈密顿回路(Hamiltonian cycle),含有图中所有顶点的路径称作哈密顿路径(Hamiltonian path)。
  首先很容易理解,如果我们希望贪吃蛇能从很小成长到填满整个屏幕,那么一定要吃掉所有出现的食物并避免蛇头撞击到蛇身。有一种最稳妥的运行策略是:将整个屏幕网格化,每一个像素点为一个点,整个屏幕抽象为一个图,显然这个图存在哈密顿路径。将哈密顿路径上的点按次序编号,设蛇头开始处为0,编号依次增加。则蛇头只需一直沿着哈密顿路径走就能访问到图中所有点,必定可以吃到食物,而且不会追尾。
  然而这种策略显然是冗长且乏味的,所以我们思考如何节约蛇行走的路程。仍然利用上文按次序编号的设置,我们同样容易了解,如果蛇不想完全按哈密顿路径行走,那么只要它下一个落脚点的编号在本该落脚的点的编号之后即可,这样至少我们可以保证改变落脚点后,继续沿着既定的哈密顿路径行走,蛇头能平安回到0点,进行下一轮哈密顿路径的轮回。
  于是我们可以采用一个不一定最优但稍有改进的策略:蛇头依然依赖哈密顿路径,但当它发现下一个食物点的编号在蛇头编号之后(两点在当前同一哈密顿路径内),且蛇头只需变更一次方向即可直达食物点,那么便不沿着原哈密顿路径,而是选择变向直达。之后如果再下一个食物点还在蛇头后则伺机抄近路,没有近路则从蛇头当前点继续按照哈密顿路径行走。
  至于如何实现这种策略的更细致的表述,由于我只是读了很久原作者的思路,然后自己在脑子里一直模拟,并没有自己实现,所以当然没有啦。不过初步想法是将整个哈密顿图构造好后,就可以知道每个点上下左右是哪四个点。创建一个一维数组,每个数组元素是一个类对象,这个类有四个公有int数据成员,保存其上下左右的点编号;还有一个公有bool数据成员,表示该点是否被蛇的身躯覆盖。这样选择抄近路时,就可以考虑四个方向的点,如果某个点在当前蛇头和食物点之间,那么变更到这个点。
  可以看到这个策略和再之前文字表述的有些不同,当然啦,当我从编程角度考虑策略时往往和最初的思路有出入,而这种可落实的思路最后才能解决问题。
  找时间搞一下这个程序吧。

发布了6 篇原创文章 · 获赞 0 · 访问量 46

猜你喜欢

转载自blog.csdn.net/qq_18839043/article/details/105260269