【PHP】抽奖算法

依然范儿特西
2021-05-26 / 0 评论 / 1,709 阅读 / 正在检测是否收录...

传入一个概率。得出是否中奖

<?php
    /*
    * 抽奖类
    */
    class Prize {
        /*
        * user_v  传入一个概率值,不能超过100
        * 概率值为 100 为必中
        */
        public function judge($user_v) {
            if($user_v > 100){
                return ['status'=>1,'message'=>'概率不能超过100'];
            }
            $gift_rate[] = $user_v;
            $gift_rate[] = 100 - $user_v;
            $seed = mt_rand(0, 10000);//随机生成一个1-10000的整数种子

            //将概率乘100,以便随机选择,组合成
            foreach ($gift_rate as $key => $value) {
                $tmpArr[$key + 1] = $value * 100;
            }
            //获取传入概率 - 10000 之间的数
            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]) {
                    //返回中奖的项数(按概率的设置顺序),如果data为1 即为中奖
                    return ['status'=>2,'message'=>'开奖成功','data'=>$i];
                    break;

                }
            }
        }
    }

    //设置中奖概率
    $user_v = '30'; 
    $Prize = new \Prize;
    $result = $Prize->judge($user_v);
    if($result['status'] == 2 && $result['data'] == 1){
        //喔嚯,中奖了

        # code

    }else{
        //未中奖
        echo $result['message'];
    }




?>

多概率抽奖

<?php
    /*
    * 一个抽奖类,精确到万分之一
    * 三个步骤:1.接受一个中奖概率数组;2.接受一个抽奖种子;3.返回中奖等级
    */
    class Lottery {
        /*
        * 中奖概率数组,自动判断奖项数目
        * 数组键值和为100,自动计算出不中奖的概率,若初始是超过100抛出一个错误
        */
        protected $_rate = array();
        /*
        * 设置中奖概率,
        * @param Array,中奖概率,以数组形式传入
        * 比如: array(30,20,10)
        */
        public function setRate($rate) {
            $this->_rate = $rate;
            //检测概率设置是否有问题
            if (array_sum($this->_rate) > 100){
                throw new Exception('Winning rate upto 100%');
            }
            //定义未中奖情况的概率
            if (array_sum($this->_rate) < 100){
                $this->_rate[] = 100 - array_sum($this->_rate);
            }
              
        }
        /*
        * 随机生成一个1-10000的整数种子,提交给中奖判断函数
        * @return int,按传入的概率排序,返回中奖的项数
        */
        public function runOnce() {
            return $this->judge(mt_rand(0, 10000));
        }
        /*
        * 按所设置的概率,判断一个传入的随机值是否中奖
        * @param int,$seed 10000以内的随机数
        * @return int,$i 按传入的概率排序,返回中奖的项数
        */
        protected function judge($seed) {
            foreach ($this->_rate as $key => $value) {
                $tmpArr[$key + 1] = $value * 100;
            }
            //将概率乘十后累计,以便随机选择,组合成
            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; //返回中奖的项数(按概率的设置顺序)
                }
            }
        }
    }



    //多概率事件
    $rate = array(33, 20, 2, 0.95, 12, 4.55);
    $a = new Lottery;
    $a->setRate($rate);
    for ($i = 0; $i <= 10000; $i++) {
    $b = $a->runOnce();
    @$rewards[$b]++;
    }
    unset($rewards['']);
    echo array_sum($rewards);


    //单多概率事件
    $rate = array(33, 20, 2, 0.95, 12, 4.55);
    $a = new \Lottery;
    $a->setRate($rate);


    $b = $a->runOnce();

    echo $b;
    
    // if($b == '1'){
    //    //执行概率事件
    // }else{
    //    //不执行概率事件
    // }




?>

1

评论 (0)

取消