公司项目需要九宫格抽奖,大奖为1%,谢谢惠顾99%!大牛看一下下面这个中奖概率设置有啥漏洞没有,实际测了一下,抽了好多次才抽到话费50元
外籍杰克兄说得对,首先这种逻辑别放在前端。
然后,只说实现的逻辑,提供一种思路,随机数落在0-1中间的任何一个数概率是相同的,那么,落在0~0.5之间的概率就是50%,落在0.5~0.6之间的概率就是10%。
确认好每个奖的中奖率,比如大奖是1%,二等奖是10%,三等奖是89%,那就判断随机数生成后落在哪个范围里。0~0.01之间就是大奖,0.01~0.11之间就是二等奖,大于0.11就是三等奖。
确定好中了几等奖以后,剩下的是前端要做的事情,顺时针或者逆时针挨个高亮,每循环完一遍时间间隔变长一点,看上去就是转速变慢了,然后转个三圈以后,只要高亮到那个奖项停止动画。
这个应该是我能想到的最直接了当的解决思路了。
随机数不就搞定了,比如获取1~100之间的随机数,抽到1的是大奖,完了随便根据情况再随机(毕竟奖品有便宜有贵的不是),其他2-100是谢谢惠顾。
PS:真是烦这种抽奖,都特么这个套路。
楼主你的思路是正确的,但是代码有 BUG
,你的 getRand
用的是 mt_rand
生成 1-sum 的随机整数,也就是,对应你设置的数组权重 v
的值,就会明白为什么得到的 1% 是(话费50元),剩下就是(谢谢惠顾)。
说重点:根据你的随机算法思路,权重 v
里面的值必须是整数。
把你的数组权重 v
改成以下的值,应该就可以有正确的结果。
$prize_arr = array(
0 => array('v' => 10), //概率 10/10000
1 => array('v' => 10), //概率 10/10000
2 => array('v' => 20), //概率 20/10000
3 => array('v' => 50), //概率 50/10000
4 => array('v' => 100), //概率 100/10000
5 => array('v' => 10), //概率 10/10000
6 => array('v' => 9800), //概率 9800/10000
);
之前我也是用这个方法,后面发现这个算法中奖概率太高了,相当于把每个奖品都放一个箱子,从上到下,每个奖品都单独抽到中奖为止,大大提高了中奖机率。
我改用只取一次的办法,把所有的奖品和干扰球都放到数组里面,在数组里面随机取一个,是奖品球再查看是否有剩余奖品,无则,返回谢谢惠顾。
一般来说,谢谢惠顾这个奖项必有,除非你其它奖品设置的概率高,数量无限制,不然,谢谢惠顾概率肯定最高最高,这个奖项可以不考虑概率,只用它的奖项名称,返回“谢谢,继续加油哦”。
链接描述
10 回答11.7k 阅读
2 回答3.2k 阅读✓ 已解决
3 回答1.7k 阅读✓ 已解决
5 回答804 阅读
4 回答2.2k 阅读✓ 已解决
3 回答1.2k 阅读✓ 已解决
2 回答2.5k 阅读✓ 已解决
这种逻辑应该后台写,并且在提交中奖结果时要进行验证,否则前端太容易篡改数据了。
点击抽奖时,请求后台
后台返回抽奖结果
前端播放抽奖动画,并且保证最后停在返回的中奖结果项上
--- 更新 ---
大致给你个权重算法