diff --git a/src/Mapgen.cpp b/src/Mapgen.cpp index 5649509..a4e7aea 100644 --- a/src/Mapgen.cpp +++ b/src/Mapgen.cpp @@ -14,6 +14,7 @@ struct Room { const char walltile = '#'; const char floortile = '.'; const char doortile = '+'; +const char testtile = ' '; bool aabb(Room &a, Room &b) { return a.pos.x <= b.pos.x + b.size.x && a.pos.x + a.size.x >= b.pos.x && @@ -81,7 +82,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) { // Room placement std::vector rooms; - for (int i = 0; i < sqrt(width*height) * 6; i++) { + for (int i = 0; i < sqrt(width*height); i++) { Room room; room.size = vec2i(rng.get_int(6, 12), rng.get_int(6, 12)); room.pos = vec2i(rng.get_int(width - room.size.x), rng.get_int(height - room.size.y)); @@ -136,7 +137,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) { if (x == 0) { dx = -1; } - else if (x == r.size.x) { + else if (x == r.size.x-1) { dx = 1; } @@ -144,7 +145,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) { if (y == 0) { dy = -1; } - else if (y == r.size.y) { + else if (y == r.size.y-1) { dy = 1; } @@ -163,14 +164,22 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) { if (potential_doors.empty()) continue; // Pick up to 3 spots and place doorss - int doors_amount = potential_doors.size() < 3 ? potential_doors.size() : 3; - doors_amount = rng.get_int(1, doors_amount); + int doors_amount = potential_doors.size() < 3 ? potential_doors.size() : 4; + doors_amount = rng.get_int(2, doors_amount); for (int i = 0; i < doors_amount; i++) { + //for (int i = 0; i < potential_doors.size(); i++) { + if (potential_doors.empty()) break; + int r = rng.get_int(potential_doors.size()-1); vec2i pos = potential_doors.at(r); map.set_tile(pos.x, pos.y, doortile); potential_doors.erase(r + potential_doors.begin()); + for (int j = potential_doors.size() - 1; j >= 0; j--) { + if ((pos - potential_doors[j]).dist() <= 4) { + potential_doors.erase(j + potential_doors.begin()); + } + } } //*/ } @@ -191,34 +200,61 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height) { } } } - int pass_amount = sqrt(width*height)*2; + int pass_amount = 100; for (int pass = 0; pass < pass_amount; pass++) { if (dead_ends.empty()) break; std::vector new_dead_ends; for (vec2i pos : dead_ends) { - map.set_tile(pos.x, pos.y, walltile); std::vector neigh { vec2i(pos.x + 1, pos.y), vec2i(pos.x, pos.y + 1), vec2i(pos.x - 1, pos.y), vec2i(pos.x, pos.y - 1) }; - for (int i = neigh.size() - 1; i >= 0; i--) { - vec2i p = neigh[i]; - if (map.get_tile(p.x, p.y) == walltile) { - neigh.erase(neigh.begin() + i); + int count = 0; + vec2i next; + for (vec2i n : neigh) { + if (map.get_tile(n.x, n.y) == walltile) { + continue; + } + else { + count++; + next = n; } } - if (neigh.size() == 1) { - std::vector neigh2{ vec2i(pos.x + 1, pos.y), vec2i(pos.x, pos.y + 1), vec2i(pos.x - 1, pos.y), vec2i(pos.x, pos.y - 1) }; - int count = 0; - for (vec2i pos : neigh2) { - if (map.get_tile(pos.x, pos.y) == walltile) { - count++; - } - } - if (count >= neigh2.size() - 1) { - new_dead_ends.emplace_back(vec2i(pos.x, pos.y)); - } + if (count == 1) { + map.set_tile(pos.x, pos.y, walltile); + new_dead_ends.emplace_back(next); + } + else if (count == 0) { + map.set_tile(pos.x, pos.y, walltile); } } dead_ends = new_dead_ends; } - + + /* flood-fill the map to see that you can actually reach everywhere + bool started = false; + for (int x = 0; x < map.get_width(); x++) { + for (int y = 0; y < map.get_height(); y++) { + if (map.get_tile(x,y) == floortile) { + std::vector stack{vec2i(x,y)}; + map.set_tile(x, y, testtile); + while (!stack.empty()) { + vec2i pos = stack.back(); + stack.pop_back(); + + auto neigh = map.get_neighbours(pos.x, pos.y); + for (vec2i n : neigh) { + char tile = map.get_tile(n.x, n.y); + if (tile == floortile || tile == doortile) { + map.set_tile(pos.x, pos.y, testtile); + stack.emplace_back(n); + } + } + } + + started = true; + break; + } + } + if (started) break; + } + //*/ return map; }