一.起因
最近在做一些关于红包和大转盘的项目,从项目设计到实施,中间花费了不少的心思。所以趁着现在有空记录下。
二.红包
红包的产品设计我们可以参考微信红包的产品设计,分为普通红包和拼手气红包。
普通红包就是把金额均等平分,而拼手气红包则是把一个固定的金额随机分成不等的份额。
思路:我们可以设计一个一个红包金额表,红包数据我们可以提前生成,然后再把红包金额放入到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.'等奖';
}
}