| 684 | |
| 685 | |
| 686 | int MicroPather::Solve( cPosition* startNode, cPosition* endNode, MP_VECTOR< cPosition >* path, float* cost ) |
| 687 | { |
| 688 | // Important to clear() in case the caller doesn't check the return code. There |
| 689 | // can easily be a left over path from a previous call. |
| 690 | path->clear(); |
| 691 | |
| 692 | #ifdef DEBUG_PATH |
| 693 | printf( "Path: " ); |
| 694 | graph->PrintStateInfo( startNode ); |
| 695 | printf( " --> " ); |
| 696 | graph->PrintStateInfo( endNode ); |
| 697 | printf( " min cost=%f\n", graph->LeastCostEstimate( startNode, endNode ) ); |
| 698 | #endif |
| 699 | |
| 700 | *cost = 0.0f; |
| 701 | |
| 702 | if ( startNode == endNode ) |
| 703 | return START_END_SAME; |
| 704 | |
| 705 | ++frame; |
| 706 | |
| 707 | OpenQueue open( graph ); |
| 708 | ClosedSet closed( graph ); |
| 709 | |
| 710 | PathNode* newPathNode = pathNodePool.GetPathNode( frame, |
| 711 | *startNode, |
| 712 | 0, |
| 713 | graph->LeastCostEstimate( startNode, endNode ), |
| 714 | 0 ); |
| 715 | |
| 716 | open.Push( newPathNode ); |
| 717 | stateCostVec.resize(0); |
| 718 | nodeCostVec.resize(0); |
| 719 | |
| 720 | while ( !open.Empty() ) |
| 721 | { |
| 722 | PathNode* node = open.Pop(); |
| 723 | |
| 724 | if ( node->state == *endNode || node->state.distanceTo(*endNode) <= 8) |
| 725 | { |
| 726 | GoalReached( node, startNode, endNode, path ); |
| 727 | *cost = node->costFromStart; |
| 728 | #ifdef DEBUG_PATH |
| 729 | DumpStats(); |
| 730 | #endif |
| 731 | return SOLVED; |
| 732 | } |
| 733 | else |
| 734 | { |
| 735 | closed.Add( node ); |
| 736 | |
| 737 | // We have not reached the goal - add the neighbors. |
| 738 | GetNodeNeighbors( node, &nodeCostVec ); |
| 739 | |
| 740 | for( int i=0; i<node->numAdjacent; ++i ) |
| 741 | { |
| 742 | // Not actually a neighbor, but useful. Filter out infinite cost. |
| 743 | if ( nodeCostVec[i].cost == FLT_MAX ) { |
no test coverage detected