zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    Post请求的两种编码格式:application/x-www-form-urlencoded和multipart/form-data传参方式
    工作中常用的JavaScript函数片段
    解决导入导出Excel表格文字乱码问题
    清空antd-design时间选择组件 RangePicker的值
    react.js Hooks路由跳转
    linux跳板机服务器搭建
    docker及docker-compose学习
    Android Jenkins+Git+Gradle持续集成
    Windows Server 2008 R2常规安全设置及基本安全策略
    ubuntu lnmp安装及php扩展
  • 原文地址:https://www.cnblogs.com/sgm4231/p/14429945.html
Copyright © 2011-2022 走看看