OPEN->NextNode=Node;// make Open List point to first node for (;;) { //从Open表中取得一个估价值最好的节点 BestNode=ReturnBestNode();
//如果该节点是目标节点就退出 if (BestNode->NodeNum == TileNumDest)// if we've found the end, break and finish break; //否则生成子节点 GenerateSuccessors(BestNode,sx,sy); } PATH = BestNode; }
再看看生成子节点函数 GenerateSuccessors:
void AstarPathfinder::GenerateSuccessors(NODE *BestNode, int dx, int dy) { int x, y;
//依次生成八个方向的子节点,简单! // Upper-Left if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y-TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Upper if ( FreeTile(x=BestNode->x, y=BestNode->y-TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Upper-Right if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y-TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Right if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y) ) GenerateSucc(BestNode,x,y,dx,dy); // Lower-Right if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y+TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Lower if ( FreeTile(x=BestNode->x, y=BestNode->y+TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Lower-Left if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y+TILESIZE) ) GenerateSucc(BestNode,x,y,dx,dy); // Left if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y) ) GenerateSucc(BestNode,x,y,dx,dy); }
看看最重要的函数GenerateSucc:
void AstarPathfinder::GenerateSucc(NODE *BestNode,int x, int y, int dx, int dy) { int g, TileNumS, c = 0; NODE *Old, *Successor;
//计算子节点的 g 值 g = BestNode->g+1;// g(Successor)=g(BestNode)+cost of getting from BestNode to Successor TileNumS = TileNum(x,y);// identification purposes
//子节点再Open表中吗? if ( (Old=CheckOPEN(TileNumS)) != NULL )// if equal to NULL then not in OPEN list, // else it returns the Node in Old { //若在 for( c = 0; c <8; c++) if( BestNode->Child[c] == NULL )// Add Old to the list of BestNode's Children // (or Successors). break; BestNode->Child[c] = Old; //比较Open表中的估价值和当前的估价值(只要比较g值就可以了) if ( g g )// if our new g value is Parent = BestNode; Old->g = g; Old->f = g + Old->h; } } else//在Closed表中吗? if ( (Old=CheckCLOSED(TileNumS)) != NULL )// if equal to NULL then not in OPEN list // else it returns the Node in Old { //若在 for( c = 0; c<8; c++) if ( BestNode->Child[c] == NULL )// Add Old to the list of BestNode's // Children (or Successors). break; BestNode->Child[c] = Old; //比较Closed表中的估价值和当前的估价值(只要比较g值就可以了) if ( g g )// if our new g value is Parent = BestNode; Old->g = g; Old->f = g + Old->h;//再依次更新Old的所有子节点的估价值 PropagateDown(Old);// Since we changed the g value of Old, we need // to propagate this new value downwards, i.e. // do a Depth-First traversal of the tree! } } else//不在Open表中也不在Close表中 { //生成新的节点 Successor = ( NODE* )calloc(1,sizeof( NODE )); Successor->Parent = BestNode; Successor->g = g; Successor->h = (x-dx)*(x-dx) + (y-dy)*(y-dy);// should do sqrt(), but since we don't really Successor->f = g+Successor->h;// care about the distance but just which branch looks Successor->x = x; // better this should suffice. Anyayz it's faster. Successor->y = y; Successor->NodeNum = TileNumS; //再插入Open表中,同时排序。 Insert(Successor);// Insert Successor on OPEN list wrt f for( c =0; c <8; c++) if ( BestNode->Child[c] == NULL )// Add Old to the list of BestNode's Children (or Successors). break; BestNode->Child[c] = Successor; } }