PHP抽奖算法

news/2024/11/11 8:46:01/文章来源:https://www.cnblogs.com/shemmor/p/18424013

一、初始化奖品
id 奖品的id

pid 奖品的自定义id

type 奖品类型,1、虚拟奖品 2、实物奖品 3、礼包码 待扩充

name 奖品名称

total 奖品总数

chance 获奖概率/抽奖基数10000

daynum 每日数量限制

pay 充值限制

$prize = [
['id' => 1, 'pid' => 11, 'type' => 1, 'name' => '典藏英雄', 'total' => 20, 'chance' => 1000, 'daynum' => 10, 'pay' => 2000 ],
['id' => 2, 'pid' => 12, 'type' => 1, 'name' => '史诗皮肤', 'total' => 40, 'chance' => 1000, 'daynum' => 10, 'pay' => 4000 ],
['id' => 3, 'pid' => 13, 'type' => 1, 'name' => '钻石奖励', 'total' => 80, 'chance' => 1000, 'daynum' => 10, 'pay' => 4000 ],
['id' => 4, 'pid' => 14, 'type' => 1, 'name' => '荣耀水晶', 'total' => 20, 'chance' => 1000, 'daynum' => 10, 'pay' => 8000 ]
];

二、谢谢参与
$thanks_prize = [
'id' => 0,
'pid' => 0,
'type' => 1,
'name' => '谢谢参与'
];

三、过滤抽奖、如充值条件
$pay_total = 7000;
foreach ($prize as $key => $value) {
if($value['pay'] > $pay_total) unset($prize[$key]);
}

四、重组概率
$now_chance = array_sum(array_column($prize, 'chance'));
$remain_chance = 10000 - $now_chance;
$prize[] = ['id' => 0, 'pid' => 0, 'type' => 1, 'name' => '谢谢参与', 'total' => 0, 'chance' => $remain_chance, 'daynum' => 0, 'pay' => 0];

$award = [];
$num = 0;
foreach ($prize as $_v) {
$num += $_v['chance'];
$award[] = ['id' => $_v['id'], 'pid' => $_v['pid'], 'type' => $_v['type'], 'name' => $_v['name'], 'total' => $_v['total'], 'chance' => $num, 'daynum' => $_v['daynum'], 'pay' => $_v['pay']];
}
初步过滤后,重构新的抽奖信息,加入谢谢参与
第二步重组概率

五、进行抽奖
$rand = mt_rand(1, 10000);
$result = [];
foreach ($award as $_k => $_v) {
if ($_k == 0) {
if ($rand > 0 && $rand <= $_v['chance']) {
$result = $_v;
break;
}
} else {
if ($rand > $award[$_k - 1]['chance'] && $rand <= $_v['chance']) {
$result = $_v;
break;
}
}
}
开始抽奖,并返回抽中的结果

六、过滤回调
//此处应该查询数据库,查看该奖品已经抽中的数量
$yet_num = 50;
if($result['pid'] != 0 && $yet_num > $result['total']) {
$result = $thanks_prize;
}

//此处应该查询数据库,查看该奖品今日已经抽中的数量
$yet_today_num = 50;
if($result['pid'] != 0 && $yet_today_num > $result['daynum']) {
$result = $thanks_prize;
}
二次过滤,奖品总数的限制以及奖品的每日限制等

七、最终抽奖结果
//删除敏感字段
unset($result['total'],$result['chance'],$result['daynum'],$result['pay']);

//返回最终抽奖结果
echo json_encode([
'prize' => $award,
'rand' => $rand,
'result' => $result
]);

八、抽奖封装成类
<?php
/**
* Created by PhpStorm.
* User: autofelix
* Date: 2020/10/30
* Time: 13:14
* Desc: 抽奖算法
*/

