牛骨文教育服务平台(让学习变的简单)
博文笔记

php大转盘抽奖算法

创建时间:2016-10-25 投稿人: 浏览次数:696

问题描述:

   现在的营销工具大部分都包含抽奖部分,例如大转盘,刮刮卡等。虽然在前端显示的效果完全不同,但是从发出抽奖请求,到返回抽奖结果直接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();


声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。