Gave up on adding a buffer and I'll just let rooms be near eachother. Seems to produce interesting results anyway.

This commit is contained in:
Zed A. Shaw 2026-03-09 11:12:26 -04:00
parent 8b129aea6b
commit 74f92dfe2c
5 changed files with 45 additions and 32 deletions

View file

@ -116,13 +116,30 @@ namespace maze {
void Builder::randomize_rooms(size_t room_size) {
// use those dead ends to randomly place rooms
for(auto at : $dead_ends) {
// moving by +1 can randomly surround rooms with walls or not
Room cur{at.x, at.y, room_size, room_size};
bool selected = Random::uniform(0,1) == 0;
// skip 50% of them
if(Random::uniform(0,1) == 0) continue;
// get the room corners randomized
std::array<Point, 4> starts{{
{at.x, at.y}, // top left
{at.x - room_size + 1, at.y}, // top right
{at.x - room_size + 1, at.y - room_size + 1}, // bottom right
{at.x, at.y - room_size + 1} // bottom left
}};
size_t offset = Random::uniform(0, 3);
// BUG: this still accidentally merges rooms
for(size_t i = 0; i < starts.size(); i++) {
size_t index = (i + offset) % starts.size();
Room cur{starts[index].x, starts[index].y, room_size, room_size};
// if it's out of bounds skip it
if(selected && room_should_exist(cur)) {
if(room_should_exist(cur)) {
$rooms.push_back(cur);
break;
}
}
}
}
@ -165,14 +182,9 @@ namespace maze {
}
}
if($rooms.size() > 0) ensure_doors();
enclose();
}
void Builder::ensure_doors() {
// NEED TO REWRITE
}
void Builder::place_rooms() {
for(auto& room : $rooms) {
for(matrix::rectangle it{$walls, room.x, room.y, room.width, room.height}; it.next();) {
@ -291,6 +303,7 @@ namespace maze {
void Builder::make_doors() {
for(auto room : $rooms) {
// BUG: still makes rooms without doors, so detect if no door added and brute force one in
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();) {

View file

@ -21,7 +21,6 @@ namespace maze {
void clear();
void hunt_and_kill(Point on={1,1});
void place_rooms();
void ensure_doors();
void enclose();
void randomize_rooms(size_t room_size);
void inner_donut(float outer_rad, float inner_rad);

View file

@ -13,7 +13,6 @@
using lighting::LightSource;
struct Room {
size_t x = 0;
size_t y = 0;
@ -22,15 +21,13 @@ struct Room {
bool contains(Point at) {
size_t right = x + width - 1;
size_t left = x;
size_t top = y;
size_t bottom = y + height - 1;
return at.x >= left && at.x <= right && at.y >= top && at.y <= bottom;
return at.x >= x
&& at.x <= x + width -1
&& at.y >= y
&& at.y <= y + height - 1;
}
bool overlaps(Room& other) {
bool overlaps(Room other) {
return
// other left > this right == other too far right
!( other.x > x + width
@ -42,7 +39,7 @@ struct Room {
|| other.y > y + height
// other bottom < this top == too far above
|| other.y + other.width < y);
|| other.y + other.height < y);
}
};

View file

@ -127,14 +127,16 @@ void Raycaster::sprite_casting() {
$level.collision->distance_sorted($sprite_order, {(size_t)$pos_x, (size_t)$pos_y}, RENDER_DISTANCE);
$sprites_to_render.clear();
// BUG: shaders are shared between sprites
// BUG: sprites seem to be shared too? Put a torch on the floor in a room then another to its left and only one is visible at a time.
// after sorting the sprites, do the projection
for(auto& rec : $sprite_order) {
if(!$sprites.contains(rec.entity)) continue;
auto& sprite_texture = $sprites.at(rec.entity);
int texture_width = (float)sprite_texture.frame_size.x;
int texture_height =(float)sprite_texture.frame_size.y;
int texture_width = float(sprite_texture.frame_size.x);
int texture_height = float(sprite_texture.frame_size.y);
int half_height = texture_height / 2;
auto sf_sprite = sprite_texture.sprite;

View file

@ -6,6 +6,8 @@
#include "constants.hpp"
#include "algos/maze.hpp"
#define DUMP 0
using std::string;
using matrix::Matrix;
@ -14,12 +16,12 @@ TEST_CASE("hunt-and-kill", "[mazes]") {
maze::Builder maze(map);
maze.hunt_and_kill();
// maze.dump("BASIC MAZE");
if(DUMP) maze.dump("BASIC MAZE");
maze.randomize_rooms(ROOM_SIZE);
maze.hunt_and_kill();
maze.make_doors();
// maze.dump("ROOM MAZE");
if(DUMP) maze.dump("ROOM MAZE");
REQUIRE(map.$dead_ends.size() > 0);
REQUIRE(map.$rooms.size() > 0);
@ -39,7 +41,7 @@ TEST_CASE("hunt-and-kill box", "[mazes]") {
maze.open_box(6);
maze.make_doors();
if(i == 42) {
if(i == 41 && DUMP) {
maze.dump("INNER BOX");
}
}
@ -52,7 +54,7 @@ TEST_CASE("hunt-and-kill ring", "[mazes]") {
maze.inner_donut(5.5, 3.5);
maze.hunt_and_kill();
// maze.dump("INNER RING");
if(DUMP) maze.dump("INNER RING");
REQUIRE(maze.$rooms.size() == 0);
}
@ -64,7 +66,7 @@ TEST_CASE("hunt-and-kill fissure", "[mazes]") {
maze.divide({3,3}, {19,18});
maze.hunt_and_kill();
// maze.dump("FISSURE MAZE");
if(DUMP) maze.dump("FISSURE MAZE");
REQUIRE(maze.$rooms.size() == 0);
}
@ -77,7 +79,7 @@ TEST_CASE("hunt-and-kill no-dead-ends", "[mazes]") {
maze.remove_dead_ends();
maze.enclose();
// maze.dump("NO DEAD ENDS");
if(DUMP) maze.dump("NO DEAD ENDS");
}
TEST_CASE("hunt-and-kill too much", "[mazes]") {
@ -93,8 +95,8 @@ TEST_CASE("hunt-and-kill too much", "[mazes]") {
maze.hunt_and_kill();
maze.make_doors();
// if(i == 41) {
// maze.dump("COMBINED");
// }
if(i == 41 && DUMP) {
maze.dump("COMBINED");
}
}
}