普通写法
function get_chance($chance = [
'和谐' => 3000,
'爱国' => 5000,
'敬业' => 110,
'友善' => 1000,
'富强' => 3000,
])
{
$cardRange = [];
$num = rand(0, array_sum(array_values($chance)));
$total = 0;
foreach ($chance as $key => $value) {
$totalBefore = $total;
$total += $value;
if ($num >= $totalBefore && $num < $total) {
return $key;
}
$cardRange[$key] = [$totalBefore, $total];
}
return $key;
}
在swoole环境中的写法, 兼容所有环境
function get_chance($chance = [
'和谐' => 3000,
'爱国' => 5000,
'敬业' => 110,
'友善' => 1000,
'富强' => 3000,
])
{
// 在协程中避免rand一段时间内值一致的问题
$cardRange = [];
$total = array_sum(array_values($chance));
// $randValue = substr(explode(' ', microtime())[0], 0, 8);
$randValue = strrev(substr(explode(' ', microtime())[0], 2, 6)) / 1000000;
$rangeBefore = 0;
$total2 = 0;
foreach ($chance as $key => $value) {
$total2 += $value;
$rangeAfter = $total2 / $total;
if ($randValue >= $rangeBefore && $randValue < $rangeAfter) {
return $key;
}
$rangeBefore = $rangeAfter;
}
return $key;
}
校验数据和预期值的差异量
$t = [
'记' => 300,
'得' => 900,
'我' => 150,
];
$r = [
'记' => 0,
'得' => 0,
'我' => 0,
];
for ($k = 0; $k <= 10000; $k++) {
$r[get_chance($t)]++;
}
var_dump($r);