Что такое хороший генератор случайных чисел для игры? - PullRequest
52 голосов
/ 26 июня 2009

Что такое хороший генератор случайных чисел для игры в C ++?

Мои соображения таковы:

  1. Требуется много случайных чисел, поэтому скорость хорошая.
  2. Игроки всегда будут жаловаться на случайные числа, но я бы хотел указать им ссылку, которая объясняет, что я действительно выполнил свою работу.
  3. Поскольку это коммерческий проект, на который у меня не так много времени, было бы неплохо, если бы алгоритм либо a) был относительно прост в реализации, либо b) имел хорошую реализацию не-GPL.
  4. Я уже использую rand() во многих местах, поэтому лучше использовать любой другой генератор, чтобы оправдать все необходимые изменения.

Я не знаю много об этом предмете, поэтому единственная альтернатива, которую я мог придумать, это Mersenne Twister ; это удовлетворяет всем этим требованиям? Есть ли что-нибудь еще лучше?

Редактировать: Мерсенн Твистер, кажется, консенсусный выбор. Но как насчет пункта № 4? Это действительно намного лучше, чем rand()?

Редактировать 2: Позвольте мне быть более ясным по пункту 2: игроки не могут обманывать, зная случайные числа. Период. Я хочу, чтобы это было достаточно случайным, чтобы люди (по крайней мере, те, кто понимают случайность) не могли пожаловаться на это, но я не беспокоюсь о прогнозах. Вот почему я ставлю скорость на первое место.

Редактировать 3: Сейчас я склоняюсь к ГСМ Marsaglia, но мне все еще хотелось бы большего. Поэтому я назначаю щедрость.

Редактировать 4: Просто примечание: я намерен принять ответ незадолго до полуночи UTC сегодня (чтобы не связываться с чьим-либо представителем). Так что, если вы думаете об ответе, не ждите до последней минуты!
Кроме того, мне нравится внешний вид генераторов XORshift от Marsaglia. У кого-нибудь есть информация о них?

Ответы [ 16 ]

1 голос
/ 24 августа 2012

GameRand реализует размещенный здесь алгоритм http://www.flipcode.com/archives/07-15-2002.shtml

Это то, что я изначально разработал в конце 80-х годов. Он легко превосходит rand () с точки зрения числового качества и, как побочный эффект, является самым быстрым случайным алгоритмом из возможных.

1 голос
/ 03 августа 2009

Я бы тоже проголосовал за Мерсена Твистера. Реализации широко доступны, они имеют очень большой период 2 ^ 19937 -1, достаточно быстрые и проходят большинство тестов на случайность, включая тесты Diehard, разработанные Marsaglia. rand () и Co., будучи LCG, дают отклонения более низкого качества, и их последовательные значения можно легко определить.

Однако следует обратить внимание на то, чтобы правильно перевести MT в состояние, которое проходит тесты на случайность. Обычно для этой цели используется LCG, такой как drand48 ().

Я бы сказал, что МТ удовлетворяет всем установленным вами требованиям (предположительно), и было бы излишним переходить на что-то вроде MWCG imo.

0 голосов
/ 04 февраля 2010

Знаешь что? Простите, если вы считаете, что этот ответ полностью отстой ... Но я (потому что бог знает, по какой причине ...) использовал DateTime.Now.Milliseconds как способ получить случайное число. Я знаю, что это не совсем случайно, но похоже, что ...

Мне просто не удавалось печатать так много, ТОЛЬКО чтобы получить случайное число! : P

0 голосов
/ 04 августа 2009

Очевидно (я забыл, где я читал, точно так же, как я забыл, где я читал, что карри полезен для предотвращения альцгейма), принимая абсолютное значение контрольной суммы вновь сгенерированного GUID, довольно случайно. Это большое число, и вы можете использовать его по модулю, чтобы уменьшить его.

Так что в SQL (моя область) это ABS (CHECKSUM (NEWID ()))% 1000

Rob

0 голосов
/ 03 августа 2009

В зависимости от целевой ОС вы можете использовать / dev / random. На самом деле он не требует никакой реализации, а в Linux (и, возможно, в некоторых других операционных системах) он действительно случайный. Чтение блоков до тех пор, пока не будет достигнута достаточная энтропия, поэтому вы можете прочитать файл и сохранить его в буфере или в другом месте, используя другой поток. Если вы не можете использовать блокирующий вызов чтения, вы можете использовать / dev / urandom. Он генерирует случайные данные почти так же, как / dev / random, но использует несколько случайных данных для мгновенного вывода. Это не так безопасно, но может работать нормально, в зависимости от того, что вы собираетесь с ним делать.

0 голосов
/ 31 июля 2009

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

A-ха!

Вот ваше реальное требование!

Никто не может обвинить вас в использовании Mersenne Twister в этом приложении.

...