Необходим предсказуемый генератор случайных чисел - PullRequest
151 голосов
/ 26 мая 2009

Я разработчик веб-игр, и у меня возникла проблема со случайными числами. Допустим, у игрока есть 20% шанс получить критический удар своим мечом. Это означает, что 1 из 5 попаданий должен быть критическим. Проблема в том, что я получил очень плохие результаты в реальной жизни & mdash; иногда игроки получают 3 крита в 5 попаданиях, иногда ни одного в 15 попаданиях. Сражения довольно короткие (3-10 попаданий), поэтому важно получить хорошее случайное распределение.

В настоящее время я использую PHP mt_rand(), но мы просто перемещаем наш код на C ++, поэтому я хочу решить эту проблему в новом движке нашей игры.

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

Ответы [ 37 ]

0 голосов
/ 26 мая 2009

Как насчет взвешивания значения?

Например, если у вас есть шанс 20% на критическое попадание, сгенерируйте число от 1 до 5 с одним числом, представляющим критический удар, или число от 1 до 100 с 20 числами, являющимся критическим попаданием.

Но пока вы работаете со случайными или псевдослучайными числами, невозможно избежать результатов, которые вы видите в данный момент. Это природа случайности.

0 голосов
/ 26 мая 2009

Предварительно рассчитать случайный критический удар для каждого игрока.

// OBJECT
//...
// OnAttack()
//...
c_h = c_h -1;
if ( c_h == 0 ) {
 // Yes, critical hit!
 c_h = random(5) + 1 // for the next time
 // ...
}
0 голосов
/ 27 мая 2009

Как многие говорят, это действительно проблема с тем, что является «случайным». Результаты, которые вы получаете, случайны, и независимо от того, как вы делаете игру, некоторые игроки будут чувствовать, что ваш счетчик не честен и не случайен. ;)

Один из возможных вариантов может заключаться в том, чтобы гарантировать попадание каждые n раз и генерировать n случайным образом в определенных границах после каждого попадания. Все дело в том, что «чувствует» в тестировании.

0 голосов
/ 27 мая 2009

Я думаю, что вы используете неправильную функцию случайного распределения. Вы, вероятно, не хотите равномерного распределения по числам. Вместо этого попробуйте нормальное распределение, чтобы критические попадания стали более необычными, чем «обычные» попадания.

Я работаю с Java, поэтому я не уверен, где можно найти что-то для C ++, которое дает вам случайные числа с нормальным распределением, но что-то там должно быть.

0 голосов
/ 26 мая 2009
static int crit = 0;

public bool isCritical()
{
   crit = crit++ % 5;
   return (crit==0);
} 

если вам все еще нужна некоторая случайность, изменяйте модуль, используя другую статическую переменную каждый раз, когда выполняется крит. изменение его будет равняться вероятности от 3 до 7, при этом среднее время между критами должно быть 1 к 5, но не менее 3 или более 7 попаданий между ними.

0 голосов
/ 26 мая 2009

Реакция на: «Проблема в том, что я получил очень плохие результаты в реальной жизни - иногда игроки получают 3 крита в 5 попаданиях, иногда ни одного в 15 попаданиях».

У вас есть шанс где-то между 3 и 4% получить ничего в 15 попаданиях ...

0 голосов
/ 26 мая 2009

Я бы предложил следующий «случайно откладываемый кубик»:

  • Поддерживает два массива, один (in-array) изначально заполнен значениями от 0 до n-1, другой (out-array) пуст
  • Когда запрашивается результат:
    • возвращает случайное значение из всех определенных значений в in-array
    • переместить это значение с in-array на out-array
    • переместить один случайный (более всех элементов, включая неопределенный!) Элемент из out-array обратно в in-array

У него есть свойство «медленнее» реагировать на большее n . Например, если вам нужен шанс 20%, установка n на 5 и попадание в 0 «менее случайны», чем установка n в 10 и попадание в 0 или 1 и от 0 до 199 из 1000 будет почти неотличим от истинной случайности в небольшой выборке. Вам нужно будет настроить n на ваш размер выборки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...