php大转盘抽奖算法
问题描述:
现在的营销工具大部分都包含抽奖部分,例如大转盘,刮刮卡等。虽然在前端显示的效果完全不同,但是从发出抽奖请求,到返回抽奖结果直接php部分可以通用。整个流程包括 1拼装奖项数组2进行概率计算3返回中奖情况(包括是否中奖,奖品编号,奖品名称,奖品图片,奖品类型等)。
问题分析:
(1)拼装奖项数组
//奖品数组 $prize_arr = array( "0" => array("id"=>1,"prize"=>"平板电脑","v"=>1), "1" => array("id"=>2,"prize"=>"数码相机","v"=>5), "2" => array("id"=>3,"prize"=>"音箱设备","v"=>10), "3" => array("id"=>4,"prize"=>"4G优盘","v"=>12), "4" => array("id"=>5,"prize"=>"10Q币","v"=>22), "5" => array("id"=>6,"prize"=>"空奖","v"=>50), );
从配置信息中获取奖品名称,数量,概率等信息,并进行拼装。
(2)核心部分 计算概率
function get_rand($proArr) { $result = ""; //概率数组的总概率精度 $proSum = array_sum($proArr); //概率数组循环 foreach ($proArr as $key => $proCur) { $randNum = mt_rand(1, $proSum); if ($randNum <= $proCur) { $result = $key; break; } else { $proSum -= $proCur; } } unset ($proArr); return $result; }$proArr是一个预先设置的数组,假设数组为:array(100,200,300,400),开始是从1,1000这个概率范围内筛选第一个数是否在他的出现概率范围之内, 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。这样筛选到最终,总会有一个数满足要求。就相当于去一个箱子里摸东西,第一个不是,第二个不是,第三个还不是,那最后一个一定是。
(3)返回中奖信息
奖品名称保存在$res["yes"]中,对应的id是$rid。未中奖奖品是$res["no"]。这里只需要返回奖品名称$result["name"]=$res["yes"]
扩展部分:
1)限制中奖次数 :在中奖函数开始时,判断统计该用户中奖次数。超出次数,跳出;没有超过,继续抽奖
2)一个人不能重复中奖:在中奖函数结束时,判断统计该用户中奖名称是否已存在。存在则重新抽奖或者跳出;不存在,则继续抽奖。
3)返回未中奖信息$res["no"]。目前大转盘,刮刮卡没有用到未中奖的信息,如果是翻牌类抽奖,则需要展示未中奖的奖品。
4)某项奖品必中一次。抽奖开始时,判断是否已有该奖品,有则正常抽奖;没有,则直接中该奖品,跳出函数。
完整代码
//计算中奖函数 function get_gift(){ //奖品数组 $prize_arr = array( "0" => array("id"=>1,"prize"=>"平板电脑","v"=>1), "1" => array("id"=>2,"prize"=>"数码相机","v"=>5), "2" => array("id"=>3,"prize"=>"音箱设备","v"=>10), "3" => array("id"=>4,"prize"=>"4G优盘","v"=>12), "4" => array("id"=>5,"prize"=>"10Q币","v"=>22), "5" => array("id"=>6,"prize"=>"空奖","v"=>50), ); foreach ($prize_arr as $key => $val) { $arr[$val["id"]] = $val["v"];//概率数组 } $rid = get_rand($arr); //根据概率获取奖项id $res["yes"] = $prize_arr[$rid-1]["prize"]; //中奖项 unset($prize_arr[$rid-1]); //将中奖项从数组中剔除,剩下未中奖项 shuffle($prize_arr); //打乱数组顺序 for($i=0;$i<count($prize_arr);$i++){ $pr[] = $prize_arr[$i]["prize"]; } $res["no"] = $pr; if($res["yes"]!="空奖"){ $result["status"]=1; $result["name"]=$res["yes"]; }else{ $result["status"]=-1; $result["msg"]=$res["yes"]; } return $result; }
function get_rand($proArr) { $result = ""; //概率数组的总概率精度 $proSum = array_sum($proArr); //概率数组循环 foreach ($proArr as $key => $proCur) { $randNum = mt_rand(1, $proSum); if ($randNum <= $proCur) { $result = $key; break; } else { $proSum -= $proCur; } } unset ($proArr); return $result; } $res=get_gift(); echo json_encode($res); die();
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: PHP中奖概率算法-按概率值排序
- 下一篇: RSA PKCS1padding 填充模式