bool Problem::FindSuccessors(const ai::Search::State * const state_in, std::vector<ai::Search::ActionStatePair> &results_out) const { #if VERBOSE std::cout << "Problem::FindSuccessors()" << std::endl; #endif const State * pwstate_in = dynamic_cast<const State *>(state_in); for(ai::Scavenger::Location::Direction direction = ai::Scavenger::Location::NORTH; direction <= ai::Scavenger::Location::WEST; direction++) { Interface interface = model->getCell(pwstate_in->location).interface[direction]; #if DEBUG std::cout << "From: " << pwstate_in <<" passable: " << interface << std::endl; #endif if(passable(interface)) { State * next = pwstate_in->move(direction); next->charge = next->charge - pathCost(model, pwstate_in, direction); if(next->charge > 0) { results_out.push_back( ai::Search::ActionStatePair( next, new Action(getActionFromDirection(direction)) ) ); } } } #if VERBOSE std::cout << "results_out.size() = " << results_out.size() << std::endl; #endif return true; }
double Problem::StepCost(const ai::Search::State * const state1_in, const ai::Search::Action * const action_in, const ai::Search::State * const state2_in) const { const Action * pwaction_in = dynamic_cast<const Action *>(action_in); const State * pwstate1_in = dynamic_cast<const State *>(state1_in); const State * pwstate2_in = dynamic_cast<const State *>(state2_in); #if DEBUG std::cout <<"stepcost() action: state1: " << pwstate1_in << " , action: " << pwaction_in << " , state2: " << pwstate2_in << std::endl; #endif return pathCost(model, pwstate1_in, getDirectionFromAction(pwaction_in->action)); }
// Compute shortest path to goal position via A* algorithm // If 'goalArea' is NULL, path will get as close as it can. bool CCSBot::ComputePath(CNavArea *goalArea, const Vector *goal, RouteType route) { // Throttle re-pathing if (!m_repathTimer.IsElapsed()) return false; // randomize to distribute CPU load m_repathTimer.Start(RANDOM_FLOAT(0.4f, 0.6f)); DestroyPath(); CNavArea *startArea = m_lastKnownArea; if (!startArea) return false; // note final specific position Vector pathEndPosition; if (!goal && !goalArea) return false; if (!goal) pathEndPosition = *goalArea->GetCenter(); else pathEndPosition = *goal; // make sure path end position is on the ground if (goalArea) pathEndPosition.z = goalArea->GetZ(&pathEndPosition); else GetGroundHeight(&pathEndPosition, &pathEndPosition.z); // if we are already in the goal area, build trivial path if (startArea == goalArea) { BuildTrivialPath(&pathEndPosition); return true; } // Compute shortest path to goal CNavArea *closestArea = nullptr; PathCost pathCost(this, route); bool pathToGoalExists = NavAreaBuildPath(startArea, goalArea, goal, pathCost, &closestArea); CNavArea *effectiveGoalArea = (pathToGoalExists) ? goalArea : closestArea; // Build path by following parent links // get count int count = 0; CNavArea *area; for (area = effectiveGoalArea; area; area = area->GetParent()) { count++; } // save room for endpoint if (count > MAX_PATH_LENGTH - 1) count = MAX_PATH_LENGTH - 1; if (count == 0) return false; if (count == 1) { BuildTrivialPath(&pathEndPosition); return true; } // build path m_pathLength = count; for (area = effectiveGoalArea; count && area; area = area->GetParent()) { count--; m_path[count].area = area; m_path[count].how = area->GetParentHow(); } // compute path positions if (ComputePathPositions() == false) { PrintIfWatched("Error building path\n"); DestroyPath(); return false; } if (!goal) { switch (m_path[m_pathLength - 1].how) { case GO_NORTH: case GO_SOUTH: pathEndPosition.x = m_path[m_pathLength - 1].pos.x; pathEndPosition.y = effectiveGoalArea->GetCenter()->y; break; case GO_EAST: case GO_WEST: pathEndPosition.x = effectiveGoalArea->GetCenter()->x; pathEndPosition.y = m_path[m_pathLength - 1].pos.y; break; } GetGroundHeight(&pathEndPosition, &pathEndPosition.z); } // append path end position m_path[m_pathLength].area = effectiveGoalArea; m_path[m_pathLength].pos = pathEndPosition; m_path[m_pathLength].ladder = nullptr; m_path[m_pathLength].how = NUM_TRAVERSE_TYPES; m_pathLength++; // do movement setup m_pathIndex = 1; m_areaEnteredTimestamp = gpGlobals->time; m_spotEncounter = nullptr; m_goalPosition = m_path[1].pos; if (m_path[1].ladder) SetupLadderMovement(); else m_pathLadder = nullptr; return true; }