Figuring out something weird about the Pathing::random_walk code.
This commit is contained in:
parent
ee804581a8
commit
77f2e94515
3 changed files with 30 additions and 10 deletions
|
@ -106,14 +106,17 @@ void Autowalker::path_fail(Matrix& bad_paths, Point pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Autowalker::path_player(Pathing& paths, Point& target_out) {
|
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) {
|
if(!found) {
|
||||||
|
fmt::println("4/8 NOT FOUND");
|
||||||
// failed to find a linear path, try diagonal
|
// 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);
|
path_fail(paths.$paths, target_out);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fmt::println("4/8 YES FOUND");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!fsm.$level.map->can_move(target_out)) {
|
if(!fsm.$level.map->can_move(target_out)) {
|
||||||
|
|
28
pathing.cpp
28
pathing.cpp
|
@ -74,12 +74,25 @@ void Pathing::clear_target(const Point &at) {
|
||||||
$input[at.y][at.x] = 1;
|
$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;
|
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
|
// first 4 directions are n/s/e/w for most enemies
|
||||||
std::array<Point, 8> dirs{{
|
std::array<Point, DIRECTION_MAX> dirs{{
|
||||||
{out.x,out.y-1}, // north
|
{out.x,out.y-1}, // north
|
||||||
{out.x+1,out.y}, // east
|
{out.x+1,out.y}, // east
|
||||||
{out.x,out.y+1}, // south
|
{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
|
{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
|
// get the current dijkstra number
|
||||||
int cur = $paths[out.y][out.x];
|
int cur = $paths[out.y][out.x];
|
||||||
|
|
||||||
// pick a random start of directions
|
// pick a random start of directions
|
||||||
// BUG: is uniform inclusive of the dir.size()?
|
// BUG: is uniform inclusive of the dir.size()?
|
||||||
int rand_start = Random::uniform<int>(0, dir_count);
|
int rand_start = Random::uniform<int>(0, dist_size);
|
||||||
|
|
||||||
// go through all possible directions
|
// 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
|
// but start at the random start, effectively randomizing
|
||||||
// which valid direction to go
|
// which valid direction to go
|
||||||
// BUG: this might be wrong given the above ranom from 0-size
|
// 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
|
if(!shiterator::inbounds($paths, dir.x, dir.y)) continue; //skip unpathable stuff
|
||||||
int weight = cur - $paths[dir.y][dir.x];
|
int weight = cur - $paths[dir.y][dir.x];
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ using matrix::Matrix;
|
||||||
|
|
||||||
constexpr const int PATHING_TOWARD=1;
|
constexpr const int PATHING_TOWARD=1;
|
||||||
constexpr const int PATHING_AWAY=-1;
|
constexpr const int PATHING_AWAY=-1;
|
||||||
constexpr const int MOVE_DIAGONAL=8;
|
constexpr const int DIRECTION_MAX=8;
|
||||||
|
|
||||||
class Pathing {
|
class Pathing {
|
||||||
public:
|
public:
|
||||||
|
@ -29,7 +29,8 @@ public:
|
||||||
Matrix &paths() { return $paths; }
|
Matrix &paths() { return $paths; }
|
||||||
Matrix &input() { return $input; }
|
Matrix &input() { return $input; }
|
||||||
int distance(Point to) { return $paths[to.y][to.x];}
|
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();
|
bool INVARIANT();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue