# PHP抽奖算法思路？

• 818

1，生成一个随机数；
2，循环对比第N个奖品的概率；
3，确定奖品；

1，先确定随机数（幸运号码）的范围；
2，确定每个奖品的号码区间，确保只抽一次奖能对应到某个奖品；
3，根据范围生成一个幸运号码；
4，根据范围确定奖品；

``````\$goods = [
0 => [
'id'    => 1,
'name'  => '苹果电脑',
'odds'  => '0.01' //概率
],
1 => [
'id'    => 2,
'name'  => 'Iphone',
'odds'  => '10.99'
],
2 => [
'id'    => 3,
'name'  => '200元红包',
'odds'  => '19'
],
3 => [
'id'    => 4,
'name'  => '安慰奖',
'odds'  => '30'
],
4 => [
'id'    => 5,
'name'  => '什么都没抽到',
'odds'  => '40'
],
];

\$baseOdds = 100; //抽奖概率基数,默认100%
\$maxBase = 1; //抽奖概率基数倍数,默认1,如果奖品概率有小数位,该倍数为10的小数位数平方,具体看下面

foreach (\$goods as \$good) {
\$decimal = strpbrk(\$good['odds'], '.'); //获取小数点后面的内容
if (\$decimal !== false) {
\$decimalCount = strlen(\$decimal) - 1;//获取小数点后面的位数
\$newMaxBase = pow(10, \$decimalCount); //例如概率如果是0.01,则全局的抽奖概率基数需要以10的平方倍数上涨
if (\$newMaxBase > \$maxBase) {
\$maxBase = \$newMaxBase; //更新基数倍数
}
}
}
\$baseOdds = \$maxBase ? \$baseOdds * \$maxBase : \$baseOdds; //更新概率基数

\$start = 1;
\$end = 0;
\$luckyCompare = \$tickets = [];
//为每个奖品生成一个幸运数区间
foreach (\$goods as \$key => \$good) {
\$newOdds = \$good['odds'] * \$maxBase;
\$end = \$end + \$newOdds;
\$luckyCompare[\$good['id']] = [\$start, \$end];
\$tick = mt_rand(\$start, \$end);
\$start = \$start + \$newOdds;
\$tickets[\$good['id']] = \$tick;
}
\$luckyNumber = mt_rand(1, \$baseOdds);
var_dump(\$luckyNumber);
var_dump(\$luckyCompare);
foreach (\$luckyCompare as \$goodId => \$compare) {
if (\$compare[0] <= \$luckyNumber && \$compare[1] >= \$luckyNumber) {
\$luckyGood = \$goodId; //最终的奖品
break;
}
}

var_dump(\$luckyGood);``````

3 个回答