#include #include #include "backend/Dungeon.h" #include "backend/RNG.h" #include "backend/print.h" #include "backend/Exception.h" #include "rl.h" #include "generate_dungeon.h" #include "GameData.h" using namespace std; static vector shuffled_directions() { vector out = { NORTH, EAST, SOUTH, WEST }; shuffle(out.begin(), out.end(), RNG::get_engine()); return out; } unique_ptr generate_dungeon() { unique_ptr dungeon = make_unique(); GameData & gd = GameData::get_instance(); lprtf("Hoeveel locaties moet de kerker hebben?\n"); unsigned location_count = 1; try { string filename = rl(); location_count = stoul(filename); } catch (...) { throw Exception("geen geldig aantal ingevoerd"); } if (location_count < 1) throw Exception("meer dan 1 locatie nodig"); vector locations = gd.random_locations(location_count); struct TempData { Location * location; int edges[4] = { -1, -1, -1, -1 }; }; vector temp_map; temp_map.resize(location_count); size_t index = 0; RNG & rng = RNG::get(); for (const string & name : locations) { Location * location = gd.create_location(name); if (index % 3 == 0) { location->add_enemy(gd.create_enemy(gd.random_enemy())); } for (const string & object : gd.random_objects(rng.rand_int(Range { 0, 3 }))) { location->add_visible_object(gd.create_object(object)); } for (const string & object : gd.random_objects(rng.rand_int(Range { 0, 2 }))) { location->add_hidden_object(gd.create_object(object)); } auto & temp = temp_map[index]; temp.location = location; for (Direction direction : shuffled_directions()) { // skip over already connected edges if (temp.edges[direction] >= 0) continue; // find another random location that is NOT here int connection = rng.rand_int(location_count - 1); if (connection == index) connection++; // make a bidirectional connection temp.edges[direction] = connection; temp_map[temp.edges[direction]].edges[-direction] = index; if (rng.rand_double() < 0.8) break; } dungeon->add_location(location); index++; } for (auto & temp : temp_map) { for (Direction direction : DIRECTIONS) { unsigned id = temp.edges[direction]; if (temp.edges[direction] < 0) continue; temp.location->set_exit(direction, temp_map[id].location); } } return dungeon; }