未经允许,不得转载!!
水平有限,不周之处欢迎指正、交流。
博客原文:http://blog.csdn.net/ime33
现在市面上很多商家为了促进交易,采取各种各样的营销方案,转盘抽奖就是里面比较经典的一种!但是商家真正的随机中奖,基本那是不可能的!
在市面上看到的抽奖90%以上的中奖概率都是商家程序内定的,中奖概率极低。
要做抽奖主要有几下几种方法:
第一种:纯前端操作(不建议项目使用,纯属研究):
var data = '[{"id":1,"prize":"590大洋","v":20.0},{"id":2,"prize":"100RMB","v":10.0},{"id":3,"prize":"安慰奖","v":10.0}]';// 奖项json
设置好奖项概率,比如第一个590大洋的概率是20%(其余是谢谢的概率60%),如果在1-100中随机出的,则指针指入到20%的500大洋的绘制角度区域范围,视为中奖。
假设我们在1-100之间randomnum随机产生一个数X,X大于100-20且X小于等于100则视为该项中奖,依次类推。
这时候我们已经知道中的奖项是多少了,接下来就是在转盘上指针指到该奖项的角度范围,该奖项角度var angle0 = [ 344, 373 ]区间,js控制在该角度区间随机产生一个角度加上旋转的基础角度,最终效果就是随机停留在该中奖区域内!
var angle0 = [ 344, 373 ];//一等奖
var angle1 = [ 226, 256 ];//二等奖
var angle2 = [ 109, 136 ];//三等奖
switch (index) {
case 0:// 一等奖
var r0 = randomnum(angle0[0], angle0[1]);//在一等奖中奖概率区间取随机角度数
angle = r0;
break;
case 1:// 二等奖
var r1 = randomnum(angle1[0], angle1[1]);
angle = r1;
break;
case 2:// 三等奖
var r2 = randomnum(angle2[0], angle2[1]);
angle = r2;
break;
}
最后一步就中奖信息展示,表单,入库,发放等等。
第二种:客户端+服务端方式,这是比较科学的。
在用户进行点击的时候,向服务端发送请求中奖信息:
概率:
$prize_arr = array(
'0' => array('id' => 1, 'prize' => '一等奖', 'v' => 5),
'1' => array('id' => 2, 'prize' => '二等奖', 'v' => 5),
'2' => array('id' => 3, 'prize' => '三等奖', 'v' => 5),
'3' => array('id' => 4, 'prize' => '四等奖', 'v' => 5),
'4' => array('id' => 5, 'prize' => '五等奖', 'v' => 5),
'5' => array('id' => 6, 'prize' => '六等奖', 'v' => 5),
'6' => array('id' => 7, 'prize' => '七等奖', 'v' => 5),
'7' => array('id' => 8, 'prize' => '八等奖', 'v' => 5),
'8' => array('id' => 9, 'prize' => '九等奖', 'v' => 5),
'9' => array('id' => 10, 'prize' => '十等奖', 'v' => 5),
'10' => array('id' => 11, 'prize' => '十一等奖', 'v' => 25),
'11' => array('id' => 12, 'prize' => '十二等奖', 'v' => 25),
);
function getRand($proArr) {
$data = '';
$proSum = array_sum($proArr); //概率数组的总概率精度
foreach ($proArr as $k => $v) { //概率数组循环
$randNum = mt_rand(1, $proSum);
if ($randNum <= $v) {
$data = $k;
break;
} else {
$proSum -= $v;
}
}
unset($proArr);
return $data;
}
后端根据用户、奖项、时间等信息综合计算出该用户中奖信息再返回给前台,前台趁着旋转的空挡进行处理中奖信息以及转盘的转动、停止位置!
第三种:也是客户端+服务端
区别在于当用户一开始进入的时候,服务端就已经计算出是否中奖以及奖项信息,返回到前台,这时候前台处理只要转动,停止转盘即可!不容易发现作弊,卡壳!
第四种:服务端高大上的中奖处理
1、绝对概率,名额递减。
服务器会设置10个奖励组对应10个奖励,给每个组1个绝对概率,让服务器随机。
即假设,我们设置:
奖励1:80%概率 奖励2:10%概率 奖励3:5%概率 奖励4:3%概率 奖励5:1%概率 奖励6:0.5%概率 奖励7:0.25%概率 奖励8:0.1%概率 奖励9:0.1%概率 奖励10:0.05%概率
比如奖励10的名额为1。奖励9的名额为2。奖励1的名额为100。
每次进入到该档次被人抽中后,名额会-1。
这种后台随机的时候是绝对随机,80%概率会获得“再接再厉”。当用户进入到某档次后如果名额为0,那么判断进入到再接再厉档次。
服务器会设置10个奖励组对应10个奖励,给每个组1个绝对概率,让服务器随机。
即假设,我们设置:
奖励1:80%概率 奖励2:10%概率 奖励3:5%概率 奖励4:3%概率 奖励5:1%概率 奖励6:0.5%概率 奖励7:0.25%概率 奖励8:0.1%概率 奖励9:0.1%概率 奖励10:0.05%概率
比如奖励10的名额为1。奖励9的名额为2。奖励1的名额为100。
每次进入到该档次被人抽中后,名额会-1。
这种后台随机的时候是绝对随机,80%概率会获得“再接再厉”。当用户进入到某档次后如果名额为0,那么判断进入到再接再厉档次。
2、权重分配,名额递减。
服务器会设置10个奖励组对应10个奖励,给每个组设立1个权重值。
假设,我们设置:
奖励1:500,奖励2:200,奖励3:100,奖励4:50,奖励5:40,奖励6:30,奖励7:20,奖励8:10,奖励9:5,奖励10:1
然后假设奖励10名额为1,奖励9的名额为2。奖励1的名额需要策划预先预估会参与此次活动的总人数。
那么,假若要抽到奖励5的概率为:
(奖励5权重*奖励5剩余名额)/(奖励1权重*奖励1剩余名额+奖励2权重*奖励2剩余名额+奖励3权重*奖励3剩余名额+…………奖励10权重*奖励10剩余名额)
每次这个档次被人抽中后,名额会-1。
这种后台随机的时候是相对随机,概率会跟随名额变化不停变动。当奖励组5的名额为0的时候,也不会落入”再接再厉“,而是可能落到奖励组4里。
假设,我们设置:
奖励1:500,奖励2:200,奖励3:100,奖励4:50,奖励5:40,奖励6:30,奖励7:20,奖励8:10,奖励9:5,奖励10:1
然后假设奖励10名额为1,奖励9的名额为2。奖励1的名额需要策划预先预估会参与此次活动的总人数。
那么,假若要抽到奖励5的概率为:
(奖励5权重*奖励5剩余名额)/(奖励1权重*奖励1剩余名额+奖励2权重*奖励2剩余名额+奖励3权重*奖励3剩余名额+…………奖励10权重*奖励10剩余名额)
每次这个档次被人抽中后,名额会-1。
这种后台随机的时候是相对随机,概率会跟随名额变化不停变动。当奖励组5的名额为0的时候,也不会落入”再接再厉“,而是可能落到奖励组4里。
个人建议一般的抽奖项目,采用第三种方式,处理方式、安全性、用户体验也比较好!