Skip to content

Commit

Permalink
maze floors
Browse files Browse the repository at this point in the history
  • Loading branch information
malytomas committed Jul 26, 2023
1 parent 3b417c0 commit 5bdfe16
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 21 deletions.
4 changes: 2 additions & 2 deletions sources/dnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using namespace cage;

enum class TileEnum
enum class TileEnum : uint8
{
// free
Empty,
Expand All @@ -22,7 +22,7 @@ enum class TileEnum
Outside,
};

enum class OccupancyEnum
enum class OccupancyEnum : uint8
{
Free, // empty tiles, walkable decorations
Prop, // doors, chests, monsters
Expand Down
37 changes: 24 additions & 13 deletions sources/export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,19 @@ namespace
res += "@";
break;
case TileEnum::Wall:
{
uint32 neighbors = 0;
if (x > 0 && f.tile(x - 1, y) == TileEnum::Wall)
neighbors += 1; // left
if (y > 0 && f.tile(x, y - 1) == TileEnum::Wall)
neighbors += 2; // top
if (x + 1 < f.width && f.tile(x + 1, y) == TileEnum::Wall)
neighbors += 4; // right
if (y + 1 < f.height && f.tile(x, y + 1) == TileEnum::Wall)
neighbors += 8; // bottom
res += connectedWall(neighbors);
}
break;
//{
// uint32 neighbors = 0;
// if (x > 0 && f.tile(x - 1, y) == TileEnum::Wall)
// neighbors += 1; // left
// if (y > 0 && f.tile(x, y - 1) == TileEnum::Wall)
// neighbors += 2; // top
// if (x + 1 < f.width && f.tile(x + 1, y) == TileEnum::Wall)
// neighbors += 4; // right
// if (y + 1 < f.height && f.tile(x, y + 1) == TileEnum::Wall)
// neighbors += 8; // bottom
// res += connectedWall(neighbors);
// break;
//}
case TileEnum::Outside:
res += uni(u8"\u2588");
break;
Expand All @@ -108,6 +108,14 @@ namespace
}
return res;
}

uint32 countTiles(const Floor &f, TileEnum tile)
{
uint32 cnt = 0;
for (auto it : f.tiles)
cnt += it == tile;
return cnt;
}
}

Export exportFloor(const Floor &floor)
Expand Down Expand Up @@ -165,6 +173,9 @@ void exportDungeon(PointerRange<const Floor> floors)
const Export e = exportFloor(f);
html->writeLine(Stringizer() + "<h2>Floor " + f.level + "</h2>");
html->write(e.html);
if (isLevelBoss(f.level))
html->writeLine(Stringizer() + "boss level: " + levelToBossIndex(f.level) + "<br>");
html->writeLine(Stringizer() + "monsters: " + countTiles(f, TileEnum::Monster) + "<br>");
html->writeLine("<hr>");
json->write(e.json);
}
Expand Down
72 changes: 66 additions & 6 deletions sources/floor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ namespace

Vec2i findAny(const Floor &f, TileEnum c)
{
std::vector<Vec2i> tmp;
tmp.reserve(f.width * f.height);
uint32 cnt = 0;
for (TileEnum a : f.tiles)
cnt += a == c;
if (cnt == 0)
return Vec2i(-1);
cnt = randomRange(0u, cnt);
for (uint32 i = 0; i < f.tiles.size(); i++)
if (f.tiles[i] == c)
tmp.push_back(Vec2i(i % f.width, i / f.width));
if (tmp.empty())
return Vec2i(-1);
return tmp[randomRange(0u, numeric_cast<uint32>(tmp.size()))];
if (cnt-- == 0)
return Vec2i(i % f.width, i / f.width);
return Vec2i(-1);
}

Vec2i findNearest(const Floor &f, Vec2i s, TileEnum c)
Expand Down Expand Up @@ -286,6 +289,61 @@ namespace
}
}

void generateMazeFloor(Floor &f)
{
const uint32 w = randomRange(f.level + 20, f.level * 2 + 30);
const uint32 h = randomRange(f.level / 3 + 15, f.level / 2 + 20);
floorResize(f, Vec2i(w, h));

{ // carve out the maze
f.tile(w / 2, h / 2) = TileEnum::Empty;
const uint32 attempts = w * h * 20;
for (uint32 i = 0; i < attempts; i++)
{
const Vec2i p = findAny(f, TileEnum::Empty);
if (p[0] < 2 || p[0] > w - 3 || p[1] < 2 || p[1] > h - 3)
continue;
static constexpr Vec2i ns[4] = {
Vec2i(-1, 0),
Vec2i(+1, 0),
Vec2i(0, -1),
Vec2i(0, +1),
};
const Vec2i c = p + ns[randomRange(0, 4)];
if (f.tile(c) != TileEnum::Outside)
continue;
uint32 en = 0;
for (Vec2i n : ns)
en += f.tile(c + n) == TileEnum::Empty;
if (en != 1)
continue;
f.tile(c) = TileEnum::Empty;
}
}

{ // find outline walls
findOutlineWalls(f);
}

{ // place stairs
const Vec2i a = findAny(f, TileEnum::Empty);
const Vec2i b = findFarthest(f, a, TileEnum::Empty);
f.tile(a) = TileEnum::Stairs;
f.tile(b) = TileEnum::Spawn;
}

{ // place some monsters
const uint32 cnt = randomRange(f.level / 6, f.level / 3 + 1) + 1;
for (uint32 i = 0; i < cnt; i++)
{
const Vec2i p = findAny(f, TileEnum::Empty);
if (p == Vec2i(-1))
break;
f.tile(p) = TileEnum::Monster;
}
}
}

void generateGenericFloor(Floor &f)
{
const uint32 w = randomRange(f.level + 20, f.level * 2 + 30);
Expand Down Expand Up @@ -400,6 +458,8 @@ Floor generateFloor(uint32 level)
generateShopFloor(f);
else if (isLevelBoss(level))
generateBossFloor(f);
else if (level > 10 && level < 90 && randomChance() < 0.05)
generateMazeFloor(f);
else
generateGenericFloor(f);
cutoutFloor(f);
Expand Down

0 comments on commit 5bdfe16

Please sign in to comment.