@@ -107,13 +107,14 @@ namespace alg {
107107as->path = NULL ;
108108as->num_nodes = 0 ;
109109
110+ // the main A*algorithm
110111while (!m_openset.is_empty ()) {
111112uint32_t value = m_openset.min_value ();
112113int cx = value/ncol;
113114int cy = value%ncol;
114115
115- if (cx == (int )x2 && cy==(int )y2) {// we reached (x2,y2)
116- // reconstruct path & return
116+ if (cx == (int )x2 && cy==(int )y2) {// great! we've reached the target position (x2,y2)
117+ // reconstruct path
117118as->num_nodes = 2 ;
118119uint32_t tmp = x2*ncol+y2;
119120while ((tmp=came_from[tmp]) != x1*ncol+y1) {
@@ -135,47 +136,55 @@ namespace alg {
135136return as;
136137}
137138
139+ // delete current positon from openset and move it into closed set.
138140m_openset.delete_min ();
139141m_closedset (cx, cy) = true ;
140142m_openset_grid (cx, cy) = false ;
141143
142- // for each neighbor
144+ // for each valid neighbor of current position
143145int nx, ny;
144146for (nx=cx-1 ;nx<=cx+1 ;nx++) {
145- if (nx<0 || nx>=(int )ncol) continue ;
146147for (ny=cy-1 ;ny<=cy+1 ;ny++) {
147- if (ny<0 || ny>=(int )nrow) continue ;
148-
149- // except the wall;
150- if (m_grid (nx,ny) == WALL) continue ;
148+ // exclude invalid position
149+ if (nx<0 || nx>=(int )ncol || ny<0 || ny>=(int )nrow) continue ;
151150// except the cur itself
152151if (nx == cx && ny==cy) continue ;
153- // if neighbour in the closed set
152+ // except the wall;
153+ if (m_grid (nx,ny) == WALL) continue ;
154+ // exclude the neighbour in the closed set
154155if (m_closedset (nx,ny)) continue ;
155156
157+ // ok, we got a valid neighbour
156158float tentative = g_score (cx,cy);
157- if (nx == cx || ny == cy) {
158- tentative += 1 + m_grid (nx,ny) ;
159- } else {
160- tentative += ( 1 + m_grid (nx,ny)) * SQRT2;
159+ if (nx == cx || ny == cy) {// horizontal/vertical neighbour is near
160+ tentative += 1 ;
161+ } else { // diagonal neighbour is farther.
162+ tentative += SQRT2;
161163}
162164
163165// if neighbour not in the openset or dist < g_score[neighbour]
164166if (!m_openset_grid (nx,ny) || tentative < g_score (nx,ny)) {
165- came_from[nx*ncol+ny] = cx*ncol+cy; // record path
166- g_score (nx,ny) = tentative;
167- f_score (nx,ny) = tentative + estimate (nx,ny,x2,y2);
168- if (!m_openset_grid (nx,ny)) {
167+ came_from[nx*ncol+ny] = cx*ncol+cy; // record the path
168+ g_score (nx,ny) = tentative;// update path cost for current position
169+ f_score (nx,ny) = tentative + estimate (nx,ny,x2,y2);// record path cost to this neighbour
170+ if (!m_openset_grid (nx,ny)) {// only insert the neighbour if it hasn't been add to the openset.
169171m_openset.insert (f_score (nx,ny), nx*ncol+ny);
170172m_openset_grid (nx,ny) = true ;
171173}
172174}
173175}
174176}
175177}
178+
179+ // haven't reached target
176180return as;
177181}
178182private:
183+ /* *
184+ * Estimate the cost for going this way, such as:
185+ * acrossing the swamp will be much slower than walking on the road.
186+ * design for you game.
187+ */
179188inline float estimate (int x1, int y1, int x2, int y2) const {
180189return sqrtf ((x2-x1) * (x2-x1) + (y2-y1)*(y2-y1));
181190}
0 commit comments