Fonction Random qui renvois le même resultat

Signaler
-
krimog
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
-
Bonjour ,

Voila j'essaye de mettre ma fonction random dans une fonction mais quand j'appelle ce dernière , elle me revois toujours le même résultat.
Je ne comprend pas pourquoi cela ne fonctionne pas ce que je fais de pas bien ^^. Merci d'avance.



class Program
    {


        // Fonction qui retourne le resultat d'un dé 6 faces
        static int UnDeSixFaces()
        {
            Random rand = new Random();
            int Lancer = rand.Next(1, 7);
            return Lancer;
        }





        static void Main(string[] args)
        {
            int Lancer;
         

            // Boucle pour faire une centaines de lancers
               for (int i = 1; i <= 100; i++)
                {

                    // Appel de la fonction pour avoir un résultat de dé.
                    Lancer = UnDeSixFaces();



                    // Pour que tous les 10 lancers je passe a la ligne.
                    if ((i % 10) == 0)
                        Console.WriteLine(" {0} ", Lancer);
                    else
                        Console.Write(" {0} ", Lancer);

                }
                Console.ReadKey();
        }
    }

7 réponses

Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
38
Salut

La correction du problème a été évoquée avant (le fait de ne pas faire un new Random() à chaque fois). Je ne vais pas donc répéter ce que disent les autres, mais expliquer pourquoi.

La classe Random ne permet (malheureusement) pas de faire un nombre aléatoire. Ca donne une suite fixe de nombres dits pseudos aléatoires. Mais comme je viens de le dire, cette liste est fixe. Si tu te positionne, au départ, au même endroit, la suite sera toujours la même.

Simplifions le truc, imaginons cette suite de nombres :
5 3 1 7 6 2 4 1 9 6 5 0 0 8
Si tu commences au troisème nombre, tu obtiendra d'abord 1, puis 7, puis 6... Si tu en crées un nouveau, et que tu commences à nouveau au troisième nombre, tu obtiendra 1, puis 7, puis 6, c'est à dire exactement la même suite.

C'est (à peu près) ainsi que Random fonctionne.
            Random r = new Random(20);
            for (int i = 0; i < 5; i++)
            {
                Console.Write(r.Next(0, 10) + " ");
            }
            Console.ReadLine();

Dans ce code, avec new Random(20), il commence au 20ième nombre de sa suite. A chaque fois. J'aurai donc TOUJOURS 1 6 7 8 2 comme résultat de ce programme. Si je ne fais pas la boucle, j'aurai donc toujours 1.

Que se passe-t-il quand tu appelles le constructeur de Random sans paramètre (new Random()) ? Si je décompile les DLL du framework, je vois que new Random() appelle new Random(Environment.TickCount).
public Random() : this(Environment.TickCount)
{
}


Environment.TickCount correspond au nombre de millisecondes écoulées depuis le démarrage du système. Autant dire que c'est extrêmement variable. Donc c'est parfait pour définir où commencer dans la liste.

Cependant, il faut bien se rendre compte qu'un ordinateur peut faire un nombre de choses incroyable en une milliseconde. Par exemple, te générer tes 100 dés. Donc puisque la milliseconde ne s'est pas écoulée, ton new Random() sera généré à partir du même nombre. Ainsi, chaque nombre généré sera le même (puisqu'on ira le chercher au même endroit de la même suite).
En revanche, si tu augmente de manière drastique le nombre de dés ou que tu mets de pauses entre chaque "tirage" de dé, ça prendra plus d'une millisecondes, et tu finiras par avoir des valeurs différentes.

Et en cadeau, ton programme corrigé :
class Program
{

    private static Random _rand = new Random();
    // Fonction qui retourne le resultat d'un dé 6 faces
    static int UnDeSixFaces()
    {
        int Lancer = _rand.Next(1, 7);
        return Lancer;
    }





    static void Main(string[] args)
    {
        int Lancer;


        // Boucle pour faire une centaines de lancers
        for (int i = 1; i <= 100; i++)
        {

            // Appel de la fonction pour avoir un résultat de dé.
            Lancer = UnDeSixFaces();



            // Pour que tous les 10 lancers je passe a la ligne.
            if ((i % 10) == 0)
                Console.WriteLine(" {0} ", Lancer);
            else
                Console.Write(" {0} ", Lancer);

        }
        Console.ReadKey();
    }
}


Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Vraiment désolé, du double poste je ne trouve pas de bouton editer.

Je voulais juste tester le random sous fonction voir cela fonctionne bien, car je souhaite a terme le mettre dans une fonction dans un objet.
Donc possible que cela ne fonctionne pas ici ( me revois toujours la même valeur) mais d'un lancement a un autre la valeur changent évidements, comme s'il ne "piochait" qu'une valeur.
Messages postés
224
Date d'inscription
vendredi 26 novembre 2010
Statut
Membre
Dernière intervention
11 juin 2013
2
Bonjour,

Essaies en mettant une pause entre chaque lancement dans ta boucle for pour voir si ca marche(genre Thread.Sleep(50)).
Messages postés
14446
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
5 avril 2020
370
Bonjour

essaye comme ça

        private int LancerDeDe()
        {
            Random rnd = new Random((int)DateTime.Now.Ticks);//là au moins tu es sur d'initialiser ton random de façon différente que lors de ton dernier appel.
            return rnd.Next(1, 7);
        }



Whismeril
Messages postés
3172
Date d'inscription
dimanche 15 février 2004
Statut
Membre
Dernière intervention
9 avril 2017
28
Bonjour

Car il faut utiliser la même instance de Random à chaque fois :
Soit tu la déclare avant la boucle et tu la passe en paramètre de ta fonction UnDeSixFaces.
Soit tu déclare le Random en static directement dans ta class.

Préfère la première solution mais ca dépend aussi de ce que tu veux faire par la suite.

_____________
Kenji
Merci bien a toutes vos réponses.

C'est pour but final d'entré dans une classe objet ou j'airais besoin de faire plusieurs lancés de dés, deux dés voir plus en simultané.
Je vais tester tout ceci tout a l'heure et mettrais a solution adoptée en réponses choisie. Merci a tous en tous cas des conseils.

En revanche, comment passer une fonction en paramètre ?

static type nomfonction1 (fonction nomfonction2) ?
static type nomfonction1 (type nomfonction2) ?
Messages postés
265
Date d'inscription
dimanche 14 avril 2013
Statut
Membre
Dernière intervention
23 mai 2014
1
Salut
Tu ne peux pas passer une fonction en paramètre. Ce que Charles Racaud t'a dit, c'Est de passer ton OBJET Random en paramètre :
static int UnDeSixFaces(Random rand)
{
int Lancer = rand.Next(1, 7);
return Lancer;
}

et dans ton main :
Random rand = new Random();
for(int i=0;i<1000;i++)
Lancer = UnDeSixFaces(rand);



@+. Hermios