void generate_platforms()

in procgen/src/games/climber.cpp [171:228]


    void generate_platforms() {
        int difficulty = rand_gen.randn(3);
        int min_platforms = difficulty * difficulty + 1;
        int max_platforms = (difficulty + 1) * (difficulty + 1) + 1;
        int num_platforms = rand_gen.randn(max_platforms - min_platforms + 1) + min_platforms;

        coin_quota = 0;
        coins_collected = 0;

        int curr_x = rand_gen.randn(main_width - 4) + 2;
        int curr_y = 0;

        int margin_x = 3;
        float enemy_prob = options.distribution_mode == EasyMode ? .2 : .5;

        for (int i = 0; i < num_platforms; i++) {
            int delta_y = choose_delta_y();

            // only spawn enemies that won't be trapped in tight spaces
            bool can_spawn_enemy = (curr_x >= margin_x) && (curr_x <= main_width - margin_x);

            if (can_spawn_enemy && (rand_gen.rand01() < enemy_prob)) {
                auto ent = add_entity(curr_x + .5, curr_y + rand_gen.randn(2) + 2 + .5, .15 * (rand_gen.randn(2) * 2 - 1), 0, .5, ENEMY);
                ent->image_type = ENEMY1;
                ent->smart_step = true;
                ent->climber_spawn_x = curr_x + .5;
                match_aspect_ratio(ent);
            }

            curr_y += delta_y;
            int plat_len = 2 + rand_gen.randn(10);

            int vx = rand_gen.randn(2) * 2 - 1;
            if (curr_x < margin_x)
                vx = 1;
            if (curr_x > main_width - margin_x)
                vx = -1;

            std::vector<int> candidates;

            for (int j = 0; j < plat_len; j++) {
                int nx = curr_x + (j + 1) * vx;
                if (nx <= 0 || nx >= main_width - 1)
                    break;
                candidates.push_back(nx);
                set_obj(nx, curr_y, WALL_TOP);
            }

            if (rand_gen.rand01() < .5 || i == num_platforms - 1) {
                int coin_x = rand_gen.choose_one(candidates);
                add_entity(coin_x + .5, curr_y + 1.5, 0, 0, 0.3f, COIN);
                coin_quota += 1;
            }

            int next_x = rand_gen.choose_one(candidates);
            curr_x = next_x;
        }
    }