PHP 红包算法
class RedPacket { public $bonus = []; //红包 public $bonusNum; //红包个数 public $bonusMoney; //红包总金额 public $moneySingleMax; //单个红包最大限制 public $moneySingleMin; //单个红包最小限制 public static $error = ''; /** * redPackageService constructor. * @param int $bonusNum * @param int $bonusMoney */ public function __construct($bonusNum = 20, $bonusMoney = 200) { $avg = ceil($bonusMoney / $bonusNum); $avgHalf = ceil($avg / 2); $this->bonusNum = $bonusNum; $this->bonusMoney = $bonusMoney; $this->moneySingleMax = $avg + $avgHalf; $this->moneySingleMin = $avg - $avgHalf; } /** * 是否能够发随机红包 * @param $bonusMoney * @param $bonusNum * @return bool */ public function isCanBuilder($bonusMoney, $bonusNum) { if (false == is_int($bonusNum) || $bonusNum <= 0) { return false; } if (false == is_numeric($bonusMoney) || $bonusMoney <= 0) { return false; } //均值 $avgMoney = $bonusMoney / 1.0 / $bonusNum; //均值小于最小值 if ($avgMoney < 0.01) { return false; } return true; } private function randomFloat($min = 0, $max = 1) { $mtRand = mt_rand(); $mtGetRandMax = mt_getrandmax(); return $min + $mtRand / $mtGetRandMax * ($max - $min); } //计算 public function compute() { if (!$this->isCanBuilder($this->bonusMoney, $this->bonusNum)) { return false; }; $bonusMoneyTemp = $this->bonusMoney; $moneySingleMax = $this->moneySingleMax; $moneySingleMin = $this->moneySingleMin; $i = 1; while ($i < $this->bonusNum) { if ($moneySingleMax > $bonusMoneyTemp) { $moneySingleMax = floatval(sprintf("%01.2f", $bonusMoneyTemp / 2));//剩余金额不够分时,把剩余金额的一半作为备用金 if ($moneySingleMin > $moneySingleMax) { //最小金额大于最大金额时,将最小金额设置为最大金额的一半 $moneySingleMin = floatval(sprintf("%01.2f", $moneySingleMax / 2)); } } $bonusMoneyRad = $this->randomFloat($moneySingleMin, $moneySingleMax);//一个红包随机金额 $bonusMoneyRad = floatval(sprintf("%01.2f", $bonusMoneyRad)); $bonusMoneyTemp = $bonusMoneyTemp - $bonusMoneyRad;//待分配的总剩余金额 $bonusMoneyTemp = floatval(sprintf("%01.2f", $bonusMoneyTemp)); $this->bonus[] = $bonusMoneyRad; $i++; } $this->bonus[] = $bonusMoneyTemp;//分配剩余金额给最后一个红包 } /** * 红包金额存入Redis * @param $hb_id */ public function redisSave($hb_id) { foreach ($this->bonus as $key => $val) { Redis::rpush('red-packet-' . $hb_id, $val); } } /** * 领取红包 * @param $hb_id * @return bool */ public function getRedisInfo($hb_id) { if (!Redis::exists('red-packet-' . $hb_id)) { self::$error = '红包已领完'; return false; } // todo 是否领取过红包判断 return Redis::lpop('red-packet-' . $hb_id); } //打印 public function output() { $total = 0; foreach ($this->bonus as $k => $v) { echo '红包' . ($k + 1) . '=' . $v . '<br/>'; $total += $v; } echo '红包总金额:' . $total; } }