in procgen/src/games/ninja.cpp [195:305]
void generate_coin_to_the_right(int difficulty) {
int min_gap = difficulty - 1;
int min_plat_w = 1;
int inc_dy = 4;
if (options.distribution_mode == EasyMode) {
min_gap -= 1;
if (min_gap < 0)
min_gap = 0;
min_plat_w = 3;
inc_dy = 2;
}
float bomb_prob = .25 * (difficulty - 1);
int max_gap_inc = difficulty == 1 ? 1 : 2;
int num_sections = rand_gen.randn(difficulty) + difficulty;
int start_x = 5;
int curr_x = start_x;
int curr_y = main_height / 2;
int min_y = curr_y;
int w = main_width;
float _max_dy = max_jump * max_jump / (2 * gravity);
int max_dy = (_max_dy - .5);
int prev_x;
int prev_y;
fill_ground_block(0, 0, start_x, curr_y);
fill_elem(0, curr_y + 8, start_x, main_height - curr_y - 8, WALL_MID);
for (int i = 0; i < num_sections; i++) {
prev_x = curr_x;
prev_y = curr_y;
int num_edges = rand_gen.randn(2) + 1;
int max_y = -1;
int last_edge_y = -1;
for (int j = 0; j < num_edges; j++) {
curr_x = prev_x + j;
if (curr_x + 15 >= w) {
break;
}
curr_y = prev_y;
int dy = rand_gen.randn(inc_dy) + 1 + int(difficulty / 3);
if (dy > max_dy) {
dy = max_dy;
}
if (curr_y >= main_height - 15) {
dy *= -1;
} else if (curr_y >= 5 && rand_gen.rand01() < .4) {
dy *= -1;
}
curr_y += dy;
if (curr_y < 3) {
curr_y = 3;
}
if (abs(curr_y - last_edge_y) <= 1) {
curr_y = last_edge_y + 2;
}
int dx = min_plat_w + rand_gen.randn(3);
fill_ground_block(curr_x, curr_y - 1, dx, 1);
curr_x += dx;
curr_x += min_gap + rand_gen.randn(max_gap_inc + 1);
if (curr_y > max_y)
max_y = curr_y;
if (curr_y < min_y)
min_y = curr_y;
last_edge_y = curr_y;
}
if (rand_gen.rand01() < bomb_prob) {
set_obj(rand_gen.randn(curr_x - prev_x + 1) + prev_x, max_y + 2, BOMB);
}
int ceiling_height = 11;
int ceiling_start = max_y - 1 + ceiling_height;
fill_ground_block(prev_x, ceiling_start, curr_x - prev_x, main_height - ceiling_start);
}
auto ent = add_entity(curr_x + .5, curr_y + .5, 0, 0, .5, GOAL);
choose_random_theme(ent);
fill_ground_block(curr_x, curr_y - 1, 1, 1);
fill_elem(curr_x, curr_y + 6, 1, main_height - curr_y - 6, WALL_MID);
int fire_y = min_y - 2;
if (fire_y < 1)
fire_y = 1;
fill_ground_block(start_x, 0, main_width - start_x, fire_y);
fill_elem(start_x, fire_y, main_width - start_x, 1, FIRE);
fill_elem(curr_x + 1, 0, main_width - curr_x - 1, main_height, WALL_MID);
}