<?php

/**
 * ランダムに関連する機能を提供するUtilクラス
 */
class RandomUtil
{
    private const LOTTERY_RANGE_MIN = 1;
    private const LOTTERY_RANGE_MAX = 100;

    /**
     * 確率による抽選
     *
     * @param int $rate 当選率
     * @return bool true:当選, false: 落選
     */
    public static function lottery(int $rate): bool
    {
        return rand(self::LOTTERY_RANGE_MIN, self::LOTTERY_RANGE_MAX) <= $rate;
    }

    /**
     * 連想配列に設定された重みを元に抽選し、当選した重みのキーを返却
     *
     * @param array $weights 任意のキーとその排出率となる重みを設定した値の配列
     * @return int|string
     */
    public static function weightLottery(array $weights): int|string
    {
        $totalWeight = array_sum(array_values($weights));
        $hitWeight = rand(0, $totalWeight);

        $cumulativeWeight = 0;
        foreach ($weights as $key => $weight) {
            $cumulativeWeight += $weight;
            if ($cumulativeWeight >= $hitWeight) {
                return $key;
            }
        }

        throw new RuntimeException('重みの設定が不正です');
    }
}