Qual è un buon generatore di numeri casuali per un gioco?

Qual è un buon generatore di numeri casuali per un gioco?

A volte gli sviluppatori di giochi non vogliono la vera casualità e un shuffle bag è più appropriato.

Se vuoi la casualità, il Mersenne Twister soddisfa le tue esigenze. È veloce, statisticamente casuale, ha un lungo periodo e ci sono molte implementazioni là fuori.

Modifica:rand() è tipicamente implementato come generatore congruente lineare. Probabilmente è meglio se fai una scelta informata se è abbastanza buono per i tuoi scopi.


Al giorno d'oggi ci sono scelte molto migliori rispetto a Mersenne Twister. Ecco un RNG chiamato WELL512, progettato dai designer di Mersenne, sviluppato 10 anni dopo, e una scelta migliore per i giochi. Il codice è di dominio pubblico dal Dr. Chris Lomont. Afferma che questa implementazione è del 40% più veloce di Mersenne, non soffre di scarsa diffusione e cattura quando lo stato contiene molti 0 bit ed è chiaramente un codice molto più semplice. Ha un periodo di 2^512; un PC impiega più di 10^100 anni per scorrere gli stati, quindi è abbastanza grande.

Ecco un documento che illustra i PRNG in cui ho trovato l'implementazione WELL512.http://www.lomont.org/Math/Papers/2008/Lomont_PRNG_2008.pdf

Quindi - più veloce, più semplice, creato dagli stessi designer 10 anni dopo e produce numeri migliori di Mersenne. Come puoi sbagliare? :)

AGGIORNAMENTO (18-11-14) :Errore corretto (modificato da 0xDA442D20UL a 0xDA442D24UL, come descritto nel documento collegato sopra).

/* initialize state to random bits */
static unsigned long state[16];
/* init should also reset this to 0 */
static unsigned int index = 0;
/* return 32 bit random number */
unsigned long WELLRNG512(void)
   {
   unsigned long a, b, c, d;
   a = state[index];
   c = state[(index+13)&15];
   b = a^c^(a<<16)^(c<<15);
   c = state[(index+9)&15];
   c ^= (c>>11);
   a = state[index] = b^c;
   d = a^((a<<5)&0xDA442D24UL);
   index = (index + 15)&15;
   a = state[index];
   state[index] = a^b^d^(a<<2)^(b<<18)^(c<<28);
   return state[index];
   }

George Marsaglia ha sviluppato alcuni dei migliori e più veloci RNG attualmente disponibili Multiply-with-carry è uno dei migliori per una distribuzione uniforme.

===Aggiornamento 12-09-2018 ===

Per il mio lavoro ora sto usando Xoshiro256**, che è una sorta di evoluzione/aggiornamento di XorShift di Marsaglia.

===Aggiornamento 23-02-2021 ===

In .NET 6 (attualmente in anteprima) l'implementazione di System.Random è stata modificata per utilizzare xoshiro256**, ma solo per il costruttore senza parametri. Il costruttore che accetta un seme utilizza il vecchio PRNG per mantenere la compatibilità con le versioni precedenti. Per ulteriori informazioni, vedere Migliora casuale (prestazioni, API, ...)