class Lottery
{
/**
* 概率基数
* @var int
*/
private $total_chance = 10000;

/**
* 谢谢参与奖励
* @var array
*/
private $thanks_prize = [
'id' => 0,
'pid' => 0,
'type' => 1,
'name' => '谢谢参与'
];

/**
* 奖池
* @var array
*/
private $prize = [
['id' => 1, 'pid' => 11, 'type' => 1, 'name' => '典藏英雄', 'total' => 20, 'chance' => 1000, 'daynum' => 10, 'pay' => 2000 ],
['id' => 2, 'pid' => 12, 'type' => 1, 'name' => '史诗皮肤', 'total' => 40, 'chance' => 1000, 'daynum' => 10, 'pay' => 4000 ],
['id' => 3, 'pid' => 13, 'type' => 1, 'name' => '钻石奖励', 'total' => 80, 'chance' => 1000, 'daynum' => 10, 'pay' => 4000 ],
['id' => 4, 'pid' => 14, 'type' => 1, 'name' => '荣耀水晶', 'total' => 20, 'chance' => 1000, 'daynum' => 10, 'pay' => 8000 ]
];

/**
* Lottery constructor.
*/
public function __construct()
{
}

/**
* @return int
*/
private function get_user_pay()
{
//这里应该调用接口,返回用户正确的充值信息
return 3000;
}

/**
* 重构奖池、重组概率
* @return array
*/
private function init_lottery_pond()
{
$award = [];

//充值限制
$user_pay = $this->get_user_pay();
foreach ($this->prize as $key => $value) {
if($value['pay'] <= $user_pay) unset($this->prize[$key]);
}

//加入谢谢惠顾
$now_chance = array_sum(array_column($this->prize, 'chance'));
$remain_chance = $this->total_chance - $now_chance;
$this->prize[] = ['id' => 0, 'pid' => 0, 'type' => 1, 'name' => '谢谢参与', 'total' => 0, 'chance' => $remain_chance, 'daynum' => 0, 'pay' => 0];

//重组概率
$num = 0;
foreach ($this->prize as $_v) {
$num += $_v['chance'];
$award[] = ['id' => $_v['id'], 'pid' => $_v['pid'], 'type' => $_v['type'], 'name' => $_v['name'], 'total' => $_v['total'], 'chance' => $num, 'daynum' => $_v['daynum'], 'pay' => $_v['pay']];
}

return $award;
}

/**
* 获取抽奖结果
* @return array
*/
public function get_prize()
{
$award = $this->init_lottery_pond();
$rand = mt_rand(1, $this->total_chance);
$result = [];
foreach ($award as $_k => $_v) {
if ($_k == 0) {
if ($rand > 0 && $rand <= $_v['chance']) {
$result = $_v;
break;
}
} else {
if ($rand > $award[$_k - 1]['chance'] && $rand <= $_v['chance']) {
$result = $_v;
break;
}
}
}

$result = $this->filter($result);
return $result;
}

/**
* 抽奖过滤回调函数
* @param $result
* @return array
*/
public function filter($result)
{
//奖品总数限制,此处应该查数据库
$yet_num = 50;
if($result['pid'] != 0 && $yet_num > $result['total']) {
$result = $this->thanks_prize;
}

//奖品每日数量限制,此处应该查数据库
$yet_today_num = 50;
if($result['pid'] != 0 && $yet_today_num > $result['daynum']) {
$result = $this->thanks_prize;
}

//不暴露敏感信息
unset($result['total'], $result['chance'], $result['daynum'], $result['pay'] );
return $result;
}

private function __clone()
{
}
}

echo json_encode((new Lottery())->get_prize());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/801011.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 指针和迭代器支持的操作

▲ 《C++ Primer》 P96 指针也都支持上面的操作。

代码整洁之道--读书笔记(14)

代码整洁之道简介: 本书是编程大师“Bob 大叔”40余年编程生涯的心得体会的总结,讲解要成为真正专业的程序员需要具备什么样的态度,需要遵循什么样的原则,需要采取什么样的行动。作者以自己以及身边的同事走过的弯路、犯过的错误为例,意在为后来者引路,助其职业生涯迈上更…

