最近在做一个抽奖转盘,在这做个小结,好记性不如写博客~~


未经允许,不得转载!!

水平有限,不周之处欢迎指正、交流。

博客原文: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,那么判断进入到再接再厉档次。

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里。



个人建议一般的抽奖项目,采用第三种方式,处理方式、安全性、用户体验也比较好!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值