前段时间公司里为了推广微信公众号吸粉,需要在公众号菜单里增加一个大转盘抽奖的活动,在活动现场手机上抽到什么奖品就是什么,当然由于部分奖品的数量有限,所以需要对每个奖项设置中奖概率,根据每个奖品的份数来设置中奖概率。但是前端给游客看到的转盘里不能显示有概率大小之分,要让游客感觉到每个奖品的概率都是一样的,这样就需要将转盘的渲染和中奖计算算法分离。
微信大转盘下面是我想到的两种抽奖奖项概率的算法,两种算法各有利弊,需要结合实际情况来看选择哪种。
算法一
第一种算法是通过设置一个数组设定每个奖项对应的数量,生成范围区间,然后计算出总数量,通过在0~总数量中生成随机数来判断当前生成的随机数是在哪个区间范围内,就此来判断出对应的奖项。
这种算法的好处是在整个过程中,每一次的抽奖各奖项概率都是相同的,保证了抽奖的公平性,缺点是如果最大概率的奖品抽完了,根据概率论原理,之后会出现一直抽到但奖品没有的情况,所以这种算法适用于高概率奖品数量大于参与人数的情况。
下面是这种算法的具体代码
//动态添加大转盘的奖品与奖品区域背景颜色和数量
turnplate.restaraunts = ["卡套", "面巾纸","宝珠笔","卡通风扇","护照夹","便携镜"];
turnplate.colors = ["#FFF4D6", "#FFFFFF", "#FFF4D6", "#FFFFFF", "#FFF4D6", "#FFFFFF"];
turnplate.rate = [799,100,20,39,50,25];
//获取随机数(奖品个数范围内)
var maxlength = 0;
for(var i in turnplate.rate){
maxlength += turnplate.rate[i];
}
var item = '';
var rate_item = rnd(0,maxlength);
//判断当前随机数在哪个范围内
var startI = 0;
var endI = 1;
for(var i in turnplate.rate){
endI = endI + turnplate.rate[i];
if(rate_item > startI && rate_item < endI){
item = (Number(i)+1);
}
startI = startI + turnplate.rate[i];
}
算出奖品序号item之后,根据item计算对应的转盘角度,实现动画效果后将转盘指针停在计算出的角度内即可。
算法二
第二种算法是需要后端服务器支持的,在游客抽奖之后通过异步操作在后端数据库生成一条奖品记录,在下次抽奖时计算数据库中的奖品记录数,如果已抽取的奖品记录数/总记录数大于等于该奖品的概率,则抽奖代码需执行continue操作直到抽到小于奖品概率的奖项为止。这种算法的好处是可以保证奖品的数量,如果奖品没有了,那么就到了该奖品的概率峰值,就不会再抽到该奖品。这种算法的缺点是越前面抽的人中大奖的概率越高,越到后面概率逐渐趋于奖品的实际概率,存在一定的不公平性。这种算法一般适用于对于奖品的份数小于抽奖人数的情况,就是奖品都要发完的情况。
第二种算法的具体代码实现比较简单,这里就不具体列出了,有兴趣的同学可以自己实现看看。
网友评论