启发式路径搜索:A*
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Drawing;
5
using System.Collections;
6
using Zephyr.WorldModel;
7
using Zephyr.DebugTools;
8
9
namespace Zephyr.Utility
10
{
11
public class ZPathFinder
12
{
13
private static ZPathFinder _pathFinder = null;
14
15
private BinaryHeap _opens = new BinaryHeap();
16
private List<ZPFCell> _closeLists = new List<ZPFCell>();
17
18
private static Point[] moves = new Point[] { new Point(0, 1), new Point(1, 0), new Point(0, -1), new Point(-1, 0) };
19
20
public static ZPathFinder Instance
21
{
22
get
23
{
24
if (_pathFinder == null)
25
{
26
_pathFinder = new ZPathFinder();
27
}
28
29
return _pathFinder;
30
}
31
}
32
33
private void reset()
34
{
35
_opens.Clear();
36
_closeLists.Clear();
37
}
38
39
//用二叉堆来实现,提高查找效率
40
private ZPFCell getMinCostZPFCell()
41
{
42
ZPFCell zpfc = _opens.DelMin();
43
44
_closeLists.Add(zpfc);
45
46
return zpfc;
47
}
48
49
public Stack<Point> FindPath(Point origin, Point destination)
50
{
51
//无需移动。
52
if (origin == destination)
53
{
54
ZLogger.Instance.LogError("FindPath find origin = destination");
55
return new Stack<Point>();
56
}
57
//如果目标点是不可达到的。
58
if (ZWorldModel.Instance.Terrain.GetZCell(destination) == null)
59
{
60
ZLogger.Instance.LogError("FindPath can't find path to an unreachable point");
61
return new Stack<Point>();
62
}
63
64
reset();
65
66
ZCell s = ZWorldModel.Instance.Terrain[origin.X, origin.Y];
67
68
//起点
69
ZPFCell oZPFCell = new ZPFCell(ZWorldModel.Instance.Terrain.GetZCell(origin));
70
71
_opens.Add(oZPFCell);
72
73
//终点
74
ZPFCell dZPFCell = null;
75
76
//开始搜索
77
while (_opens.Count > 0)
78
{
79
//得到未探测路径中成本最小的点
80
ZPFCell minCostzpfc = getMinCostZPFCell();
81
82
//找到了目标点。
83
if (minCostzpfc.ZCell.Location == destination)
84
{
85
dZPFCell = minCostzpfc;
86
break;
87
}
88
89
//将成本最小点周围的点添加到未探测路径中去
90
//同时计算成本。
91
foreach (Point movePoint in moves)
92
{
93
Point searchPoint = new Point(minCostzpfc.ZCell.Location.X + movePoint.X,
94
minCostzpfc.ZCell.Location.Y + movePoint.Y);
95
96
ZCell searchZCell = ZWorldModel.Instance.Terrain.GetZCell(searchPoint);
97
98
//这个点是地图上的有效的,并且不在OpenList和CloseList中。
99
if (searchZCell != null && !openListContain(searchPoint) && !closeListContain(searchPoint))
100
{
101
ZPFCell newZPFCell = new ZPFCell(searchZCell);
102
newZPFCell.Pre = minCostzpfc;
103
104
newZPFCell.CostPath = minCostzpfc.CostPath + (int)newZPFCell.ZCell.AreaType;
105
newZPFCell.Cost = newZPFCell.CostPath + heuristic(newZPFCell.ZCell.Location, destination);
106
107
_opens.Add(newZPFCell);
108
}
109
}
110
}
111
112
//返回结果。
113
if (dZPFCell != null)
114
{
115
return dZPFCell.Path;
116
}
117
else
118
{
119
ZLogger.Instance.LogError("PathFinder can't find the way from " + origin + " to " + destination);
120
return new Stack<Point>();
121
}
122
}
123
124
private int heuristic(Point from, Point to)
125
{
126
return ZUtils.GetManhattanDis(from, to);
127
}
128
129
private bool openListContain(Point p)
130
{
131
int len = _opens.Count;
132
133
for (int index = 0; index < len; index++)
134
{
135
if (_opens[index].ZCell.Location == p)
136
{
137
return true;
138
}
139
}
140
141
return false;
142
}
143
144
private bool closeListContain(Point p)
145
{
146
foreach (ZPFCell zpfc in _closeLists)
147
{
148
if (zpfc.ZCell.Location == p)
149
{
150
return true;
151
}
152
}
153
154
return false;
155
}
156
157
158
}
159
}
160
这并不是完整的代码,但是通过看以上代码足以了解AStar算法的实现思想。
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Drawing;5
using System.Collections;6
using Zephyr.WorldModel;7
using Zephyr.DebugTools;8

