diff --git a/src/algos/maze.cpp b/src/algos/maze.cpp index 0693364..aaa0311 100644 --- a/src/algos/maze.cpp +++ b/src/algos/maze.cpp @@ -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) { diff --git a/src/algos/maze.hpp b/src/algos/maze.hpp index 5130409..7100e52 100644 --- a/src/algos/maze.hpp +++ b/src/algos/maze.hpp @@ -10,6 +10,7 @@ namespace maze { std::vector& $rooms; std::vector& $dead_ends; std::unordered_map $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(); }; } diff --git a/src/game/map.hpp b/src/game/map.hpp index c396db0..e3b21c6 100644 --- a/src/game/map.hpp +++ b/src/game/map.hpp @@ -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; diff --git a/tests/mazes.cpp b/tests/mazes.cpp index b8fd631..7e3b7bd 100644 --- a/tests/mazes.cpp +++ b/tests/mazes.cpp @@ -18,6 +18,7 @@ TEST_CASE("hunt-and-kill", "[mazes]") { maze.randomize_rooms(ROOM_SIZE); maze.hunt_and_kill(); + maze.make_doors(); // maze.dump("ROOM MAZE"); REQUIRE(map.$dead_ends.size() > 0); @@ -30,15 +31,16 @@ TEST_CASE("hunt-and-kill box", "[mazes]") { maze::Builder maze(map); maze.hunt_and_kill(); - maze.randomize_rooms(ROOM_SIZE+1); maze.clear(); + maze.inner_box(6, 4); + maze.randomize_rooms(ROOM_SIZE+2); - maze.inner_box(6, 3); maze.hunt_and_kill(); maze.open_box(6); + maze.make_doors(); - if(maze.$rooms.size() == 0) { - maze.dump("NO ROOMS"); + if(i == 42) { + maze.dump("INNER BOX"); } } } @@ -67,8 +69,6 @@ TEST_CASE("hunt-and-kill fissure", "[mazes]") { REQUIRE(maze.$rooms.size() == 0); } - - TEST_CASE("hunt-and-kill no-dead-ends", "[mazes]") { Map map(21, 21); maze::Builder maze(map); @@ -88,10 +88,13 @@ TEST_CASE("hunt-and-kill too much", "[mazes]") { maze.hunt_and_kill(); maze.randomize_rooms(ROOM_SIZE); maze.clear(); - maze.inner_donut(4, 2); + maze.inner_donut(9, 4); maze.divide({3,3}, {15,16}); maze.hunt_and_kill(); + maze.make_doors(); - // maze.dump("COMBINED"); + // if(i == 41) { + // maze.dump("COMBINED"); + // } } }