php 抽奖算法

<?php
 require '../vendor/autoload.php';

class Draw
{
    //奖品池
    public static $prizes = [
        ['id' => 1, 'name' => 'iphone', 'num' => 1, 'surplusNum' => 1],
        ['id' => 2, 'name' => '小米max', 'num' => 100, 'surplusNum' => 100],
        ['id' => 3, 'name' => '小米3', 'num' => 200, 'surplusNum' => 200],
        ['id' => 4, 'name' => '山寨机', 'num' => 1000, 'surplusNum' => 1000],
        ['id' => 5, 'name' => '安慰奖', 'num' => 50000, 'surplusNum' => 50000],
    ];
    //参加人数
    public static $maxNum = 0;
    //设置中奖名单
    public static $luckList = [];

    /**
     * 设定权重
     */
    public function settingDraw()
    {
        return array(
            array('id' => 1, 'name' => '一等奖', 'pid' => 1, 'v' => 1.5),
            array('id' => 2, 'name' => '二等奖', 'pid' => 2, 'v' => 2.5),
            array('id' => 3, 'name' => '三等奖', 'pid' => 3, 'v' => 10),
            array('id' => 4, 'name' => '四等奖', 'pid' => 4, 'v' => 100),
            array('id' => 5, 'name' => '五等奖', 'pid' => 5, 'v' => 100000),
            array('id' => 6, 'name' => '没中奖', 'pid' => 6, 'v' => 1000000)
        );
    }

    /**
     * 获得第一次抽奖结果
     * @param $proArr
     * @return array
     */
    public function drawResultOne($proArr)
    {
        $result = array();
        foreach ($proArr as $key => $val) {
            $arr[$key] = $val['v'];
        }
        // 概率数组的总概率
        $proSum = array_sum($arr);
        asort($arr);
        // 概率数组循环
        foreach ($arr as $k => $v) {
            $randNum = mt_rand(1, $proSum);
            if ($randNum <= $v) {
                $result = $proArr[$k];
                break;
            } else {
                $proSum -= $v;
            }
        }
        return $result;
    }

    /**
     *
     * 获取抽奖结果
     */
    public function run($user)
    {
        self::$maxNum += 1;
        //获取权重设置
        $drawRules = $this->settingDraw();
        //获得第一次抽奖结果
        $drawResult = $this->drawResultOne($drawRules);
        //读取奖池
        if ((array_search($drawResult, $drawRules) + 1) == count($drawRules)) {
            $user['get'] = $drawResult['name'];
            return $user;
        } else {
            foreach (self::$prizes as $k => &$v) {
                if ($drawResult['pid'] == $v['id']) {
                    if ($v['surplusNum'] <= 0) {
                        $user['get'] = '没中奖';
                        break;
                    } else {
                        array_push(self::$luckList, ['username' => $user['name'], 'good' => $drawResult['name'].'---'.$v['name']]);
                        $user['get'] = $drawResult['name'];
                        $v['surplusNum'] -= 1;
                    }
                }
            }
            return $user;
        }
    }

}

function dd($data)
{
    echo "<pre/>";
    print_r($data);
}


//随机生成用户数量
$users = [];
$userNum = mt_rand(1000, 100000);
$users = array_pad($users, $userNum, ['id' => '', 'name' => '', 'get' => '']);
//$users = array_chunk($users,100);
$obj = new Draw();
foreach ($users as $k => $v) {
    $v['id'] = $k + 1;
    $v['name'] = 'user' . ((string)$k + 1);
    $users[$k] = $obj->run($v);
}

//中奖结果
dd($users);
echo "<hr/>";
//奖品剩余情况
dd($obj::$prizes);
参加人数
echo "<hr/>";
dd($obj::$maxNum);
获奖名单
echo "<hr/>";
dd($obj::$luckList);

  计算部分不是原创 参考 https://segmentfault.com/a/1190000007431893

转载于:https://www.cnblogs.com/gongchixin/articles/7850643.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值