前段時間公司里為了推廣微信公眾號吸粉镰惦,需要在公眾號菜單里增加一個大轉(zhuǎn)盤抽獎的活動,在活動現(xiàn)場手機(jī)上抽到什么獎品就是什么麸澜,當(dāng)然由于部分獎品的數(shù)量有限坛梁,所以需要對每個獎項設(shè)置中獎概率,根據(jù)每個獎品的份數(shù)來設(shè)置中獎概率膘融。但是前端給游客看到的轉(zhuǎn)盤里不能顯示有概率大小之分芙粱,要讓游客感覺到每個獎品的概率都是一樣的,這樣就需要將轉(zhuǎn)盤的渲染和中獎計算算法分離氧映。
下面是我想到的兩種抽獎獎項概率的算法春畔,兩種算法各有利弊,需要結(jié)合實際情況來看選擇哪種屯耸。
算法一
第一種算法是通過設(shè)置一個數(shù)組設(shè)定每個獎項對應(yīng)的數(shù)量拐迁,生成范圍區(qū)間,然后計算出總數(shù)量疗绣,通過在0~總數(shù)量中生成隨機(jī)數(shù)來判斷當(dāng)前生成的隨機(jī)數(shù)是在哪個區(qū)間范圍內(nèi)线召,就此來判斷出對應(yīng)的獎項。
這種算法的好處是在整個過程中多矮,每一次的抽獎各獎項概率都是相同的缓淹,保證了抽獎的公平性哈打,缺點是如果最大概率的獎品抽完了,根據(jù)概率論原理讯壶,之后會出現(xiàn)一直抽到但獎品沒有的情況料仗,所以這種算法適用于高概率獎品數(shù)量大于參與人數(shù)的情況。
下面是這種算法的具體代碼
//動態(tài)添加大轉(zhuǎn)盤的獎品與獎品區(qū)域背景顏色和數(shù)量
turnplate.restaraunts = ["卡套", "面巾紙","寶珠筆","卡通風(fēng)扇","護(hù)照夾","便攜鏡"];
turnplate.colors = ["#FFF4D6", "#FFFFFF", "#FFF4D6", "#FFFFFF", "#FFF4D6", "#FFFFFF"];
turnplate.rate = [799,100,20,39,50,25];
//獲取隨機(jī)數(shù)(獎品個數(shù)范圍內(nèi))
var maxlength = 0;
for(var i in turnplate.rate){
maxlength += turnplate.rate[i];
}
var item = '';
var rate_item = rnd(0,maxlength);
//判斷當(dāng)前隨機(jī)數(shù)在哪個范圍內(nèi)
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之后伏蚊,根據(jù)item計算對應(yīng)的轉(zhuǎn)盤角度立轧,實現(xiàn)動畫效果后將轉(zhuǎn)盤指針停在計算出的角度內(nèi)即可。
算法二
第二種算法是需要后端服務(wù)器支持的躏吊,在游客抽獎之后通過異步操作在后端數(shù)據(jù)庫生成一條獎品記錄氛改,在下次抽獎時計算數(shù)據(jù)庫中的獎品記錄數(shù),如果已抽取的獎品記錄數(shù)/總記錄數(shù)大于等于該獎品的概率比伏,則抽獎代碼需執(zhí)行continue操作直到抽到小于獎品概率的獎項為止胜卤。這種算法的好處是可以保證獎品的數(shù)量,如果獎品沒有了赁项,那么就到了該獎品的概率峰值葛躏,就不會再抽到該獎品。這種算法的缺點是越前面抽的人中大獎的概率越高悠菜,越到后面概率逐漸趨于獎品的實際概率舰攒,存在一定的不公平性。這種算法一般適用于對于獎品的份數(shù)小于抽獎人數(shù)的情況李剖,就是獎品都要發(fā)完的情況芒率。
第二種算法的具體代碼實現(xiàn)比較簡單囤耳,這里就不具體列出了篙顺,有興趣的同學(xué)可以自己實現(xiàn)看看。