1 #ifndef __BFS__H
2 #define __BFS__H
3
4 #include "AIDefine.h"
5 #include <queue>
6
7 class BFS
8 {
9 private:
10 BFS();
11 public:
12 static bool find(const PointI &size, const PointI &start, const PointI &end, AI_VisitFun visitFun, Path **path = NULL,
13 EFindType findType = EFIND_TYPE8, AI_DitanceFun fun = AI_Ditance1)
14 {
15 if(size.x <= 0 || size.y <= 0 || start.x < 0 || start.y < 0 || end.x < 0 || end.y < 0 ||
16 start.x >= size.x || start.y >= size.y || end.x >= size.x || end.y >= size.y ||
17 !visitFun(start.x, start.y), !visitFun(end.x, end.y))
18 {
19 if(NULL != path){*path = new Path(false, 0.0f);}
20 return false;
21 }
22 if(start.x == end.x && start.y == end.y)
23 {
24 if(NULL != path){*path = new Path(true, 0.0f);}
25 return true;
26 }
27
28 std::priority_queue<Info*, std::vector<Info*>, InfoCmp> visit;
29 Info *nodeArr = new Info[size.x * size.y];
30 Info *cur, *next;
31 PointI pos;
32
33 cur = &nodeArr[size.x * start.y + start.x];
34 cur->x = start.x; cur->y = start.y; cur->visited = true; cur->f = 0;
35 visit.push(cur);
36
37 while(!visit.empty())
38 {
39 cur = visit.top();
40 visit.pop();
41 if(cur->x == end.x && cur->y == end.y)
42 {
43 if(NULL != path)
44 {
45 *path = new Path(true, cur->f);
46 while (NULL != cur)
47 {
48 (*path)->push_front(PointI(cur->x, cur->y));
49 cur = cur->parent;
50 }
51 }
52 if(NULL != nodeArr){delete[] nodeArr;}
53 return true;
54 }
55 for(int i = 0; i < findType; ++i)
56 {
57 pos.x = cur->x + AI_FindHelpPoint[i].x; pos.y = cur->y + AI_FindHelpPoint[i].y;
58 if(pos.x >= 0 && pos.y >= 0 && pos.x < size.x && pos.y < size.y
59 && !nodeArr[size.x * pos.y + pos.x].visited && AI_CheckPass(cur->x, cur->y, pos.x, pos.y, visitFun))
60 {
61 next = &nodeArr[size.x * pos.y + pos.x];
62 next->visited = true; next->x = pos.x; next->y = pos.y;
63 next->f = cur->f + fun(cur->x, cur->y, next->x, next->y);
64 next->parent = cur;
65 visit.push(next);
66 }
67 }
68 }
69
70 if(NULL != nodeArr){delete[] nodeArr;}
71 return false;
72 }
73 private:
74 struct Info
75 {
76 Info():visited(false),x(0),y(0),f(0.0f),parent(NULL){}
77 bool visited;
78 int x,y;
79 float f;
80 Info *parent;
81 };
82 struct InfoCmp
83 {
84 bool operator () (const Info *p1, const Info *p2)
85 {
86 return p1->f > p2->f;
87 }
88 };
89 };
90
91 #endif