7个寻路算法 BStar.h

  1 #ifndef __BSTAR__H
  2 #define __BSTAR__H
  3 
  4 #include "AIDefine.h"
  5 #include <vector>
  6 
  7 class BStar
  8 {
  9 private:
 10     BStar();
 11 public:
 12     static bool find(const PointI &size, const PointI &start, const PointI &end, AI_VisitFun visitFun, Path **path = NULL)
 13     {
 14         if(size.x <= 0 || size.y <= 0 || start.x < 0 || start.y < 0 || end.x < 0 || end.y < 0 ||
 15             start.x >= size.x || start.y >= size.y || end.x >= size.x || end.y >= size.y ||
 16             !visitFun(start.x, start.y), !visitFun(end.x, end.y))
 17         {
 18             if(NULL != path){*path = new Path(false, 0.0f);}
 19             return false;
 20         }
 21         if(start.x == end.x && start.y == end.y)
 22         {
 23             if(NULL != path){*path = new Path(true, 0.0f);}
 24             return true;
 25         }
 26 
 27         EDIRTYPE curDir = DIR_LEFT, nextDir = DIR_NONE;
 28         if(AI_ABS(end.x - start.x) >= AI_ABS(end.y - start.y))
 29         {
 30             if(end.x > start.x){curDir = DIR_RIGHT;}
 31             else{curDir = DIR_LEFT;}
 32         }else
 33         {
 34             if(end.y > start.y){curDir = DIR_DOWN;}
 35             else{curDir = DIR_UP;}
 36         }
 37 
 38         std::vector<Info*> visit;
 39         std::vector<Info*>::iterator iter;
 40         Info *nodeArr = new Info[size.x * size.y];
 41         Info *cur, *next;
 42         PointI pos;
 43 
 44         cur = &nodeArr[size.x * start.y + start.x];
 45         cur->x = start.x; cur->y = start.y; cur->visited = true;cur->dir = curDir;
 46         visit.push_back(cur);
 47 
 48         while(!visit.empty())
 49         {
 50             iter = visit.end(); --iter; cur = *iter;curDir = cur->dir;
 51             if(cur->x == end.x && cur->y == end.y)
 52             {
 53                 if(NULL != path)
 54                 {
 55                     *path = new Path(true, 0.0f);
 56                     for(iter = visit.begin(); iter != visit.end(); ++iter)
 57                     {
 58                         (*path)->push_back(PointI((*iter)->x, (*iter)->y));
 59                     }
 60                 }
 61                 if(NULL != nodeArr){delete[] nodeArr;}
 62                 return true;
 63             }
 64             if(DIR_LEFT == curDir){pos.x = cur->x - 1;pos.y = cur->y;}
 65             else if(DIR_RIGHT == curDir){pos.x = cur->x + 1;pos.y = cur->y;}
 66             else if(DIR_DOWN == curDir){pos.x = cur->x;pos.y = cur->y + 1;}
 67             else if(DIR_UP == curDir){pos.x = cur->x;pos.y = cur->y - 1;}
 68             if(AI_CheckRange(pos,size) && !nodeArr[size.x * pos.y + pos.x].visited && visitFun(pos.x, pos.y))
 69             {
 70                 next = &nodeArr[size.x * pos.y + pos.x];
 71                 next->x = pos.x; next->y = pos.y; next->visited = true;next->dir = curDir;
 72                 visit.push_back(next);
 73                 if(DIR_LEFT == curDir || DIR_RIGHT == curDir)
 74                 {
 75                     if(next->x == end.x)
 76                     {
 77                         if(end.y >= cur->y)
 78                         {
 79                             pos.x = cur->x; pos.y = cur->y + 1;
 80                             if(AI_CheckRange(pos,size) && !nodeArr[size.x * pos.y + pos.x].visited && visitFun(pos.x, pos.y))
 81                             {
 82                                 next->dir = curDir = DIR_DOWN;
 83                             }
 84                         }else
 85                         {
 86                             pos.x = cur->x; pos.y = cur->y - 1;
 87                             if(AI_CheckRange(pos,size) && !nodeArr[size.x * pos.y + pos.x].visited && visitFun(pos.x, pos.y))
 88                             {
 89                                 next->dir = curDir = DIR_UP;
 90                             }
 91                         }
 92                     }
 93                 }else if(DIR_DOWN == curDir || DIR_UP == curDir)
 94                 {
 95                     if(next->y == end.y)
 96                     {
 97                         if(end.x >= cur->x)
 98                         {
 99                             pos.x = cur->x + 1; pos.y = cur->y;
100                             if(AI_CheckRange(pos,size) && !nodeArr[size.x * pos.y + pos.x].visited && visitFun(pos.x, pos.y))
101                             {
102                                 next->dir = curDir = DIR_RIGHT;
103                             }
104                         }else
105                         {
106                             pos.x = cur->x - 1; pos.y = cur->y;
107                             if(AI_CheckRange(pos,size) && !nodeArr[size.x * pos.y + pos.x].visited && visitFun(pos.x, pos.y))
108                             {
109                                 next->dir = curDir = DIR_LEFT;
110                             }
111                         }
112                     }
113                 }
114             }else
115             {
116                 if(DIR_LEFT == curDir || DIR_RIGHT == curDir)
117                 {
118                     if(end.y >= cur->y)
119                     {
120                         pos.x = cur->x; pos.y = cur->y + 1;nextDir = DIR_DOWN;
121                         if(!AI_CheckRange(pos,size) || nodeArr[size.x * pos.y + pos.x].visited || !visitFun(pos.x, pos.y))
122                         {
123                             pos.x = cur->x; pos.y = cur->y - 1;nextDir = DIR_UP;
124                         }
125                     }else
126                     {
127                         pos.x = cur->x; pos.y = cur->y - 1;nextDir = DIR_UP;
128                         if(!AI_CheckRange(pos,size) || nodeArr[size.x * pos.y + pos.x].visited || !visitFun(pos.x, pos.y))
129                         {
130                             pos.x = cur->x; pos.y = cur->y + 1;nextDir = DIR_DOWN;
131                         }
132                     }
133                 }else if(DIR_DOWN == curDir || DIR_UP == curDir)
134                 {
135                     if(end.x >= cur->x)
136                     {
137                         pos.x = cur->x + 1; pos.y = cur->y;nextDir = DIR_RIGHT;
138                         if(!AI_CheckRange(pos,size) || nodeArr[size.x * pos.y + pos.x].visited || !visitFun(pos.x, pos.y))
139                         {
140                             pos.x = cur->x - 1; pos.y = cur->y;nextDir = DIR_LEFT;
141                         }
142                     }else
143                     {
144                         pos.x = cur->x - 1; pos.y = cur->y;nextDir = DIR_LEFT;
145                         if(!AI_CheckRange(pos,size) || nodeArr[size.x * pos.y + pos.x].visited || !visitFun(pos.x, pos.y))
146                         {
147                             pos.x = cur->x + 1; pos.y = cur->y;nextDir = DIR_RIGHT;
148                         }
149                     }
150                 }
151                 if(!AI_CheckRange(pos,size) || nodeArr[size.x * pos.y + pos.x].visited || !visitFun(pos.x, pos.y))
152                 {
153                     visit.pop_back();
154                 }else
155                 {
156                     next = &nodeArr[size.x * pos.y + pos.x];
157                     next->x = pos.x; next->y = pos.y; next->visited = true;next->dir = nextDir;
158                     visit.push_back(next);
159                 }
160             }
161         }
162         if(NULL != path){*path = new Path(false, 0.0f);}
163         if(NULL != nodeArr){delete[] nodeArr;}
164         return false;
165     }
166 private:
167     enum EDIRTYPE
168     {
169         DIR_NONE,
170         DIR_LEFT,
171         DIR_RIGHT,
172         DIR_UP,
173         DIR_DOWN
174     };
175     struct Info
176     {
177         Info():visited(false),x(0),y(0),dir(DIR_NONE){}
178         bool visited;
179         int x,y;
180         EDIRTYPE dir;
181     };
182 };
183 
184 #endif

 

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