way better map/maze debug output.

This commit is contained in:
Zed A. Shaw 2026-03-15 00:09:47 -04:00
parent 3394de064c
commit f304538325
8 changed files with 72 additions and 24 deletions

View file

@ -37,7 +37,7 @@ tracy_build:
meson compile -j 10 -C builddir
test: build
./builddir/runtests -d yes
./builddir/runtests -d yes "[map-fail]"
run: build test
ifeq '$(OS)' 'Windows_NT'
@ -60,7 +60,7 @@ clean:
meson compile --clean -C builddir
debug_test: build
gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests
gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests "[map-fail]"
win_installer:
powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp'

View file

@ -18,14 +18,22 @@ namespace matrix {
} else {
print("{:x}<", cell);
}
} else if(cell == WALL_PATH_LIMIT) {
print("# ");
} else if(cell == 0) {
print(". ");
} else if(cell > 15 && cell < 32) {
print("{:x}+", cell - 16);
} else if(cell > 31) {
} else if(cell == DEAD_END_VALUE) {
print("* ");
} else if(cell == DOOR_VALUE) {
print("¦ ");
} else if(cell == 1) {
print("▒▒");
} else if(cell == ROOM_SPACE_VALUE) {
print("\%\%");
} else if(cell == WALL_PATH_LIMIT) {
print("■■");
} else if(cell == 0) {
print(" ");
} else if(cell > 15 && cell < 32) {
print("{:X} ", cell - 16);
} else if(cell > 31) {
print("..");
} else {
print("{:x} ", cell);
}

View file

@ -3,7 +3,7 @@
#include "algos/rand.hpp"
#include "constants.hpp"
#include "algos/maze.hpp"
#include <ranges>
#include <algorithm>
using std::string;
using matrix::Matrix;
@ -111,11 +111,30 @@ namespace maze {
return true;
}
inline size_t room_sweetspot(size_t width, size_t room_size) {
if(width < 20) {
return 4;
} else if(width < 30) {
return (width / room_size / 2);
} if(width < 50) {
return width / room_size;
} else {
return width / 2;
}
}
void Builder::randomize_rooms(size_t room_size) {
std::shuffle($dead_ends.begin(), $dead_ends.end(), Random::GENERATOR);
size_t max_rooms = room_sweetspot($width, room_size);
// use those dead ends to randomly place rooms
for(auto at : $dead_ends) {
// skip 50% of them
if(Random::uniform(0,1) == 0) continue;
// if(Random::uniform(0,1) == 0) continue;
// quit after we've hit the room max threshold
if($rooms.size() > max_rooms) break;
// get the room corners randomized
std::array<Point, 4> starts{{
@ -125,7 +144,6 @@ namespace maze {
{at.x, at.y - room_size + 1} // bottom left
}};
size_t offset = Random::uniform(0, 3);
// BUG: this still accidentally merges rooms
@ -221,7 +239,7 @@ namespace maze {
}
}
void Builder::dump(const std::string& msg) {
void Builder::dump(const std::string& msg, bool path_too) {
auto wall_copy = $walls;
// mark the rooms too
@ -230,7 +248,7 @@ namespace maze {
it.next();)
{
if(wall_copy[it.y][it.x] == 0 && wall_copy[it.y][it.x] != 3) {
wall_copy[it.y][it.x] = WALL_PATH_LIMIT;
wall_copy[it.y][it.x] = ROOM_SPACE_VALUE;
}
}
}
@ -238,11 +256,19 @@ namespace maze {
// mark dead ends
for(auto at : $dead_ends) {
// don't mark dead ends if there's something else there
wall_copy[at.y][at.x] = 32;
wall_copy[at.y][at.x] = DEAD_END_VALUE;
}
for(auto [at, _] : $doors) {
wall_copy[at.y][at.x] = 0xd;
wall_copy[at.y][at.x] = DOOR_VALUE;
}
if(path_too) {
for(matrix::each_cell it{wall_copy}; it.next();) {
if(wall_copy[it.y][it.x] == SPACE_VALUE) {
wall_copy[it.y][it.x] = $paths.$paths[it.y][it.x];
}
}
}
matrix::dump(msg, wall_copy);

View file

@ -1,6 +1,7 @@
#pragma once
#include "algos/matrix.hpp"
#include "game/map.hpp"
#include "algos/pathing.hpp"
#include <functional>
namespace maze {
@ -36,7 +37,7 @@ namespace maze {
void inner_box(size_t outer_size, size_t inner_size);
void divide(Point start, Point end);
void remove_dead_ends();
void dump(const std::string& msg);
void dump(const std::string& msg, bool path_too=false);
void open_box(size_t outer_size);
void add_dead_end(Point at);
bool room_should_exist(Room& room, bool allow_dupes=false);

View file

@ -46,6 +46,9 @@ constexpr int INV_SPACE = 1;
constexpr int WALL_VALUE = 1;
constexpr int SPACE_VALUE = 0;
constexpr int WALL_PATH_LIMIT = 1000;
constexpr int ROOM_SPACE_VALUE = 1001;
constexpr int DOOR_VALUE = 1002;
constexpr int DEAD_END_VALUE = 1003;
constexpr int WALL_LIGHT_LEVEL = 3;
constexpr int WORLDBUILD_DIVISION = 4;
constexpr int WORLDBUILD_SHRINK = 2;
@ -68,8 +71,8 @@ constexpr int COMBAT_UI_Y = RAY_VIEW_HEIGHT;
constexpr int COMBAT_UI_WIDTH = RAY_VIEW_WIDTH ;
constexpr int COMBAT_UI_HEIGHT = SCREEN_HEIGHT - RAY_VIEW_HEIGHT;
constexpr int INITIAL_MAP_W = 17;
constexpr int INITIAL_MAP_H = 15;
constexpr int INITIAL_MAP_W = 25;
constexpr int INITIAL_MAP_H = 25;
constexpr float DEFAULT_ROTATE=0.25f;

View file

@ -12,8 +12,8 @@ using std::shared_ptr, std::make_shared;
using namespace components;
struct LevelScaling {
int map_width=20;
int map_height=20;
int map_width=INITIAL_MAP_W;
int map_height=INITIAL_MAP_H;
};
namespace GameDB {

View file

@ -52,8 +52,18 @@ void WorldBuilder::generate_map() {
]
)"_json;
int i = 0;
for(; i < 10; i++) {
auto [maze, valid] = maze::script($map, script);
dbc::check(valid, "invalid maze");
if(valid) {
break;
} else {
maze.dump(fmt::format("FAILED width={}", $map.width()), true);
}
}
dbc::check(i < 10, "failed to find a valid map after 10 attempts");
$map.init_tiles();
stylize_rooms();

View file

@ -38,7 +38,7 @@ TEST_CASE("camera control", "[map]") {
TEST_CASE("map placement test", "[map-fail]") {
GameDB::init();
for(int i = 0; i < 5; i++) {
for(int i = 0; i < 20; i++) {
auto& level = GameDB::create_level();
for(size_t rnum = 0; rnum < level.map->room_count(); rnum++) {