9
namespace Zephyr.Utility10
{11
public class ZPathFinder12
{13
private static ZPathFinder _pathFinder = null;14

15
private BinaryHeap _opens = new BinaryHeap();16
private List<ZPFCell> _closeLists = new List<ZPFCell>();17

18
private static Point[] moves = new Point[] { new Point(0, 1), new Point(1, 0), new Point(0, -1), new Point(-1, 0) };19

20
public static ZPathFinder Instance21
{22
get23
{24
if (_pathFinder == null)25
{26
_pathFinder = new ZPathFinder();27
}28

29
return _pathFinder;30
}31
}32

33
private void reset()34
{35
_opens.Clear();36
_closeLists.Clear();37
}38

39
//用二叉堆来实现,提高查找效率40
private ZPFCell getMinCostZPFCell()41
{42
ZPFCell zpfc = _opens.DelMin();43

44
_closeLists.Add(zpfc);45

46
return zpfc;47
}48

49
public Stack<Point> FindPath(Point origin, Point destination)50
{51
//无需移动。52
if (origin == destination)53
{54
ZLogger.Instance.LogError("FindPath find origin = destination");55
return new Stack<Point>();56
}57
//如果目标点是不可达到的。58
if (ZWorldModel.Instance.Terrain.GetZCell(destination) == null)59
{60
ZLogger.Instance.LogError("FindPath can't find path to an unreachable point");61
return new Stack<Point>();62
}63

64
reset();65

66
ZCell s = ZWorldModel.Instance.Terrain[origin.X, origin.Y];67

68
//起点69
ZPFCell oZPFCell = new ZPFCell(ZWorldModel.Instance.Terrain.GetZCell(origin));70

71
_opens.Add(oZPFCell);72

73
//终点74
ZPFCell dZPFCell = null;75

76
//开始搜索77
while (_opens.Count > 0)78
{79
//得到未探测路径中成本最小的点80
ZPFCell minCostzpfc = getMinCostZPFCell();81

82
//找到了目标点。83
if (minCostzpfc.ZCell.Location == destination)84
{85
dZPFCell = minCostzpfc;86
break;87
}88

89
//将成本最小点周围的点添加到未探测路径中去90
//同时计算成本。91
foreach (Point movePoint in moves)92
{93
Point searchPoint = new Point(minCostzpfc.ZCell.Location.X + movePoint.X,94
minCostzpfc.ZCell.Location.Y + movePoint.Y);95

96
ZCell searchZCell = ZWorldModel.Instance.Terrain.GetZCell(searchPoint);97

98
//这个点是地图上的有效的,并且不在OpenList和CloseList中。99
if (searchZCell != null && !openListContain(searchPoint) && !closeListContain(searchPoint))100
{101
ZPFCell newZPFCell = new ZPFCell(searchZCell);102
newZPFCell.Pre = minCostzpfc;103

104
newZPFCell.CostPath = minCostzpfc.CostPath + (int)newZPFCell.ZCell.AreaType;105
newZPFCell.Cost = newZPFCell.CostPath + heuristic(newZPFCell.ZCell.Location, destination);106

107
_opens.Add(newZPFCell);108
}109
}110
}111

112
//返回结果。113
if (dZPFCell != null)114
{115
return dZPFCell.Path;116
}117
else118
{119
ZLogger.Instance.LogError("PathFinder can't find the way from " + origin + " to " + destination);120
return new Stack<Point>();121
}122
}123

124
private int heuristic(Point from, Point to)125
{126
return ZUtils.GetManhattanDis(from, to);127
}128

129
private bool openListContain(Point p)130
{131
int len = _opens.Count;132

133
for (int index = 0; index < len; index++)134
{135
if (_opens[index].ZCell.Location == p)136
{137
return true;138
}139
}140

141
return false;142
}143

144
private bool closeListContain(Point p)145
{146
foreach (ZPFCell zpfc in _closeLists)147
{148
if (zpfc.ZCell.Location == p)149
{150
return true;151
}152
}153

154
return false;155
}156

157

158
}159
}160

如果你对AStar算法不熟悉,参考一下的网址。适合初学者。
http://www.policyalmanac.org/games/aStarTutorial.htm
同时有中文翻译版:http://blog.csdn.net/johncools/archive/2006/03/13/623076.aspx


浙公网安备 33010602011771号