diff --git a/autowalker.cpp b/autowalker.cpp index 19ebffe..983beed 100644 --- a/autowalker.cpp +++ b/autowalker.cpp @@ -106,14 +106,17 @@ void Autowalker::path_fail(Matrix& bad_paths, Point pos) { } bool Autowalker::path_player(Pathing& paths, Point& target_out) { - bool found = paths.random_walk(target_out, false, PATHING_TOWARD); + bool found = paths.random_walk(target_out, false, PATHING_TOWARD, 4, 8); if(!found) { + fmt::println("4/8 NOT FOUND"); // failed to find a linear path, try diagonal - if(!paths.random_walk(target_out, false, PATHING_TOWARD, MOVE_DIAGONAL)) { + if(!paths.random_walk(target_out, false, PATHING_TOWARD, 8, 8)) { path_fail(paths.$paths, target_out); return false; } + } else { + fmt::println("4/8 YES FOUND"); } if(!fsm.$level.map->can_move(target_out)) { diff --git a/pathing.cpp b/pathing.cpp index 0995612..81390b7 100644 --- a/pathing.cpp +++ b/pathing.cpp @@ -74,12 +74,25 @@ void Pathing::clear_target(const Point &at) { $input[at.y][at.x] = 1; } -bool Pathing::random_walk(Point &out, bool random, int direction, size_t dir_count) { +/* + * This is a weird discovery, but if you randomly select a starting point on + * the 8 compass, but only check 4 directions from there, it does the best + * pathing so far. It will walk around items, navigate around enemies, find + * paths through corners, etc. If you change slice_count/dist_count to just + * 4 it fails more frequently. + * + * Look in the autowalker.cpp:path_player function for an example of what + * I'm doing. I start with 4/8 and it finds paths 99% of the time, but + * if that fails I do a full 8 direction search. This weirdly finds the + * best directions to go more often. + */ +bool Pathing::random_walk(Point &out, bool random, + int direction, size_t slice_count, size_t dist_size) +{ bool zero_found = false; - dbc::check(dir_count == 4 || dir_count == 8, "Only 8 or 4 directions allowed."); // first 4 directions are n/s/e/w for most enemies - std::array dirs{{ + std::array dirs{{ {out.x,out.y-1}, // north {out.x+1,out.y}, // east {out.x,out.y+1}, // south @@ -92,19 +105,22 @@ bool Pathing::random_walk(Point &out, bool random, int direction, size_t dir_cou {out.x-1,out.y-1} // north west }}; + dbc::check(slice_count <= dirs.size(), "slize_count must be <= DIRECTION_MAX"); + dbc::check(dist_size <= dirs.size(), "dist_size must be <= DIRECTION_MAX"); + // get the current dijkstra number int cur = $paths[out.y][out.x]; // pick a random start of directions // BUG: is uniform inclusive of the dir.size()? - int rand_start = Random::uniform(0, dir_count); + int rand_start = Random::uniform(0, dist_size); // go through all possible directions - for(size_t i = 0; i < dir_count; i++) { + for(size_t i = 0; i < slice_count; i++) { // but start at the random start, effectively randomizing // which valid direction to go // BUG: this might be wrong given the above ranom from 0-size - Point dir = dirs[(i + rand_start) % dir_count]; + Point dir = dirs[(i + rand_start) % dist_size]; if(!shiterator::inbounds($paths, dir.x, dir.y)) continue; //skip unpathable stuff int weight = cur - $paths[dir.y][dir.x]; diff --git a/pathing.hpp b/pathing.hpp index c55acf1..ad5ebc3 100644 --- a/pathing.hpp +++ b/pathing.hpp @@ -7,7 +7,7 @@ using matrix::Matrix; constexpr const int PATHING_TOWARD=1; constexpr const int PATHING_AWAY=-1; -constexpr const int MOVE_DIAGONAL=8; +constexpr const int DIRECTION_MAX=8; class Pathing { public: @@ -29,7 +29,8 @@ public: Matrix &paths() { return $paths; } Matrix &input() { return $input; } int distance(Point to) { return $paths[to.y][to.x];} - bool random_walk(Point &out, bool random, int direction, size_t dir_count = 4); + bool random_walk(Point &out, bool random, int direction, + size_t slice_count=4, size_t dist_size=4); bool INVARIANT(); };