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();


猜你喜欢

转载自blog.csdn.net/dyfc3sfd3s/article/details/52918805