7个寻路算法 Dijkstra.h

  1 #ifndef __DIJKSTRA__H
  2 #define __DIJKSTRA__H
  3 
  4 #include "AIDefine.h"
  5 #include <queue>
  6 
  7 class Dijkstra
  8 {
  9 private:
 10 #define MAXNUM 0x7FFFFFFF
 11 public:
 12     Dijkstra()
 13     {
 14         m_nodeArr = NULL;
 15         m_able = false;
 16     }
 17     ~Dijkstra()
 18     {
 19         if(NULL != m_nodeArr)
 20         {
 21             delete[] m_nodeArr;
 22             m_nodeArr = NULL;
 23         }
 24     }
 25     static bool find(const PointI &size, const PointI &start, const PointI &end, AI_VisitFun visitFun, Path **path = NULL,
 26         EFindType findType = EFIND_TYPE8, AI_DitanceFun fun = AI_Ditance1)
 27     {
 28         Dijkstra dijkstra;
 29         if(dijkstra.init(size, end, visitFun, findType, fun))
 30         {
 31             return dijkstra.findPath(start, path);
 32         }
 33         if(NULL != path){*path = new Path(false, 0.0f);}
 34         return false;
 35     }
 36     bool init(const PointI &size, const PointI &end, AI_VisitFun visitFun, EFindType findType = EFIND_TYPE8, AI_DitanceFun fun = AI_Ditance1)
 37     {
 38         if(size.x <= 0 || size.y <= 0 || end.x < 0 || end.y < 0 || end.x >= size.x || end.y >= size.y)
 39         {
 40             m_able = false;
 41             return false;
 42         }
 43         m_able = true;
 44         m_size.x = size.x; m_size.y = size.y;
 45         m_end.x = end.x; m_end.y = end.y;
 46         if(NULL != m_nodeArr){delete m_nodeArr; m_nodeArr = NULL;}
 47         m_nodeArr = new Info[size.x * size.y];
 48         Info *cur, *next;
 49         PointI pos;
 50         int i;
 51         PriorityQueue<Info*, InfoCmp> visit;
 52         //std::priority_queue<Info*, std::vector<Info*>, InfoCmp> visit;
 53         for(i = 0; i < findType; ++i)
 54         {
 55             pos.x = end.x + AI_FindHelpPoint[i].x;pos.y = end.y + AI_FindHelpPoint[i].y;
 56             if(pos.x >= 0 && pos.x <size.x && pos.y >= 0 && pos.y < size.y && AI_CheckPass(end.x, end.y, pos.x, pos.y, visitFun))
 57             {
 58                 cur = &m_nodeArr[pos.y * size.x + pos.x];
 59                 cur->x = pos.x; cur->y = pos.y;
 60                 cur->dis = fun(end.x, end.y, cur->x, cur->y);
 61                 cur->path.x = end.x; cur->path.y = end.y; cur->hasPath = true;
 62                 visit.push(cur);
 63             }
 64         }
 65         cur = &m_nodeArr[end.y * size.x + end.x];
 66         cur->dis = 0; cur->visited = true;
 67         cur->path.x = end.x; cur->path.y = end.y; cur->hasPath = true;
 68         cur->x = end.x; cur->y = end.y;
 69 
 70         float cost;
 71         while(!visit.empty())
 72         {
 73             cur = visit.top();visit.pop();
 74             cur->visited = true;
 75             for(i = 0; i < findType; ++i)
 76             {
 77                 pos.x = cur->x + AI_FindHelpPoint[i].x;pos.y = cur->y + AI_FindHelpPoint[i].y;
 78                 if(pos.x >= 0 && pos.x <size.x && pos.y >= 0 && pos.y < size.y)
 79                 {
 80                     next = &m_nodeArr[pos.y * size.x + pos.x];
 81                     next->x = pos.x; next->y = pos.y;
 82                     cost = fun(cur->x, cur->y, next->x, next->y);
 83                     if(!next->visited && AI_CheckPass(cur->x, cur->y, next->x, next->y, visitFun) && cur->dis + cost < next->dis)
 84                     {
 85                         next->dis = cur->dis + cost;
 86                         next->path.x = cur->x; next->path.y = cur->y; next->hasPath = true;
 87                         visit.push(next);
 88                     }
 89                 }
 90             }
 91         }
 92         return true;
 93     }
 94     bool getDis(const PointI &start, float &dis)
 95     {
 96         dis = 0;
 97         if(m_able)
 98         {
 99             if(start.x == m_end.x && start.y == m_end.y)
100             {
101                 return true;
102             }
103             if(start.x < 0 || start.x >= m_size.x || start.y < 0 || start.y >= m_size.y)
104             {
105                 return false;
106             }
107             dis = m_nodeArr[start.y * m_size.x + start.x].dis;
108             return true;
109         }
110         return false;
111     }
112     bool findPath(const PointI &start, Path **path = NULL, bool isStart = true)
113     {
114         bool result = false;
115         if(m_able)
116         {
117             Path *_path = new Path(true, 0.0f);
118             if(start.x == m_end.x && start.y == m_end.y)
119             {
120                 if(NULL != path){*path = _path;}else{delete _path;}
121                 return true;
122             }
123             Info *cur;
124             _path->push_front(PointI(start.x, start.y));
125             cur = &m_nodeArr[start.y * m_size.x + start.x];
126             _path->setDis(cur->dis);
127             while(cur->hasPath)
128             {
129                 if(cur->path.x == m_end.x && cur->path.y == m_end.y)
130                 {
131                     result = true;
132                     break;
133                 }
134                 if(isStart){_path->push_back(PointI(cur->path.x, cur->path.y));}
135                 else{_path->push_front(PointI(cur->path.x, cur->path.y));}
136                 cur = &m_nodeArr[cur->path.y * m_size.x + cur->path.x];
137             }
138             if(!result){delete _path; _path = new Path(false, MAXNUM);}
139             else
140             {
141                 if(isStart){_path->push_back(PointI(m_end.x, m_end.y));}
142                 else{_path->push_front(PointI(m_end.x, m_end.y));}
143             }
144             if(NULL != path){*path = _path;}else{delete _path;}
145         }
146         return result;
147     }
148 private:
149     struct Info
150     {
151         Info():dis(MAXNUM),visited(false), hasPath(false){}
152         int x, y;
153         PointI path;
154         float dis;
155         bool visited;
156         bool hasPath;
157     };
158     struct InfoCmp
159     {
160         bool operator () (const Info *p1, const Info *p2)
161         {
162             return p1->dis < p2->dis;
163         }
164     };
165 private:
166     Info     *m_nodeArr;
167     PointI    m_size;
168     PointI    m_end;
169     bool     m_able;
170 };
171 
172 #endif

 

posted @ 2013-11-23 01:37  liusijian  阅读(686)  评论(0编辑  收藏  举报