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