in procgen/src/mazegen.cpp [213:290]
void MazeGen::generate_maze_with_doors(int num_doors) {
generate_maze();
std::vector<int> forks;
std::vector<int> adj_space;
std::vector<int> adj_wall;
for (int i = 0; i < array_dim * array_dim; i++) {
if (get_obj(i) == SPACE) {
get_neighbors(i, SPACE, adj_space);
get_neighbors(i, WALL_OBJ, adj_wall);
if (adj_space.size() > 2) {
forks.push_back(i);
}
}
}
std::vector<int> chosen = rand_gen->choose_n(forks, num_doors);
num_doors = (int)(chosen.size());
for (int i : chosen) {
grid.set_index(i, DOOR_OBJ);
}
int agent_cell;
{
std::vector<int> space_cells = filter_cells(SPACE);
std::vector<int> door_neighbors;
// don't let the agent spawn next to a door, as there might not be room
// for the key
do {
agent_cell = rand_gen->choose_one(space_cells);
door_neighbors.clear();
get_neighbors(agent_cell, DOOR_OBJ, door_neighbors);
} while (door_neighbors.size() > 0);
grid.set_index(agent_cell, AGENT_OBJ);
}
std::set<int> s0;
s0.insert(agent_cell);
for (int door_num = 0; door_num < num_doors + 1; door_num++) {
std::set<int> s1;
int found_door = -1;
if (door_num < num_doors) {
found_door = expand_to_type(s0, s1, DOOR_OBJ);
grid.set_index(found_door, DOOR_OBJ + door_num + 1);
s0.insert(s1.begin(), s1.end());
}
expand_to_type(s0, s1, -999);
std::vector<int> space_cells;
for (int x : s1) {
space_cells.push_back(x);
}
fassert(space_cells.size() > 0);
int key_cell = rand_gen->choose_one(space_cells);
grid.set_index(key_cell, door_num == num_doors
? EXIT_OBJ
: (KEY_OBJ + door_num + 1));
s0.insert(s1.begin(), s1.end());
if (found_door >= 0) {
s0.insert(found_door);
}
}
}