PHP抽奖算法如何理解,并实现一个抽奖功能
Admin 2022-09-16 群英技术资讯 799 次浏览
这篇文章主要介绍“PHP抽奖算法如何理解,并实现一个抽奖功能”,有一些人在PHP抽奖算法如何理解,并实现一个抽奖功能的问题上存在疑惑,接下来小编就给大家来介绍一下相关的内容,希望对大家解答有帮助,有这个方面学习需要的朋友就继续往下看吧。希望:所以说,树倒了,没有一片雪花是无辜的,抽奖都是假的,只有人家想让你中和不想让你中,如果大家觉得文章有帮助,欢迎点赞。
<?php
$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 ]
];
奖品详情应该从数据库中读出来
奖品详情应该加入缓存,避免数据库的压力
<?php
$thanks_prize = [
'id' => 0,
'pid' => 0,
'type' => 1,
'name' => '谢谢参与'
];
为填充剩余概率的奖品
<?php
$pay_total = 7000;
foreach ($prize as $key => $value) {
if($value['pay'] > $pay_total) unset($prize[$key]);
}
初步过滤一些必要因素,比如充值,角色创建时间等
<?php
$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']];
}
初步过滤后,重构新的抽奖信息,加入谢谢参与
第二步重组概率
<?php
$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;
}
}
}
开始抽奖,并返回抽中的结果
<?php
//此处应该查询数据库,查看该奖品已经抽中的数量
$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;
}
二次过滤,奖品总数的限制以及奖品的每日限制等
<?php
//删除敏感字段
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());
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本篇文章小编给大家分享一下python装饰器底层原理代码解析,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
这篇文章主要给大家介绍关于php实现rpc的操作,本文有具体代码和调用过程,具有一定的借鉴价值,感兴趣的朋友可以参考学习,下面我们就一起来看看具体操作吧。
Error 和 Logging 函数是 PHP 核心的组成部分,它们无需安装即可使用。
php数组合并的方法:1、array_merge数字key被归为0,包含相同的key,则保留第二个key值;2、array_merge_recursive数字key为0,包含相同key时,合成数组;3、array_combine创建新数组。
这篇文章给大家分享PHP函数的应用,主要介绍php如何实现获取汉字首字母功能代码,具有一定的借鉴参考价值,感兴趣的朋友不妨看看,下面就跟随小编一起来了解一下吧。
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 ICP核准(ICP备案)粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008