Implemented GBFS
This commit is contained in:
parent
2dd44ab169
commit
7eee6a5c54
@ -196,6 +196,62 @@ Path Dijkstra::CalculatePath(WorldPos start_world, WorldPos end_world)
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GBFS::Heuristic(const TilePos& a, const TilePos& b)
|
||||||
|
{
|
||||||
|
return static_cast<float>(std::abs(a.x- b.x) + std::abs(a.y - b.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
Path GBFS::CalculatePath(WorldPos start_world, WorldPos end_world)
|
||||||
|
{
|
||||||
|
if (!m_Map) return {};
|
||||||
|
|
||||||
|
const TilePos start = m_Map->WorldToTile(start_world);
|
||||||
|
const TilePos end = m_Map->WorldToTile(end_world);
|
||||||
|
|
||||||
|
if (!m_Map->IsTilePosValid(start) || !m_Map->IsTilePosValid(end))
|
||||||
|
return {};
|
||||||
|
if (start == end) return {};
|
||||||
|
|
||||||
|
m_CameFrom.clear();
|
||||||
|
|
||||||
|
std::priority_queue<QueueEntry, std::vector<QueueEntry>, std::greater<>> frontier;
|
||||||
|
frontier.push({Heuristic(start, end), start});
|
||||||
|
m_CameFrom[start] = start; // sentinel
|
||||||
|
|
||||||
|
while (!frontier.empty())
|
||||||
|
{
|
||||||
|
const QueueEntry current = frontier.top();
|
||||||
|
frontier.pop();
|
||||||
|
|
||||||
|
if (current.tile == end) // early exit
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (TilePos next : m_Map->GetNeighbors(current.tile))
|
||||||
|
{
|
||||||
|
if (!m_CameFrom.count(next)) // not visited
|
||||||
|
{
|
||||||
|
m_CameFrom[next] = current.tile;
|
||||||
|
frontier.push({Heuristic(end, next), next});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reconstruct path
|
||||||
|
if (!m_CameFrom.count(end))
|
||||||
|
return {}; // goal never reached
|
||||||
|
|
||||||
|
Path path;
|
||||||
|
TilePos cur = end;
|
||||||
|
path.push_back(m_Map->TileToWorld(cur));
|
||||||
|
|
||||||
|
while (cur != start)
|
||||||
|
{
|
||||||
|
cur = m_CameFrom[cur];
|
||||||
|
path.push_back(m_Map->TileToWorld(cur));
|
||||||
|
}
|
||||||
|
std::reverse(path.begin(), path.end());
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<PathFinderBase> create(PathFinderType type, const Map* map) {
|
std::unique_ptr<PathFinderBase> create(PathFinderType type, const Map* map) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -205,6 +261,8 @@ std::unique_ptr<PathFinderBase> create(PathFinderType type, const Map* map) {
|
|||||||
return std::move(std::make_unique<BFS>(map));
|
return std::move(std::make_unique<BFS>(map));
|
||||||
case PathFinderType::DIJKSTRA:
|
case PathFinderType::DIJKSTRA:
|
||||||
return std::move(std::make_unique<Dijkstra>(map));
|
return std::move(std::make_unique<Dijkstra>(map));
|
||||||
|
case PathFinderType::GBFS:
|
||||||
|
return std::move(std::make_unique<GBFS>(map));
|
||||||
case PathFinderType::COUNT:
|
case PathFinderType::COUNT:
|
||||||
LOG_WARNING("Incorrect pathfinder type");
|
LOG_WARNING("Incorrect pathfinder type");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -15,6 +15,7 @@ enum class PathFinderType {
|
|||||||
LINEAR = 1,
|
LINEAR = 1,
|
||||||
BFS,
|
BFS,
|
||||||
DIJKSTRA,
|
DIJKSTRA,
|
||||||
|
GBFS,
|
||||||
COUNT,
|
COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,6 +76,21 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GBFS: public PathFinderBase {
|
||||||
|
|
||||||
|
public:
|
||||||
|
GBFS(const Map* m): PathFinderBase(m) {}
|
||||||
|
Path CalculatePath(WorldPos start, WorldPos end) override;
|
||||||
|
const std::string_view& GetName() const override { return m_Name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static float Heuristic(const TilePos& a, const TilePos& b);
|
||||||
|
const std::string_view m_Name = "Greedy Best First Search";
|
||||||
|
std::unordered_map<TilePos, TilePos, TilePosHash> m_CameFrom;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<PathFinderBase> create(PathFinderType type, const Map* map);
|
std::unique_ptr<PathFinderBase> create(PathFinderType type, const Map* map);
|
||||||
|
|
||||||
} // pathfinder namespace
|
} // pathfinder namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user