web-dev-qa-db-fra.com

Mêmes nombres aléatoires chaque fois que j'exécute le programme

Mes nombres aléatoires qui sortent, sortent dans la même séquence chaque fois que je lance mon jeu. Pourquoi cela arrive-t-il?

J'ai

#include <cstdlib> 

et j'utilise cela pour générer les nombres aléatoires

randomDiceRollComputer = 1 + Rand() % 6;
25
soniccool

Vous devez amorcer votre générateur de nombres aléatoires:

Essayez de mettre cela au début du programme:

srand ( time(NULL) );

Notez que vous devrez #include <ctime>.

L'idée ici est de semer le RNG avec un numéro différent chaque fois que vous lancez le programme. En utilisant le temps comme graine, vous obtenez un nombre différent chaque fois que vous lancez le programme.

30
Mysticial

Vous devez donner une graine au générateur de nombres aléatoires. Cela peut être fait en prenant l'heure actuelle, car il s'agit, espérons-le, d'une sorte d'aléatoire.

#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    int  r;
    srand(time(0));
    r = Rand();
    return 0;
} 
8
tune2fs

La fonction Rand() est spécifiquement requise pour produire la même séquence de nombres lorsqu'elle est semée avec une semence donnée (en appelant srand()); chaque valeur de départ possible spécifie une séquence. Et si vous n'appelez jamais srand(), vous obtenez la même séquence que vous auriez obtenue en appelant srand(1) avant tout appel à Rand().

(Cela ne s'applique pas à différentes implémentations C ou C++.)

Cela peut être utile à des fins de test. S'il y a un bogue dans votre programme, par exemple, vous pouvez le reproduire en le réexécutant avec la même graine, garantissant que (sauf autres comportements imprévisibles) vous obtiendrez la même séquence de nombres pseudo-aléatoires.

Appeler srand(time(NULL)) est la méthode recommandée pour obtenir des nombres pseudo-aléatoires plus ou moins imprévisibles. Mais ce n'est pas parfait. Si votre programme s'exécute deux fois dans la même seconde, vous obtiendrez probablement la même séquence, car time() (généralement) a une résolution de 1 seconde. Et les implémentations typiques de `Rand () ne sont pas assez bonnes pour une utilisation cryptographique; il est trop facile pour un attaquant de deviner quels nombres vous allez obtenir.

Il existe un certain nombre d'autres implémentations de nombres aléatoires. Les systèmes Linux ont deux pseudo-périphériques, /dev/random Et /dev/urandom, À partir desquels vous pouvez lire des valeurs d'octets pseudo-aléatoires de qualité raisonnablement élevée. Certains systèmes peuvent avoir des fonctions telles que random(), drand48(), etc. Et il existe de nombreux algorithmes; J'ai entendu de bonnes choses sur le Mersenne Twister .

Pour quelque chose comme un jeu, où vous ne vous attendez pas ou ne vous souciez pas des joueurs essayant de tricher, srand(time(NULL)) et Rand() est probablement assez bon. Pour des raisons plus sérieuses, vous devriez demander conseil à quelqu'un qui en sait plus sur ce sujet que moi.

La section 13 de la FAQ comp.lang.c contient de très bonnes informations sur la génération de nombres pseudo-aléatoires.

3
Keith Thompson

Les générateurs de nombres pseudo-aléatoires prennent un nombre de départ, ou graine, puis génèrent le nombre suivant dans la séquence à partir de cela. C'est pourquoi ils sont appelés pseudo-aléatoires, car s'ils utilisent toujours la même valeur de départ, ils généreront la même séquence de nombres que le générateur de lib C standard. Cela peut être corrigé en donnant au générateur une valeur de départ qui changera la prochaine fois que le programme sera exécuté comme l'heure actuelle.

Quoi qu'il en soit, le code que vous recherchez, comme d'autres l'ont dit, est:

srand(time(0)); //Seed the generator, give it a starting value
1
jgon