逖靖寒的世界

每天进步一点点

导航

启发式路径搜索: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(01), new Point(10), new Point(0-1), new Point(-10) };
 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算法的实现思想。
 
如果你对AStar算法不熟悉,参考一下的网址。适合初学者。
http://www.policyalmanac.org/games/aStarTutorial.htm
同时有中文翻译版:http://blog.csdn.net/johncools/archive/2006/03/13/623076.aspx

posted on 2007-12-31 08:47  逖靖寒  阅读(1084)  评论(4编辑  收藏  举报