Создание вероятности на php. Можете помочь?

Здравствуйте. Делаю мини-игру на сайте. Есть сундук. По нажатию на него случается запрос к БД с призами. Структура таблицы: id, name, description, ver(вероятность выпадения).
Все призы заносятся в array вместе с их вероятностью. Так как срандомить, чтобы, к примеру, GTA V не выпадала пять раз подряд, а GTA SA, у которой вероятность выпадения больше, выпадала, естественно, чаще. Спасибо
  • Вопрос задан
  • 4568 просмотров
Решения вопроса 2
GeneMoss
@GeneMoss
void
/**
 * Случайная выборка с учетом веса каждого элемента.
 * @param array $data Массив, в котором ищется случайный элемент
 * @param string $column Параметр массива, содержащий «вес» вероятности
 * @return int Индекс найденного элемента в массиве $data 
 */
function getRandomIndex($data, $column = 'ver') {
  $rand = mt_rand(1, array_sum(array_column($data, $column)));
  $cur = $prev = 0;
  for ($i = 0, $count = count($data); $i < $count; ++$i) {
    $prev += $i != 0 ? $data[$i-1][$column] : 0;
    $cur += $data[$i][$column];
    if ($rand > $prev && $rand <= $cur) {
      return $i;
    }
  }
  return -1;
}

// Использование
$games = [
	['name' => 'Игра 1', 'ver' => 2], // вероятность 2/15
	['name' => 'Игра 2', 'ver' => 0], // вероятность 0/15
	['name' => 'Игра 3', 'ver' => 1], // вероятность 1/15
	['name' => 'Игра 4', 'ver' => 4], // вероятность 4/15
	['name' => 'Игра 5', 'ver' => 8], // вероятность 8/15
];
$i = getRandomIndex($games);
echo $games[$i]['name'];

В параметре массива «ver» задается вероятность выпадения данного элемента таким образом, что вероятность выпадения каждого элемента равна ver/sum, где sum — сумма вероятностей в данном массиве (в примере это: 2 + 0 + 1 + 4 + 8 = 15).

После миллиона испытаний получено следующее количество выпадений:
  • Игра 1 = 13.3958%
  • Игра 2 = 0%
  • Игра 3 = 6.671%
  • Игра 4 = 26.6124%
  • Игра 5 = 53.3208%

Что до сотой доли процента совпадает с заданной вероятностью в параметре «ver».

P. S. Суть алгоритма — имитация случайной выборки из массива, который заполнен элементами, которые дублируются с заданной частотой.
Ответ написан
Комментировать
sergiks
@sergiks Куратор тега PHP
♬♬
Алгоритм:
  1. сложить вероятности найденных призов
  2. выбрать случайное число от 1 до суммы
  3. определить, в «зону» какого из призов оно попадает

Примерно:
$stock = [
	["id"=>1, "ver"=>13, "name"=>"gta v"],
	["id"=>2, "ver"=>48, "name"=>"gta sa"],
	["id"=>3, "ver"=>119, "name"=>"chess"],
];

$total = 0;
foreach($stock as $v) $total += $v["ver"];

$rnd = rand(1, $total);

$run = 0;
foreach($stock as $v) {
	$run += $v["ver"];
	if( $rnd <= $run) break;
}

$prizeName = $v["name"];
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@rPman
Алгоритмы псевдо-случайного вознаграждения в ммрпг вообще патентованные, от них зависит как долго игроки будут терпеть это безобразие.

делайте как это делают в устройствах для гамблинга, игровых автоматах ит.п. - заранее просчитайте список выигрышей, с последующей проверкой на итоговые распределения, исключение вырожденных случаев и перекосов, и чтобы владелец игры не в накладе остался.

Заранее считать - алгоритм проще чем последовательная генерация - проще проверить итоговое распределение.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы