在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
最近玩《QQ飞车手游》,出了一款点券A车,需要消耗抽奖券抽奖,甚是激动,于是抽了几次,没想到中的都是垃圾道具,可恨可叹~~ 这几天项目中也涉及到了类似的概率操作,于是思考了一下,简单分装了一个精确到万分之一的概率算法实现类,废话不多说上代码。 <?php /** * Created by PhpStorm. * User: hgq * Date: 2018/05/07 * Time: 上午 10:00 * 一个抽奖类,精确到万分之一 * 三个步骤:1.接受一个中奖概率数组;2.接受一个抽奖种子;3.返回中奖等级 */ class LuckyDraw { /** * 中奖概率数组,自动判断奖项数目 * 数组键值和为10000,自动计算出不中奖的概率,若初始是超过10000抛出一个错误 * @var array */ protected $_rate = array(); /** * 设置中奖概率, * @param array $rate 中奖概率,以数组形式传入 * @throws Exception * @author hgq <[email protected]>. * @date: 2018/05/07 上午 10:05 */ public function setRate($rate = array(1)) { $this->_rate = $rate; if(array_sum($this->_rate) > 10000)//检测概率设置是否有问题 throw new Exception('Winning rate upto 100%'); if(array_sum($this->_rate) < 10000) //定义未中奖情况的概率,用户给的概率只和为100时,则忽略0 $this->_rate[] = 10000 - array_sum($this->_rate); } /** * 随机生成一个1-10000的整数种子,提交给中奖判断函数 * @return int 按传入的概率排序,返回中奖的项数 * @author hgq <[email protected]>. * @date: 2018/05/07 上午 10:07 */ public function runOnce() { return $this->judge(mt_rand(0, 10000)); } /** * 按所设置的概率,判断一个传入的随机值是否中奖 * @param $seed 10000以内的随机数 * @return int $i 按传入的概率排序,返回中奖的项数 从1开始 如果只有一个奖项则等于1即中奖 * @author hgq <[email protected]>. * @date: 2018/05/07 上午 10:17 */ protected function judge($seed) { foreach($this->_rate as $key => $value) { $tmpArr[$key + 1] = $value; } //将概率累计,以便随机选择,组合成 $tmpArr[0] = 0; 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; //返回中奖的项数(按概率的设置顺序) } } } } 最后看一下运行效果,循环运行10000次 上述设置了6款产品,概率分别为100,200,500,600,420,512,多次运行中奖概率基本符合概率设置,如果将对应的奖项的设置成0,即意味着该奖项抽中的几率是0 最后说一下为什么抽不到大奖?在很多类似的抽奖活动中,参与者往往抽不到大奖,笔者从程序的角度举个例给你看,假如我是抽奖活动的主办方,我设置了6个奖项,每个奖项不同的中奖概率,假如一等奖是一台iphoneX,可是我设置了其中奖概率为0,这意味着什么? 这意味着参与抽奖者无论怎么抽,永远也无法中奖。 所以抽奖有风险,操作需谨慎啊~~
作者:旧旧的 <[email protected]> 解决问题的方式,就是解决它一次 |
2022-08-18
2022-07-29
2022-08-17
2022-09-18
2022-08-17
请发表评论