More cleanups of the tests and fixes to the room and door positioning.
This commit is contained in:
parent
8e2a691337
commit
02d23bb77d
11 changed files with 75 additions and 78 deletions
|
|
@ -9,16 +9,6 @@ using std::string;
|
|||
using matrix::Matrix;
|
||||
|
||||
namespace maze {
|
||||
inline size_t rand(size_t i, size_t j) {
|
||||
if(i < j) {
|
||||
return Random::uniform(i, j);
|
||||
} else if(j < i) {
|
||||
return Random::uniform(j, i);
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool complete(Matrix& maze, size_t width, size_t height) {
|
||||
for(size_t row = 1; row < height; row += 2) {
|
||||
for(size_t col = 1; col < width; col += 2) {
|
||||
|
|
@ -89,8 +79,9 @@ namespace maze {
|
|||
}
|
||||
|
||||
bool Builder::room_should_exist(Room& room, bool allow_dupes) {
|
||||
if(!matrix::inbounds($walls, room.x, room.y) ||
|
||||
!matrix::inbounds($walls, room.x + room.width, room.y + room.height))
|
||||
// padding by 1 for the perimeter wall
|
||||
if(!matrix::inbounds($walls, room.x - 1, room.y - 1) ||
|
||||
!matrix::inbounds($walls, room.x + room.width + 2, room.y + room.height + 2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -187,7 +178,7 @@ namespace maze {
|
|||
$walls[row][col] = 0;
|
||||
} else {
|
||||
// found neighbors, pick random one
|
||||
auto nb = n[rand(size_t(0), n.size() - 1)];
|
||||
auto nb = n[Random::abs(size_t(0), n.size() - 1)];
|
||||
$walls[nb.y][nb.x] = 0;
|
||||
|
||||
size_t row = (nb.y + on.y) / 2;
|
||||
|
|
@ -196,12 +187,14 @@ namespace maze {
|
|||
on = nb;
|
||||
}
|
||||
}
|
||||
|
||||
if($rooms.size() > 0) place_rooms();
|
||||
}
|
||||
|
||||
void Builder::place_rooms() {
|
||||
for(auto& room : $rooms) {
|
||||
for(matrix::rectangle it{$walls, room.x, room.y, room.width, room.height}; it.next();) {
|
||||
$walls[it.y][it.x] = 0;
|
||||
$walls[it.y][it.x] = SPACE_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -239,7 +232,7 @@ namespace maze {
|
|||
}
|
||||
|
||||
void Builder::dump(const std::string& msg, bool path_too) {
|
||||
auto wall_copy = $walls;
|
||||
Matrix wall_copy = $walls;
|
||||
|
||||
// mark the rooms too, but not if pathing
|
||||
if(!path_too) {
|
||||
|
|
@ -307,6 +300,11 @@ namespace maze {
|
|||
}
|
||||
}
|
||||
|
||||
bool Builder::valid_door(size_t x, size_t y) {
|
||||
return (space_available(x, y - 1) && space_available(x, y + 1)) // north south
|
||||
|| (space_available(x - 1, y) && space_available(x + 1, y));
|
||||
}
|
||||
|
||||
void Builder::place_doors() {
|
||||
for(auto room : $rooms) {
|
||||
int best_longest = 0;
|
||||
|
|
@ -319,17 +317,14 @@ namespace maze {
|
|||
|
||||
// can't path out of the room, so now punch a hole until it can
|
||||
matrix::perimeter it{room.x - 1, room.y - 1, room.width + 2, room.height + 2};
|
||||
while(it.next()) {
|
||||
// don't use corners
|
||||
if((it.x == room.x - 1 && it.y == room.y - 1) ||
|
||||
(it.x == room.x - 1 && it.y == room.y + 2) ||
|
||||
(it.x == room.width + 2 && it.y == room.y + 2) ||
|
||||
(it.x == room.width + 2 && it.y == room.y - 1)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while(it.next()) {
|
||||
if($walls[it.y][it.x] == WALL_VALUE) {
|
||||
// valid doors are free north/south or east/west
|
||||
if(!valid_door(it.x, it.y)) continue;
|
||||
|
||||
$walls[it.y][it.x] = SPACE_VALUE;
|
||||
|
||||
longest = compute_paths(room.x, room.y);
|
||||
|
||||
// keep track of the best door so far, which is the one with the longest path
|
||||
|
|
@ -348,8 +343,6 @@ namespace maze {
|
|||
$walls[best_door.y][best_door.x] = SPACE_VALUE;
|
||||
$doors.insert_or_assign(best_door, true);
|
||||
}
|
||||
|
||||
fmt::println("map valid after doors? {}", validate());
|
||||
}
|
||||
|
||||
void Builder::inner_box(size_t outer_size, size_t inner_size) {
|
||||
|
|
@ -408,7 +401,7 @@ namespace maze {
|
|||
|
||||
// initial path test can just use one room then look for
|
||||
// any cells that are empty in the walls map but unpathed in the paths
|
||||
Room test_room = $rooms.at(rand(0, $rooms.size() - 1));
|
||||
Room test_room = $rooms.at(Random::abs(size_t(0), $rooms.size() - 1));
|
||||
compute_paths(test_room.x, test_room.y);
|
||||
|
||||
for(matrix::each_cell it{$walls}; it.next();) {
|
||||
|
|
@ -422,10 +415,10 @@ namespace maze {
|
|||
}
|
||||
|
||||
bool Builder::space_available(size_t x, size_t y) {
|
||||
bool in_bounds = matrix::inbounds($walls, x, y);
|
||||
bool is_space = $walls[y][x] == SPACE_VALUE;
|
||||
bool not_perimeter = x > 0 && y > 0 && x < $width - 2 && y < $height - 2;
|
||||
return in_bounds && is_space && not_perimeter;
|
||||
return (matrix::inbounds($walls, x, y) && // in bounds
|
||||
$walls[y][x] == SPACE_VALUE && // is a space
|
||||
!$doors.contains({x, y}) && // no door there
|
||||
(x > 0 && y > 0 && x < $width - 2 && y < $height - 2)); // not perimeter;
|
||||
}
|
||||
|
||||
void Builder::punch_dead_end(size_t at_x, size_t at_y, size_t x, size_t y) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ namespace maze {
|
|||
void punch_dead_end(size_t at_x, size_t at_y, size_t x, size_t y);
|
||||
bool space_available(size_t x, size_t y);
|
||||
int compute_paths(size_t x, size_t y);
|
||||
bool valid_door(size_t x, size_t y);
|
||||
};
|
||||
|
||||
std::pair<Builder, bool> script(Map& map, nlohmann::json& config);
|
||||
|
|
|
|||
|
|
@ -9,5 +9,4 @@ namespace Random {
|
|||
int tick = Random::uniform_real(float(from), float(to));
|
||||
return std::chrono::milliseconds{tick};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,5 +27,15 @@ namespace Random {
|
|||
return rand(GENERATOR);
|
||||
}
|
||||
|
||||
auto abs(auto i, auto j) {
|
||||
if(i < j) {
|
||||
return Random::uniform(i, j);
|
||||
} else if(j < i) {
|
||||
return Random::uniform(j, i);
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
std::chrono::milliseconds milliseconds(int from, int to);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue