Add a terrible maze generation algorithm to test if a maze style map looks/feels better. The walls are disabled so you can walk around.
parent
6cbfcf993e
commit
7a0b2f988d
@ -0,0 +1,145 @@ |
||||
#include <fmt/core.h> |
||||
#include <string> |
||||
#include "rand.hpp" |
||||
#include "constants.hpp" |
||||
#include "maze.hpp" |
||||
|
||||
using std::string; |
||||
using matrix::Matrix; |
||||
|
||||
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 split_dir(size_t iDim, size_t jDim) { |
||||
if(iDim < jDim) { |
||||
return false; |
||||
} else if(jDim < iDim) { |
||||
return true; |
||||
} else { |
||||
return Random::uniform(0, 1); |
||||
} |
||||
} |
||||
|
||||
inline bool good_hole(Matrix &map, size_t split, size_t hole, bool horiz) { |
||||
if(hole % 2 == 0) return false; |
||||
|
||||
size_t j = horiz ? split : hole; |
||||
size_t i = horiz ? hole : split; |
||||
if(map[j][i] == WALL_PATH_LIMIT) return false; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void divide(Matrix& map, std::vector<Room> &rooms, |
||||
Point iCoords, Point jCoords, bool horizontal) { |
||||
int iDim = iCoords.y - iCoords.x; |
||||
int jDim = jCoords.y - jCoords.x; |
||||
bool punch_room = false; |
||||
|
||||
if(iDim <= 0 || jDim <= 0) { |
||||
return; |
||||
} else if(iDim <= 2 && jDim <= 2) { |
||||
fmt::println("MADE ROOM! {},{}; {},{}", |
||||
iCoords.x, iCoords.y, jCoords.x, jCoords.y); |
||||
punch_room = true; |
||||
} |
||||
|
||||
if(horizontal) { |
||||
size_t split = 0; |
||||
do { |
||||
split = rand(iCoords.x, iCoords.x + iDim + 1); |
||||
} while(split % 2); |
||||
|
||||
size_t hole = 0; |
||||
do { |
||||
hole = rand(jCoords.x, jCoords.x + jDim +1); |
||||
} while(good_hole(map, split, hole, horizontal)); |
||||
|
||||
for(size_t j = jCoords.x; j <= jCoords.y; j++) { |
||||
if(j != hole) { |
||||
map[split][j] = WALL_PATH_LIMIT; |
||||
} |
||||
} |
||||
|
||||
divide(map, rooms, |
||||
{iCoords.x, size_t(split - 1)}, |
||||
jCoords, |
||||
split_dir(split - iCoords.x - 1, jDim)); |
||||
|
||||
divide(map, rooms, |
||||
{size_t(split + 1), iCoords.y}, |
||||
jCoords, |
||||
split_dir(iCoords.x - split - 1, jDim)); |
||||
} else { |
||||
size_t split = 0; |
||||
do { |
||||
split = rand(jCoords.x, jCoords.x + jDim + 1); |
||||
} while(split % 2); |
||||
|
||||
size_t hole = 0; |
||||
do { |
||||
hole = rand(iCoords.x, iCoords.x + iDim + 1); |
||||
} while(good_hole(map, split, hole, horizontal)); |
||||
|
||||
for(size_t i = iCoords.x; i <= iCoords.y; i++) { |
||||
if(i != hole) { |
||||
map[i][split] = WALL_PATH_LIMIT; |
||||
} |
||||
} |
||||
|
||||
divide(map, rooms, |
||||
iCoords, |
||||
{jCoords.x, size_t(split - 1)}, |
||||
split_dir(iDim, split - jCoords.x - 1)); |
||||
|
||||
divide(map, rooms, |
||||
iCoords, |
||||
{size_t(split + 1), jCoords.y}, |
||||
Random::uniform(0, 1)); |
||||
} |
||||
|
||||
if(punch_room) { |
||||
for(size_t j = jCoords.x; j <= jCoords.y; j++) { |
||||
for(size_t i = iCoords.x; i <= iCoords.y; i++) { |
||||
map[j][i] = 0; |
||||
} |
||||
} |
||||
|
||||
Room room{iCoords.x, jCoords.x, iCoords.y - iCoords.x + 1, jCoords.y - jCoords.x + 1}; |
||||
|
||||
for(auto r : rooms) { |
||||
if(r.x == room.x && r.y == room.y) { |
||||
return; |
||||
} |
||||
} |
||||
|
||||
rooms.push_back(room); |
||||
} |
||||
} |
||||
|
||||
|
||||
void maze::recursive_div(Matrix& map, std::vector<Room>& rooms) { |
||||
size_t width = matrix::width(map); |
||||
size_t height = matrix::height(map); |
||||
|
||||
for(size_t i = 0; i < height; i++) { |
||||
for(size_t j = 0; j < width; j++) { |
||||
int val = (i == 0 || |
||||
j == 0 || |
||||
i == height - 1 || |
||||
j == width - 1); |
||||
|
||||
map[i][j] = val == 1 ? WALL_PATH_LIMIT : 0; |
||||
} |
||||
} |
||||
|
||||
divide(map, rooms, {1, height - 2}, {1, width - 2}, split_dir(1, 1)); |
||||
} |
@ -0,0 +1,7 @@ |
||||
#pragma once |
||||
#include "matrix.hpp" |
||||
#include "map.hpp" |
||||
|
||||
namespace maze { |
||||
void recursive_div(matrix::Matrix& map, std::vector<Room>& rooms); |
||||
} |
@ -0,0 +1,23 @@ |
||||
#include <catch2/catch_test_macros.hpp> |
||||
#include <fmt/core.h> |
||||
#include <string> |
||||
#include "matrix.hpp" |
||||
#include "rand.hpp" |
||||
#include "constants.hpp" |
||||
#include "maze.hpp" |
||||
|
||||
using std::string; |
||||
using matrix::Matrix; |
||||
|
||||
TEST_CASE("simple maze first attempt", "[maze-gen]") { |
||||
auto map = matrix::make(21, 21); |
||||
std::vector<Room> rooms; |
||||
|
||||
maze::recursive_div(map, rooms); |
||||
matrix::dump("MAZE?", map); |
||||
|
||||
for(auto& room : rooms) { |
||||
fmt::println("room: {},{}; {},{}", |
||||
room.x, room.y, room.width, room.height); |
||||
} |
||||
} |
Loading…
Reference in new issue