简单实用的 PHP 中奖概率抽奖现实

我们在PHP开发过程中,常常会用到概率抽奖的问题。比如大转盘抽奖、抽微信红包、九宫格抽奖、刮刮卡。其实只要是关于概率的问题,全都可以用下面这个 抽奖核心方法 类即可现实。虽然注释我写的已经足够详细,但是为了小白也能看懂,后面我将会做更详细的解释。

/*
 * 抽奖核心方法
 */
function raffleCore($configArray) // (1)
{
    // 实例化一个空数组,用来存放抽奖核心信息。
    $coreArray = [];
    // 把配置文件中的"id(奖品编号)"和"chance(奖品中奖概率)"两项目单独合并为一个数组。
    foreach ($configArray as $key => $value) {
        $coreArray[$value['id']] = $value['chance'];
    }
    // 实例化一个空字符串,用来存放中奖的奖品编号。
    $result = '';
    // 概率数组的总概率
    $coreSum = array_sum($coreArray);
    // 如果总概率为0,则直接返回。(2)
    if ($coreSum === 0) {
        return null;
    }
    // 概率数组循环
    foreach ($coreArray as $id => $chance) {
        // (3)
        $coreNumber = mt_rand(1, $coreSum); // 生成一个1到总概率之间的随机数
        if ($coreNumber <= $chance) {
            $result = $id; // 如果随机数小于当前的概率数,则直接返回当前id。
            break;
        } else { // 否则从总概率中剔除掉当前的概率,继续循环。
            $coreSum = $coreSum - $chance;
        }
    }
    unset($coreArray); //$coreArr数组使用完,销毁。
    return $result; // 返回中奖的奖品编号。
}

注释(1)

$configArray 变量为传入的奖品配置,举个例子。

$configArray = [
    ["id" => 0, "title" => "1元红包", "chance" => 5, "number" => 3000],
    ["id" => 1, "title" => "2元红包", "chance" => 3, "number" => 1500],
    ["id" => 2, "title" => "5元红包", "chance" => 2, "number" => 500],
];

其中 idchance 是必要的。 id 是返回时的商品编号。建议 id 的编号从0开始,这样商品编号就能与数组下标一至,方便获取商品信息。 chance 是商品的中奖概率。通过上面的 抽奖核心方法 就能知道,这个是必须的。 其他的参数可以根据具体的项目添加,我在这个地方用到的还有 titlenumber 两个参数,分别为 标题奖品总数

注释(2)

上面的配置参数在传到 抽奖核心方法 前往往会先进行判断,当前的奖品是否已经达到了 奖品总数 的上限,如果已经达到上限,则把概率设置为 0,这样当前奖品就不参与抽奖。 当所有奖品的中奖概率都为 0 时,则直接返回 null 不进行抽奖操作。

注释(3)

抽奖核心方法 的原理,举个例子。 根据上面的配置,概率为 5:3:2总概率10 ,从 110 中随机产生一个数 $coreNumber,如果 $coreNumber 小于 当前奖品概率 5 ,则直接返回当前 id。否则从总概率中剔除掉 当前奖品概率,继续循环。

第一次循环时 当前奖品概率数id0 的商品的概率 5 ,从 110 三个奖品的概率总和 中随机产生一个数 $coreNumber, 那么 $coreNumber 小于等于 当前奖品概率数 5 的概率为 50% ,这与我们期待的概率是吻合的,所以直接返回当前 id 。如果$coreNumber 大于 当前奖品概率数 5 ,则认为中的是 id1 或者 id2 的奖品,进入下一次循环。

第二次循环时 当前奖品概率数id1 的商品的概率 3 ,从 15 总概率减去上一个奖品的概率 中随机产生一个数 $coreNumber,那么 $coreNumber 小于等于 当前奖品概率数 3 的概率为 60%,这与我们期待的概率是吻合的,所以直接返回当前 id 。如果$coreNumber 大于 当前奖品概率数 5 ,则认为中的是 id2 的奖品,进入下一次循环。

第三次循环时 当前奖品概率数id2 的商品的概率 2 ,从 12 总概率减去上一个奖品的概率 中随机产生一个数 $coreNumber,那么 $coreNumber 小于等于 当前奖品概率数 2 的概率为 100%,所以直接返回当前 id

全部评论(0)
必填
必填,不公开
我信任你,不会填写广告链接
收起