Maze gen can now more efficiently produce an interesting map that is fully pathable.

This commit is contained in:
Zed A. Shaw 2026-03-12 00:54:34 -04:00
parent f85ae8a6c6
commit e6fcbd8dcf
3 changed files with 75 additions and 8 deletions

View file

@ -215,12 +215,11 @@ namespace maze {
void Builder::remove_dead_ends() {
dbc::check($dead_ends.size() > 0, "you have to run an algo first, no dead_ends to remove");
for(auto at : $dead_ends) {
for(matrix::compass it{$walls, at.x, at.y}; it.next();) {
if($walls[it.y][it.x] == 0) {
int diff_x = at.x - it.x;
int diff_y = at.y - it.y;
$walls[at.y + diff_y][at.x + diff_x] = 0;
if($walls[it.y][it.x] == SPACE_VALUE) {
punch_dead_end(at.x, at.y, it.x, it.y);
break;
}
}
@ -404,4 +403,62 @@ namespace maze {
return true;
}
void Builder::punch_dead_end(size_t at_x, size_t at_y, size_t x, size_t y) {
int diff_x = at_x - x;
int diff_y = at_y - y;
$walls[at_y + diff_y][at_x + diff_x] = SPACE_VALUE;
}
bool Builder::repair() {
// possible fixes
// go through each dead end and remove until it works
// go through each room and add a door until it works
// only find rooms that are unpathable and fix them
// walk the path deleting dead ends at the end of the path
std::vector<Point> removed_ends;
bool now_valid = false;
for(auto& at : $dead_ends) {
// punch a hole for this dead end
for(matrix::compass it{$walls, at.x, at.y}; it.next();) {
if($walls[it.y][it.x] == SPACE_VALUE) {
punch_dead_end(at.x, at.y, it.x, it.y);
removed_ends.push_back({it.x, it.y});
break;
}
}
// if that validates it then done
if(validate()) {
now_valid = true;
fmt::println("MID dead_end removed={}, total={}, %={}",
removed_ends.size(), $dead_ends.size(),
float(removed_ends.size()) / float($dead_ends.size()));
break;
}
}
// now go back and see if we can add any back
int added_back = 0;
for(auto& at : removed_ends) {
$walls[at.y][at.x] = WALL_VALUE;
if(!validate()) {
$walls[at.y][at.x] = SPACE_VALUE;
} else {
added_back++;
}
}
enclose();
now_valid = validate();
fmt::println("FINAL now_valid={} added_back={} removed={}, total={}, %={}",
now_valid, added_back, removed_ends.size() - added_back, $dead_ends.size(),
float(removed_ends.size() - added_back) / float($dead_ends.size()));
// didn't find a way to make it valid
return now_valid;
}
}

View file

@ -40,5 +40,7 @@ namespace maze {
bool room_should_exist(Room& room, bool allow_dupes=false);
void make_doors();
bool validate();
bool repair();
void punch_dead_end(size_t at_x, size_t at_y, size_t x, size_t y);
};
}