void MazeGen::generate_maze_with_doors()

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);
        }
    }
}