Пример #1
0
	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);
	}
Пример #2
0
	// 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));
			}
		}
	}