php简单抽奖算法(设置库存)
2026/9/9 14:06:57 网站建设 项目流程

注意: probability(概率)之和必须=100

下面方法为简单没有库存

public function draw() { $draw_list = [ [ "name" => "空奖(0-80)", "probability" => "80.00" ], [ "name" => "5积分(80-90)", "probability" => "10.00" ], [ "name" => "10积分(90-98)", "probability" => "8.00" ], [ "name" => "20积分(98-100)", "probability" => "2.00" ], ]; // 生成一个0到100之间的随机数 $randomNum = random_int(0, 100); $currentProbability = 0; foreach ($draw_list as $draw_info) { $currentProbability += $draw_info['probability']; if ($randomNum <= $currentProbability) { $draw_info['currentProbability'] = $currentProbability; $draw_info['randomNum'] = $randomNum; $draw_result = $draw_info; break; } } $this->success("请求成功!", $draw_result); }

含有库存写法

public function draw_test() { $draw_list = [ [ "name" => "空奖(0-80)", "probability" => "80.00", "stock" => 0 ], [ "name" => "5积分(80-90)", "probability" => "10.00", "stock" => 1 ], [ "name" => "10积分(90-98)", "probability" => "9.9999999", "stock" => 0 ], [ "name" => "20积分(98-100)", "probability" => "0.0000001", "stock" => 1 ], ]; // 修改这里调整支持的小数位数 $scale = 100000000; // ========== 整数溢出安全校验 ========== $maxExpectTotalWeight = 100 * $scale; // 预留1/2安全余量,防止后续分摊权重后溢出 if ($maxExpectTotalWeight > PHP_INT_MAX / 2) { $this->error("scale配置过大,存在整数溢出风险,请调小scale值"); } $emptyTotalWeight = 0; $validList = []; foreach ($draw_list as $item) { $p = (float)$item['probability']; $intWeight = (int)round($p * $scale); if ($item['stock'] > 0) { $validList[] = [ 'name' => $item['name'], 'probability' => $item['probability'], //保留原始概率 'weight' => $intWeight, 'stock' => $item['stock'] ]; } else { $emptyTotalWeight += $intWeight; } } // 边界:全部奖品库存为0 if (empty($validList)) { $this->error("暂无可用奖品"); } // 将库存=0的奖项权重分摊到有效奖品 if ($emptyTotalWeight > 0) { $validCount = count($validList); $avgAdd = (int)($emptyTotalWeight / $validCount); $remainder = $emptyTotalWeight % $validCount; //余数补到最后一项 foreach ($validList as $idx => &$v) { $v['weight'] += $avgAdd; if ($idx === $validCount - 1) { $v['weight'] += $remainder; } } unset($v); } $totalWeight = array_sum(array_column($validList, 'weight')); // 极端保护:总权重不能小于1 if ($totalWeight < 1) { $this->error("奖品权重合计异常"); } $rand = mt_rand(1, $totalWeight); $currentWeight = 0; $draw_result = null; foreach ($validList as $row) { $currentWeight += $row['weight']; if ($rand <= $currentWeight) { $draw_result = $row; $draw_result['rand'] = $rand; $draw_result['totalWeight'] = $totalWeight; break; } } $this->success("请求成功!", $draw_result); }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询