启发式路径搜索:A*
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Drawing;
5using System.Collections;
6using Zephyr.WorldModel;
7using Zephyr.DebugTools;
8
9namespace 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算法的实现思想。2using System.Collections.Generic;
3using System.Text;
4using System.Drawing;
5using System.Collections;
6using Zephyr.WorldModel;
7using Zephyr.DebugTools;
8
9namespace 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算法不熟悉,参考一下的网址。适合初学者。
http://www.policyalmanac.org/games/aStarTutorial.htm
同时有中文翻译版:http://blog.csdn.net/johncools/archive/2006/03/13/623076.aspx