Direction::Enum OnThinkPacman3(const Pawn& in_ourPawn, const World& in_ourWorld, float in_deltaTime, float in_totalTime) { std::vector<PointObj*> pointObjects; in_ourWorld.GetPointObjects(pointObjects); Vector2 avgBestLocation = Vector2(0, 0); for(auto obj : pointObjects) { avgBestLocation = avgBestLocation + obj->GetPosition(); } PointObj* closestObject = nullptr; float closestSqr = FLT_MAX; for (auto obj : pointObjects) { float distanceSqr = (obj->GetPosition() - avgBestLocation).MagnitudeSqr(); if(distanceSqr < closestSqr) { closestSqr = distanceSqr; closestObject = obj; } } if (!closestObject) return Direction::Invalid; PathNode* start = in_ourWorld.GetNode(in_ourPawn.GetClosestNode()); PathNode* destination = in_ourWorld.GetNode(closestObject->GetNode()); return aStar(in_ourWorld, start, destination); }
// expands the current node in all four directions. Adds valid expansions to the frontier list void Expand(const World& in_world, std::shared_ptr<ScoredNode> in_curNode, const PathNode& in_targetNode, std::vector<const Pawn* const> in_ghosts, std::priority_queue<std::shared_ptr<ScoredNode>, std::vector<std::shared_ptr<ScoredNode>>, std::function<bool(std::shared_ptr<ScoredNode>, std::shared_ptr<ScoredNode>)>>& inout_frontier, std::map<PathNode*, std::shared_ptr<ScoredNode>>& inout_frontierMap, const std::map<PathNode*, std::shared_ptr<ScoredNode>>& in_processedNodes) { for (int i = 0; i < 4; i++) { const PathNodeConnection& connection = in_curNode->node->GetConnection(static_cast<Direction::Enum>(i)); if (connection.IsValid()) { //Gather the information on this next connection PathNode* connectedNode = in_world.GetNode(connection.GetOtherNodeId()); //If the node has already been processed then by definition of A* we must be back tracking and we can ignore this connection auto foundInProcessed = in_processedNodes.find(connectedNode); if (foundInProcessed != in_processedNodes.end()) continue; float cost = in_curNode->totalScore + connection.GetCost(); float h = huristic(*connectedNode, in_targetNode) + CalculateGhostEffect(*connectedNode, in_ghosts) + CalculatePointBonus(*connectedNode); float totalCost = cost + h; //check if the frontier already contains this node, if it does keep the larger of the two auto foundInFrontier = inout_frontierMap.find(connectedNode); if (foundInFrontier != inout_frontierMap.end()) { //if we are worse than the node already in the frontier then we should skip further processing if (foundInFrontier->second->totalScore < totalCost) continue; else inout_frontierMap.erase(foundInFrontier); } std::shared_ptr<ScoredNode> newNode = std::make_shared<ScoredNode>(connectedNode, cost, h, static_cast<Direction::Enum>(i), in_curNode); inout_frontier.push(newNode); inout_frontierMap.insert(std::pair<PathNode*, std::shared_ptr<ScoredNode>>(connectedNode, newNode)); } } }