Pathing in either diagonal or simple motion works.

This commit is contained in:
Zed A. Shaw 2025-08-31 00:17:47 -04:00
parent e92fd2b6f3
commit fc678c6b42
3 changed files with 34 additions and 20 deletions

View file

@ -37,7 +37,7 @@ tracy_build:
meson compile -j 10 -C builddir meson compile -j 10 -C builddir
test: asset_build build test: asset_build build
./builddir/runtests -d yes "[pathing]" ./builddir/runtests -d yes
run: build test run: build test
ifeq '$(OS)' 'Windows_NT' ifeq '$(OS)' 'Windows_NT'
@ -60,7 +60,7 @@ clean:
meson compile --clean -C builddir meson compile --clean -C builddir
debug_test: build debug_test: build
gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests -e "[pathing]" gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests -e
win_installer: win_installer:
powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp' powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp'

View file

@ -76,29 +76,42 @@ void Pathing::clear_target(const Point &at) {
PathingResult Pathing::find_path(Point &out, int direction, bool diag) PathingResult Pathing::find_path(Point &out, int direction, bool diag)
{ {
(void)diag;
// get the current dijkstra number // get the current dijkstra number
int cur = $paths[out.y][out.x]; int cur = $paths[out.y][out.x];
int target = cur; int target = cur;
bool found = false; bool found = false;
// go through all possible directions // a lambda makes it easy to capture what we have to change
for(matrix::box it{$paths, out.x, out.y, 1}; it.next();) { auto next_step = [&](size_t x, size_t y) -> bool {
target = $paths[it.y][it.x]; target = $paths[y][x];
// don't go through walls // don't go through walls
if(target == WALL_PATH_LIMIT) continue; if(target == WALL_PATH_LIMIT) return false;
int weight = cur - target; int weight = cur - target;
if(weight == direction) { if(weight == direction) {
out = {(size_t)it.x, (size_t)it.y}; out = {x, y};
found = true; found = true;
break; return true;
} else if(weight == 0) { } else if(weight == 0) {
out = {(size_t)it.x, (size_t)it.y}; out = {x, y};
found = true; found = true;
} }
return false;
};
if(diag) {
for(matrix::box it{$paths, out.x, out.y, 1}; it.next();) {
bool should_stop = next_step(it.x, it.y);
if(should_stop) break;
}
} else {
for(matrix::compass it{$paths, out.x, out.y}; it.next();) {
bool should_stop = next_step(it.x, it.y);
if(should_stop) break;
}
} }
if(target == 0) { if(target == 0) {

View file

@ -8,6 +8,7 @@
#include "game_level.hpp" #include "game_level.hpp"
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#include "rand.hpp"
using namespace fmt; using namespace fmt;
using namespace nlohmann; using namespace nlohmann;
@ -46,25 +47,25 @@ TEST_CASE("multiple targets can path", "[pathing]") {
}); });
paths.compute_paths(walls_copy); paths.compute_paths(walls_copy);
bool diag = Random::uniform<int>(0, 1);
auto pos = GameDB::player_position().location; auto pos = GameDB::player_position().location;
auto found = paths.find_path(pos, PATHING_TOWARD, false); auto found = paths.find_path(pos, PATHING_TOWARD, diag);
while(found == PathingResult::CONTINUE) { while(found == PathingResult::CONTINUE) {
fmt::println("\033[2J\033[1;1H"); // fmt::println("\033[2J\033[1;1H");
matrix::dump("failed paths", paths.$paths, pos.x, pos.y); // matrix::dump(diag ? "diag" : "simple", paths.$paths, pos.x, pos.y);
std::this_thread::sleep_for(200ms); std::this_thread::sleep_for(200ms);
found = paths.find_path(pos, PATHING_TOWARD, false); found = paths.find_path(pos, PATHING_TOWARD, diag);
} }
fmt::println("\033[2J\033[1;1H"); // fmt::println("\033[2J\033[1;1H");
matrix::dump("failed paths", paths.$paths, pos.x, pos.y); // matrix::dump(diag ? "diag" : "simple", paths.$paths, pos.x, pos.y);
if(found == PathingResult::FOUND) { if(found == PathingResult::FOUND) {
fmt::println("FOUND!"); fmt::println("FOUND!");
} else if(found == PathingResult::FAIL) { } else if(found == PathingResult::FAIL && !diag) {
fmt::println("FAILED!"); REQUIRE(found != PathingResult::FAIL);
std::this_thread::sleep_for(20000ms);
} }
} }