diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-10-24 14:44:20 +0200 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-10-24 14:44:20 +0200 |
commit | afc66d3013b7d47c6c22d6a99809bc3e7d1ff0dc (patch) | |
tree | de50baa5d2f87cc8a416cbd321f7c7f430b03613 /BreadthFirstPathfinder.cpp | |
parent | 1e0a52b03fe655d7073ef20703dbb2e7646f74d3 (diff) |
implement breadth-first search pathfinding
Diffstat (limited to 'BreadthFirstPathfinder.cpp')
-rw-r--r-- | BreadthFirstPathfinder.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/BreadthFirstPathfinder.cpp b/BreadthFirstPathfinder.cpp new file mode 100644 index 0000000..ef4492a --- /dev/null +++ b/BreadthFirstPathfinder.cpp @@ -0,0 +1,67 @@ +#include "BreadthFirstPathfinder.h" +#include "Museum.h" +#include "NullTileBehavior.h" + +using namespace std; + +void BreadthFirstPathfinder::clear() { + Pathfinder::clear(); + this->solution.clear(); +} + +const BreadthFirstPathfinder::Path & BreadthFirstPathfinder::get_path() { + return this->solution; +} + +void BreadthFirstPathfinder::find_between(const XY & start, const XY & end) { + this->clear(); + + vector<Path> trails = { { start } }; + this->end = end; + + while (trails.size() > 0) { + trails = this->find_step(trails); + } +} + +vector<BreadthFirstPathfinder::Path> BreadthFirstPathfinder::find_step(const vector<Path> & to_visit) { + vector<Path> next_step = {}; + + for (Path trail : to_visit) { + const XY & here = trail.front(); + if (here == this->end) { + this->solution = trail; + return {}; + } + + Tile & tile = this->museum.canvas.get_tile(here); + const XY offsets[] = { + { 0, 1 }, + { 1, 0 }, + { 0, -1 }, + { -1, 0 }, + }; + for (size_t i = 0; i < 4; i++) { + const XY offset = offsets[i]; + Tile * neighbor = tile.get_neighbor(offset); + + // if neighbor doesn't exist (out of bounds) + if (neighbor == nullptr) continue; + + // if neighbor is a blank tile + TileBehavior * behavior = neighbor->behavior.get(); + if (dynamic_cast<NullTileBehavior *>(behavior) != nullptr) continue;; + + // if neighbor is already visited + if (this->is_visited(here + offset)) continue; + this->set_visited(here + offset); + + Path trail_copy = trail; + trail_copy.push_front(here + offset); + next_step.push_back(trail_copy); + } + } + + return next_step; +} + |