More refinement of the maps. Now the inner box won't have rooms in it and I can mark a region free of rooms. Rooms also have a guaranteed door.

This commit is contained in:
Zed A. Shaw 2026-03-08 12:25:40 -04:00
parent 87a1193a4a
commit 8b129aea6b
4 changed files with 40 additions and 33 deletions

View file

@ -101,6 +101,10 @@ namespace maze {
return false;
}
if(room.overlaps($no_rooms_region)) {
return false;
}
for(auto& other : $rooms) {
if(room.overlaps(other)) return false;
}
@ -113,8 +117,7 @@ namespace maze {
// use those dead ends to randomly place rooms
for(auto at : $dead_ends) {
// moving by +1 can randomly surround rooms with walls or not
size_t offset = Random::uniform(0,1);
Room cur{at.x+offset, at.y+offset, room_size, room_size};
Room cur{at.x, at.y, room_size, room_size};
bool selected = Random::uniform(0,1) == 0;
// if it's out of bounds skip it
@ -184,16 +187,14 @@ namespace maze {
size_t x = matrix::width($walls) / 2;
size_t y = matrix::height($walls) / 2;
for(matrix::circle it{$walls, {x, y}, outer_rad};
it.next();)
for(matrix::circle it{$walls, {x, y}, outer_rad}; it.next();)
{
for(int x = it.left; x < it.right; x++) {
$walls[it.y][x] = 0;
}
}
for(matrix::circle it{$walls, {x, y}, inner_rad};
it.next();)
for(matrix::circle it{$walls, {x, y}, inner_rad}; it.next();)
{
for(int x = it.left; x < it.right; x++) {
$walls[it.y][x] = 1;
@ -288,6 +289,23 @@ namespace maze {
});
}
void Builder::make_doors() {
for(auto room : $rooms) {
perimeter(room.x, room.y, room.width, room.height, [&](auto x, auto y) {
if($ends_map.contains({x, y})) {
for(matrix::compass door_at{$walls, x, y}; door_at.next();) {
if($walls[door_at.y][door_at.x] == WALL_VALUE) {
$walls[door_at.y][door_at.x] = SPACE_VALUE;
break;
}
}
}
});
}
enclose();
}
void Builder::inner_box(size_t outer_size, size_t inner_size) {
size_t x = matrix::width($walls) / 2;
size_t y = matrix::height($walls) / 2;
@ -301,6 +319,9 @@ namespace maze {
{
$walls[it.y][it.x] = 1;
}
// make a fake room that blocks others
$no_rooms_region = {x - outer_size, y - outer_size, outer_size * 2 + 1, outer_size * 2 + 1};
}
void Builder::add_dead_end(Point at) {

View file

@ -10,6 +10,7 @@ namespace maze {
std::vector<Room>& $rooms;
std::vector<Point>& $dead_ends;
std::unordered_map<Point, bool> $ends_map;
Room $no_rooms_region{0,0,0,0};
Builder(Map& map) :
$walls(map.$walls), $rooms(map.$rooms), $dead_ends(map.$dead_ends)
@ -32,5 +33,6 @@ namespace maze {
void open_box(size_t outer_size);
void add_dead_end(Point at);
bool room_should_exist(Room& room);
void make_doors();
};
}

View file

@ -14,25 +14,6 @@
using lighting::LightSource;
/*
struct Point {
double x;
double y;
};
struct Rect {
Point p1, p2, p3, p4;
// four corners (any order)
bool contains(const Point& pt) const {
double minX = std::min({p1.x, p2.x, p3.x, p4.x});
double maxX = std::max({p1.x, p2.x, p3.x, p4.x});
double minY = std::min({p1.y, p2.y, p3.y, p4.y});
double maxY = std::max({p1.y, p2.y, p3.y, p4.y});
return pt.x >= minX && pt.x <= maxX && pt.y >= minY && pt.y <= maxY;
}
};
*/
struct Room {
size_t x = 0;
size_t y = 0;