1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Simple solution that works - by ChatGPT :)

This commit is contained in:
Tomasz Zieliński
2023-04-16 20:24:42 +02:00
parent d7092fbeb5
commit 7c6e4bc2fe

View File

@@ -43,94 +43,39 @@ float CZonePlacer::getDistance (float distance) const
void CZonePlacer::findPathsBetweenZones() void CZonePlacer::findPathsBetweenZones()
{ {
typedef std::pair<int, int> ConnectionIndex;
auto zones = map.getZones(); auto zones = map.getZones();
std::set<std::shared_ptr<Zone>> zonesToCheck; std::set<std::shared_ptr<Zone>> zonesToCheck;
//Initialize direct connections // Iterate through each pair of nodes in the graph
for (auto zone : zones)
{
auto zoneId = zone.second->getId();
for (auto connection : zone.second->getConnections())
{
if (!vstd::contains(distancesBetweenZones[zoneId], connection))
{
distancesBetweenZones[zoneId][connection] = 1;
distancesBetweenZones[connection][zoneId] = 1;
}
}
}
for (auto startZone : zones) for (const auto& zone : zones)
{ {
size_t start = startZone.second->getId(); int start = zone.first;
const auto& zone1Ptr = zone.second;
distancesBetweenZones[start][start] = 0; // Distance from a node to itself is 0
for (auto endZone : zones) std::queue<int> q;
{ std::map<int, bool> visited;
size_t end = endZone.second->getId(); visited[start] = true;
q.push(start);
if (start != end) // Perform Breadth-First Search from the starting node
while (!q.empty())
{ {
auto currentEnd = end; int current = q.front();
while (!vstd::contains(distancesBetweenZones[start], end)) q.pop();
{
size_t distance = 10; //Some large but not infinite number to not blow up the weights
std::stack<int> nearbyZones;
std::set<int> checkedZones;
//FIXME: we may know the path from previous iterations, but can't be sure if it's optimal :? const auto& currentZone = zones.at(current);
const auto& connections = currentZone->getConnections();
for (auto nearbyZone : startZone.second->getConnections()) for (uint32_t neighbor : connections)
{ {
nearbyZones.push(nearbyZone); if (!visited[neighbor])
}
while (!nearbyZones.empty())
{ {
auto currentZone = nearbyZones.top(); visited[neighbor] = true;
nearbyZones.pop(); q.push(neighbor);
distancesBetweenZones[start][neighbor] = distancesBetweenZones[start][current] + 1;
checkedZones.insert(currentZone);
for (auto neighbourZone : distancesBetweenZones[currentZone])
{
if (neighbourZone.first == currentEnd)
{
//This zone has connection to our end zone
if (!vstd::contains(distancesBetweenZones[currentZone], currentEnd))
{
//Initialize the connection of adjacent zones
distancesBetweenZones[currentZone][currentEnd] = 1;
}
if ((distancesBetweenZones[currentZone][currentEnd] + 1) < distance)
{
//We found new, shorter path
distance = distancesBetweenZones[currentZone][currentEnd] + 1;
//Add just found connection
distancesBetweenZones[start][currentEnd] = distance;
//Connection is bidirectional
distancesBetweenZones[currentEnd][start] = distance;
//Unwind the stack, find the path between start previous-to-last zone
currentEnd = currentZone;
}
}
else
{
if (!vstd::contains(checkedZones, neighbourZone.first))
{
//We didn't check that zone yet
nearbyZones.push(neighbourZone.first);
}
}
}
}
//At the very least after this step we will find 1 more step connecting the two zones
} }
} }
} }