PHP实现自定义中奖和概率算法

最近玩《QQ飞车手游》,出了一款点券A车,但需要用抽奖券抽奖,很是激动,于是抽了几次,没想到中的都是垃圾道具,可恨可叹~~

这几天项目中也涉及到了类似的概率操作,于是思考了一下,简单分装了一个精确到万分之一的概率算法实现类,废话不多说上代码。

<?php

/**
 * Created by PhpStorm.
 * User: hgq
 * Date: 2018/05/07
 * Time: 上午 10:00
 * 一个抽奖类,精确到万分之一
 * 三个步骤:1.接受一个中奖概率数组;2.接受一个抽奖种子;3.返回中奖等级
 */
class LuckyDraw {
    /**
     * 中奖概率数组,自动判断奖项数目
     * 数组键值和为10000,自动计算出不中奖的概率,若初始是超过10000抛出一个错误
     * @var array
     */
    protected $_rate = array();

    /**
     * 设置中奖概率,
     * @param array $rate 中奖概率,以数组形式传入
     * @throws Exception
     * @author hgq <[email protected]>.
     * @date: 2018/05/07 上午 10:05
     */
    public function setRate($rate = array(1)) {
        $this->_rate = $rate;
        if(array_sum($this->_rate) > 10000)//检测概率设置是否有问题
            throw new Exception('Winning rate upto 100%');
        if(array_sum($this->_rate) < 10000)
            //定义未中奖情况的概率,用户给的概率只和为100时,则忽略0
            $this->_rate[] = 10000 - array_sum($this->_rate);
    }

    /**
     * 随机生成一个1-10000的整数种子,提交给中奖判断函数
     * @return int 按传入的概率排序,返回中奖的项数
     * @author hgq <[email protected]>.
     * @date: 2018/05/07 上午 10:07
     */
    public function runOnce() {
        return $this->judge(mt_rand(0, 10000));
    }

    /**
     * 按所设置的概率,判断一个传入的随机值是否中奖
     * @param $seed 10000以内的随机数
     * @return int $i 按传入的概率排序,返回中奖的项数 从1开始 如果只有一个奖项则等于1即中奖
     * @author hgq <[email protected]>.
     * @date: 2018/05/07 上午 10:17
     */
    protected function judge($seed) {
        foreach($this->_rate as $key => $value) {
            $tmpArr[$key + 1] = $value;
        }
        //将概率累计,以便随机选择,组合成
        $tmpArr[0] = 0;
        foreach($tmpArr as $key => $value) {
            if($key > 0) {
                $tmpArr[$key] += $tmpArr[$key - 1];
            }
        }
        for($i = 1; $i < count($tmpArr); $i++) {
            if($tmpArr[$i - 1] < $seed && $seed <= $tmpArr[$i]) {
                return $i; //返回中奖的项数(按概率的设置顺序)
            }
        }
    }
}

最后看一下运行效果,循环运行10000次

上述设置了6款产品,概率分别为100,200,500,600,420,512,多次运行中奖概率基本符合概率设置,如果将对应的奖项的设置成0,即意味着该奖项抽中的几率是0

最后说一下为什么抽不到大奖?

在很多类似的抽奖活动中,参与者往往抽不到大奖,笔者从程序的角度举个例给你看,假如我是抽奖活动的主办方,我设置了6个奖项,每个奖项不同的中奖概率,假如一等奖是一台iphoneX,可是我设置了其中奖概率为0,这意味着什么?

这意味着参与抽奖者无论怎么抽,永远也无法中奖。

所以抽奖有风险,操作需谨慎啊~~

By  Hgq

猜你喜欢

转载自www.cnblogs.com/widgetbox/p/9001409.html