一、实验要求
实验内容:
1)迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫;
2) 要求查找并理解迷宫生成的算法,并尝试用两种不同的算法来生成随机的迷宫。
3)要求迷宫游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹;系统提示迷宫路径要求基于A*算法实现,输出玩家当前位置到迷宫出口的最优路径。设计交互友好的游戏图形界面。
二、实验过程
A*算法
要求:
1、迷宫随机生成
2、玩家走迷宫,留下足迹;
3、系统用A*算法寻路,输出路径
解决问题: 1、如何显示迷宫的图形界面; 2、如何生成随机的迷宫; 3、怎样移动游戏中走迷宫的“玩家”; 4、用A*算法求解迷宫;
A* (A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是许多其他问题的常用启发式算法。
公式表示为: f*(n)=g*(n)+h*(n),
其中, f*(n) 是从初始状态经由状态n到目标状态的最小代价估计,
h*(n) 是从状态n到目标状态的路径的最小估计代价。
(对于路径搜索问题,状态就是图中的节点,代价就是距离)
真实h(n)的选取:
保证找到最短路径(最优解的)条件,关键在于估价函数f(n)的选取(或者说h(n)的选取)。
以h(n)表达状态n到目标状态估计的距离,那么h(n)的选取大致有如下三种情况:
-
如果h(n)< h*(n),这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。
-
如果h(n)=h*(n),此时的搜索效率是最高的。
如何生成随机的迷宫
深度优先遍历算法
1.从第一个单元开始,检查当前单元是否堵塞(即周围四个单元都是已被访问或不可访问)
2.若不堵塞,则随机选择一个相邻单元作为下一单元,检查是否可访问
3.若可访问,则打破当前单元与下一单元之间的墙壁,将当前单元入栈,将下一单元作为当前单元;若不不可访问,则回到步骤2
4.若当前单元堵塞,则回退至上一单元
5.如此遍历,直到所有的单元都被访问
随机普利姆算法
1.使迷宫全是墙,即每个单元之间无法连通
2.随机选一个单元格作为迷宫的通路,然后把它的邻墙放入列表
3.当列表里还有墙时:
从列表里随机选一个墙,如果这面墙分隔的两个单元只有一个单元被访问过:那就从列表里移除这面墙,即把墙打通,让未访问的单元成为迷宫的通路把这个单元的墙加入列表;
4.如果墙两面的单元都已经被访问过,那就从列表里移除这面墙
如此遍历,直到列表没有墙
相对于深度优先的算法,Randomized Prim’s Algorithm不是优先选择最近选中的单元格,而是随机的从所有的列表中的单元格进行选择,新加入的单元格和旧加入的单元格同样概率会被选择,新加入的单元格没有优先权。因此其分支更多,生成的迷宫更复杂,岔路更多,难度更大,也更自然。
迷宫寻路算法
(1)广度优先搜索算法
从图的某一结点出发,首先依次访问该结点的所有邻接结Vi1,Vi2,Vi3,……Vin,再按这些顶点被访问的先后次序依次访问与它们相邻接的所有未被访问的顶点,最后重复此过程,直至所有顶点均被访问位置。
(2)dijkstra(迪杰斯特拉)算法
1、把V分成两组:
1)S:已求出最短路径的顶点的集合。
2)T=V-S:尚未确定最短路径的顶点集合。
2、将T中顶点按最短路径递增的次序加入到S中。
(3)Greed-Best-First(最好优先贪婪算法)
起始节点记作S,目标节点记作E,对于任意节点G,从当前节点G到目标节点E的曼哈顿距离记作MG,优先队列openList中数据为(G,MG)(节点,当前节点到目标节点E的曼哈顿距离)。
1.将起始节点S放入openList,openList是一个优先队列,曼哈顿距离越小的节点,优先级越高。
2.判断openList是否为空,如果为空&