hexo安装后报错hexo 不是内部或外部命令,也不是可运行的程序 或批处理文件。

hexo问题 之前利用hexo和gitee搭建了一个博客,但是最近gitee的gitpage停止服务了,便想着在github上搭建一个。 在到安装hexo这一步的时候,一直报错hexo 不是内部或外部命令,也不是可运行的程序 或批处理文件。 我的所有安装步骤和环境变量发现都没有错,反复配置后去找了一…

跑冒滴漏监测系统

跑冒滴漏监测系统应用计算机视觉和深度学习技术对危化品生产区域实时检测,当检测到液体泄露时,立即抓拍存档告警并回传给后台监控平台方便人员及时处理,提高图像数据的实时监控效率。跑冒滴漏监测系统7*24小时不间断对监控画面实时分析监测,避免意外事故发生,同时降低人力…

学校食堂明厨亮灶监控系统

学校食堂明厨亮灶监控系统通过卷积神经网络学习与图像识别技术,学校食堂明厨亮灶监控系统将对现场监控画面进行24小时实时分析,如:厨房出现老鼠狗猫、厨师未戴口罩、厨师未戴厨师帽、厨师服穿戴识别、抽烟识别、玩手机识别,同时实时抓拍相关情况,全程记录留痕,提升监管效…

河道采砂识别监测系统

河道采砂识别监测系统借助深度视觉边缘分析技术,自动对监控区域违法采砂进行实时监测。如果河道采砂识别监测系统监测到有人违法采砂时,立即抓拍存档预警,将违规采砂截图发给后台管理中心,提醒后台人员及时处理。河道采砂识别监测系统可根据时间段违规记录、视频进行查找,…

煤炭传送带状态检测系统

煤炭传送带状态检测系统通过机器视觉+边缘分析技术对煤炭皮带状况进行实时监测,一旦煤炭传送带状态检测系统监测到皮带跑偏、堆煤、撕裂、异物等其他情况,煤炭传送带状态检测系统马上开展警报提醒,通知后台监控平台,并提醒相关人员及时处置。煤炭传送带状态检测系统同时把告…

城市道路积水识别监测系统

城市道路积水识别监测系统基于机器视觉分析,城市道路积水识别监测系统实时识别街道路面积水情况,对严重积水时立即报警。城市道路积水识别监测系统对低洼区域进行实时监测,一旦城市道路积水识别监测系统监测到街道路面积水时,立即进行抓拍告警,告知监控管理中心,提醒相关…

Thinkphp8安装topthink/think-captcha验证码的和使用方法

ThinkPHP8默认没有验证码,安装验证码可以使用composer来安装验证码 一、安装验证码 执行composer安装验证码 composer require topthink/think-captcha二、使用方法 1、在目录app\middleware.php中开启session \think\middleware\SessionInit::class 2、配置验证码 安装好验证…

水尺监测识别系统

水尺监测识别系统利用计算机视觉+机器学习技术对河道湖泊进行实时检测,当水尺监测识别系统监测到河道水位异常时,立即告警。水尺监测识别系统同时将告警截图和视频保存下来,推送给后台。水尺监测识别系统极大提升现场区域的管控效率,既方便又节省人力。水尺监测识别系统利用…

人员规范操作行为识别系统

人员规范操作行为识别系统对现场人员操作行为进行实时监测分析,如果人员规范操作行为识别系统发现现场人员未按照要求规范进行操作、遗漏操作步骤更改先后作业顺序或者操作不规范,人员规范操作行为识别系统立即抓拍存档现场语音播报提醒相关人员行为不规范请立即改正,并同步…

皮带跑偏检测系统

皮带跑偏检测系统对煤矿皮带运行状态进行全天候实时监测,一旦皮带跑偏检测系统监测到现场皮带跑偏、撕裂、堆煤、异物等异常情况时,皮带跑偏检测系统马上开展警报,通知监督管理办公室,并提醒负责人及时处置。皮带跑偏检测系统并把警报截屏和视频储存到数据库系统系统中生成…