void game_reset()

in procgen/src/games/jumper.cpp [221:379]


    void game_reset() override {
        if (options.distribution_mode == EasyMode) {
            visibility = 12;
            compass_dim = 3;
        } else {
            visibility = 16;
            compass_dim = 2;
        }

        if (options.distribution_mode == MemoryMode) {
            timeout = 2000;
        }

        BasicAbstractGame::game_reset();

        out_of_bounds_object = WALL_OBJ;

        wall_theme = rand_gen.randn(NUM_WALL_THEMES);
        jump_count = 0;
        jump_delta = 0;
        jump_time = 0;
        has_support = false;
        facing_right = true;

        int maze_dim = main_width / MAZE_SCALE;

        std::shared_ptr<MazeGen> maze_gen(new MazeGen(&rand_gen, maze_dim));
        maze_gen->generate_maze_no_dead_ends();

        for (int i = 0; i < grid_size; i++) {
            int obj = maze_gen->grid.get((i % main_width) / MAZE_SCALE + 1, (i / main_width) / MAZE_SCALE + 1);

            float prob = obj == WALL_OBJ ? .8 : .2;
            if (rand_gen.rand01() < prob) {
                set_obj(i, WALL_OBJ);
            } else {
                set_obj(i, SPACE);
            }
        }

        for (int iteration = 0; iteration < 2; iteration++) {
            room_manager->update();
        }

        // add border cells. needed for helping with solvability and proper rendering of bottommost floor tiles
        for (int i = 0; i < main_width; i++) {
            set_obj(i, 0, CAVEWALL);
            set_obj(i, main_height - 1, CAVEWALL);
        }

        for (int i = 0; i < main_height; i++) {
            set_obj(0, i, CAVEWALL);
            set_obj(main_width - 1, i, CAVEWALL);
        }

        std::set<int> best_room;
        room_manager->find_best_room(best_room);
        fassert(best_room.size() > 0);

        for (int i = 0; i < grid_size; i++) {
            set_obj(i, CAVEWALL);
        }

        std::vector<int> free_cells;

        for (int i : best_room) {
            set_obj(i, SPACE);
            free_cells.push_back(i);
        }

        int goal_cell = rand_gen.choose_one(free_cells);

        std::vector<int> agent_candidates;

        for (int i = 0; i < grid_size; i++) {
            int x = i % main_width;
            int y = i / main_width;

            if (is_space_on_ground(x, y)) {
                agent_candidates.push_back(i);
            }
        }

        int agent_cell = rand_gen.choose_one(agent_candidates);

        std::vector<int> goal_path;
        room_manager->find_path(agent_cell, goal_cell, goal_path);

        bool should_prune = options.distribution_mode != MemoryMode;

        if (should_prune) {
            std::set<int> wide_path;
            wide_path.insert(goal_path.begin(), goal_path.end());
            room_manager->expand_room(wide_path, 4);

            for (int i = 0; i < grid_size; i++) {
                set_obj(i, CAVEWALL);
            }

            for (int i : wide_path) {
                set_obj(i, SPACE);
            }
        }

        goal = spawn_entity_at_idx(goal_cell, .5, GOAL);
        float spike_prob = options.distribution_mode == MemoryMode ? 0 : .2;

        for (int i = 0; i < grid_size; i++) {
            int x = i % main_width;
            int y = i / main_width;

            if (is_space_on_ground(x, y) && (is_space_on_ground(x - 1, y) && is_space_on_ground(x + 1, y))) {
                if (rand_gen.rand01() < spike_prob) {
                    set_obj(x, y, SPIKE);
                }
            }
        }

        // We prevent log vertical walls to improve solvability
        for (int i = 0; i < grid_size; i++) {
            int x = i % main_width;
            int y = i / main_width;

            if (is_left_wall(x, y) && is_left_wall(x, y + 1) && is_left_wall(x, y + 2)) {
                set_obj(x, y + rand_gen.randn(3), SPACE);
            }

            if (is_right_wall(x, y) && is_right_wall(x, y + 1) && is_right_wall(x, y + 2)) {
                set_obj(x, y + rand_gen.randn(3), SPACE);
            }
        }

        agent->x = (agent_cell % main_width) + .5;
        agent->y = (agent_cell / main_width) + agent->ry;

        std::vector<int> spike_cells = get_cells_with_type(SPIKE);

        for (int spike_cell : spike_cells) {
            set_obj(spike_cell, SPACE);
            float spike_ry = 0.4f;
            float spike_rx = 0.23f;

            add_entity_rxy((spike_cell % main_width) + .5, (spike_cell / main_width) + spike_ry, 0, 0, spike_rx, spike_ry, SPIKE);
        }

        for (int i = 0; i < grid_size; i++) {
            int x = i % main_width;
            int y = i / main_width;

            if (is_top_wall(x, y)) {
                set_obj(x, y, CAVEWALL_TOP);
            }
        }

        agent->rx = 0.254f;
        agent->ry = 0.4f;

        out_of_bounds_object = CAVEWALL;
    }