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