Refactor EntityBehavior SEEK/FLEE to use PathProvider strategy; refs #315
EntityBehavior no longer holds a direct DijkstraMap reference. A new PathProvider interface has three concrete implementations: - DijkstraProvider: steps along a (possibly inverted) DijkstraMap. SEEK descends a normal map toward roots; FLEE descends an inverted map away from threats. - AStarProvider: follows a pre-computed AStarPath step-by-step. - TargetProvider: takes a single (x, y) target and picks the Chebyshev neighbor closest to it each turn. Entity.set_behavior() gains a pathfinder= kwarg accepting any of the above (DijkstraMap, AStarPath, or (x, y) tuple). The old executeSeek/executeFlee helpers collapse into a single executeProviderStep() that delegates to the provider. EntityBehavior.h forward-declares PathProvider so the header stays light. EntityBehavior::reset() moves out of line to avoid pulling PathProvider into the header. New tests: tests/regression/issue_315_path_provider_test.py covers all three providers driving SEEK, FLEE via inverted DijkstraMap, mid-run pathfinder swap, and invalid-argument handling. grid_step_bench baseline refreshed against the new provider dispatch path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
767d0d4b0f
commit
17f2d6e1ef
7 changed files with 349 additions and 82 deletions
65
src/PathProvider.cpp
Normal file
65
src/PathProvider.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#include "PathProvider.h"
|
||||
#include "UIGrid.h"
|
||||
#include "UIGridPathfinding.h"
|
||||
#include "UIGridPoint.h"
|
||||
|
||||
static bool cellWalkable(UIGrid& grid, int x, int y) {
|
||||
if (x < 0 || x >= grid.grid_w || y < 0 || y >= grid.grid_h) return false;
|
||||
return grid.at(x, y).walkable;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// DijkstraProvider
|
||||
// -----------------------------------------------------------------------------
|
||||
DijkstraProvider::DijkstraProvider(std::shared_ptr<DijkstraMap> map)
|
||||
: map_(std::move(map)) {}
|
||||
|
||||
sf::Vector2i DijkstraProvider::nextStep(sf::Vector2i from, UIGrid& /*grid*/, bool* ok) {
|
||||
if (!map_) {
|
||||
if (ok) *ok = false;
|
||||
return {-1, -1};
|
||||
}
|
||||
bool valid = false;
|
||||
sf::Vector2i step = map_->descentStep(from.x, from.y, &valid);
|
||||
if (ok) *ok = valid;
|
||||
return step;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// AStarProvider
|
||||
// -----------------------------------------------------------------------------
|
||||
AStarProvider::AStarProvider(std::vector<sf::Vector2i> path)
|
||||
: path_(std::move(path)) {}
|
||||
|
||||
sf::Vector2i AStarProvider::nextStep(sf::Vector2i /*from*/, UIGrid& /*grid*/, bool* ok) {
|
||||
if (index_ >= path_.size()) {
|
||||
if (ok) *ok = false;
|
||||
return {-1, -1};
|
||||
}
|
||||
if (ok) *ok = true;
|
||||
return path_[index_++];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// TargetProvider
|
||||
// -----------------------------------------------------------------------------
|
||||
TargetProvider::TargetProvider(sf::Vector2i target)
|
||||
: target_(target) {}
|
||||
|
||||
sf::Vector2i TargetProvider::nextStep(sf::Vector2i from, UIGrid& grid, bool* ok) {
|
||||
int dx = target_.x - from.x;
|
||||
int dy = target_.y - from.y;
|
||||
if (dx == 0 && dy == 0) {
|
||||
if (ok) *ok = false;
|
||||
return {-1, -1}; // already at target
|
||||
}
|
||||
int sx = (dx > 0) ? 1 : ((dx < 0) ? -1 : 0);
|
||||
int sy = (dy > 0) ? 1 : ((dy < 0) ? -1 : 0);
|
||||
sf::Vector2i step{from.x + sx, from.y + sy};
|
||||
if (!cellWalkable(grid, step.x, step.y)) {
|
||||
if (ok) *ok = false;
|
||||
return {-1, -1};
|
||||
}
|
||||
if (ok) *ok = true;
|
||||
return step;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue