标签:proArr 奖品 抽奖 appAnglePrize TP5 中奖 数组 概率 转盘
1、实现
转盘分多种情况,常见的有 不同中奖几率的奖品 、限定数量的奖品 和 限定数量和中奖几率的奖品
1.1、不同中奖几率的奖品 的实现
1)计算出总概率的精度M
2)然后将所有的概率数组依次遍历
3)遍历中随机取出一个1~M的数字
4)如果随机数比当前这个数概率小,则表示命中。
5)反之则将总精度减去当前未命中的概率,表示剩余的总概率
总精度是为了生成随机数,而减去未命中的概率是为了排除出去,最后必定会命中
1.1.1、代码实现
- 传入的数组对应原有下标的一维数组,值为概率,整数/小数都可以
- 计算完后返回对应的下标,再可根据下标找到对应下标的中奖内容即可
测试的中奖几率的方法
/**
* 测试中奖概率
*/
public function test()
{
//获取奖品列表
$appAnglePrize =db('奖品配置表')->where('status', 1)->field('name as "奖项",rate')->order('weigh', 'DESC')->select();
//获取对应的几率数组
$rateArr = array_column($appAnglePrize, 'rate');
foreach ($appAnglePrize as $k => $v) {
$appAnglePrize[$k]['中奖次数'] = 0;
$appAnglePrize[$k]['概率'] = strval($v['rate']) . '%';
unset($appAnglePrize[$k]['rate']);
}
for ($i = 0; $i < 10000; $i++) {
$result = $this->getRandPrize($rateArr);
$appAnglePrize[$result]['中奖次数']++;
}
$this->success($appAnglePrize);
}
抽奖方法
/**
* 返回转盘抽奖结果
* @param array $proArr 概率数组(值为概率)
* @return int|string 返回对应数组的下标
*/
private function getRandPrize($proArr)
{
$result = '';
//概率数组的总概率精度
$proSum = array_sum($proArr);
//概率数组循环
foreach ($proArr as $key => $proCur) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur) {
$result = $key;
break;
} else {
$proSum -= $proCur;
}
}
unset ($proArr);
return $result;
}
1.1.2、测试
1)我们可以看出已经很接近对应的概率了。
2)我这里是跑一万次,我分别跑了好几次观察结果是可行的。
标签:proArr,奖品,抽奖,appAnglePrize,TP5,中奖,数组,概率,转盘 来源: https://blog.csdn.net/weixin_39171255/article/details/113243187
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。