一.起因
最近在做一些關於紅包和大轉盤的項目,從項目設計到實施,中間花費了不少的心思。所以趁着現在有空記錄下。
二.紅包
紅包的產品設計我們可以參考微信紅包的產品設計,分爲普通紅包和拼手氣紅包。
普通紅包就是把金額均等平分,而拼手氣紅包則是把一個固定的金額隨機分成不等的份額。
思路:我們可以設計一個一個紅包金額表,紅包數據我們可以提前生成,然後再把紅包金額放入到redis中去,用redis的list類型去模擬一個隊列,這樣可以減低搶紅包時對數據庫的壓力。其次主要核心還是隨機金額的算法。
拼手氣紅包算法:
/**
* 限制總額的隨機紅包
*/
private function limitRand ($min,$max,$num,$total){
$data = array();
if ($min * $num > $total) {
return array();
}
if($max*$num < $total){
return array();
}
while ($num >= 1) {
$num--;
$kmix = max($min, $total - $num * $max);
$kmax = min($max, $total - $num * $min);
$kAvg = $total / ($num + 1);
//獲取最大值和最小值的距離之間的最小值
$kDis = min($kAvg - $kmix, $kmax - $kAvg);
//獲取0到1之間的隨機數與距離最小值相乘得出浮動區間,這使得浮動區間不會超出範圍
$r = ((float)(rand(1, 10000) / 10000) - 0.5) * $kDis * 2;
$k = sprintf("%.2f", $kAvg + $r);
$total -= $k;
$data[] = $k;
}
shuffle($data);
return $data;
}
三. 大轉盤
而大轉盤的設計比較簡單,因爲大轉盤的本質是概率的計算。所以核心還是概率的算法,其核心算法如下
//根據概率數據隨機抽獎
$probabilityArr = [10 ,20,30,40,50,80,100]
$range = randomFloat(0,$probabilityArr[$len]);
for ($i=0;$i<$forTimes;$i++){
if($probabilityArr[$i]<= $range && $range<$probabilityArr[($i+1)]){
echo '恭喜你中了'.$i.'等獎';
}
}