Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
901 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  [DOTNET] Probleme improbable de Random

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[DOTNET] Probleme improbable de Random

n°1758771
massanu
Posté le 12-07-2008 à 14:53:50  profilanswer
 

Bonjour :hello:
 
J'ai un probleme tres sympa de Random qui commence a bien me les casser :/
 
Je vous expose le truc
 
Je suis sur un bout de code pour un jeu de carte (rien d'exceptionel me direz vous)
 
J'ai une classe CARTE qui génère une carte avec un numéro.
 
Je doit tirer 5 cartes (5 différentes) et c'est LA que le problème survient
 
Dans le constructeur de la classe CARTE j'ai ceci :

Code :
  1. public Carte()
  2.         {
  3.             System.Random rnd = new System.Random(DateTime.Now.Millisecond * DateTime.Now.Millisecond);
  4.             _numero = rnd.Next(1,53) ;
  5.             _image = new Image();
  6.             _image.ImageUrl = "~/img/cards/" + _numero + ".png";
  7.             _valeur = "";
  8.             _couleur = "";
  9.         }


 
 
Elles sont crées tout simplement comme ceci :
 

Code :
  1. C1= new Carte();
  2.             C2= new Carte();
  3.             C3= new Carte();
  4.             C4= new Carte();
  5.             C5= new Carte();


 
Mais le problème c'est qu'il me fou a chaque fois les 5 mêmes cartes :(
 
Comprend vraiment pas pourquoi  
 
Si vous avez une idée, n'hesitez pas !
 
merci :jap:


Message édité par massanu le 12-07-2008 à 14:55:00
mood
Publicité
Posté le 12-07-2008 à 14:53:50  profilanswer
 

n°1758772
massanu
Posté le 12-07-2008 à 15:01:45  profilanswer
 

J'ajouterais meme a l'improbable ceci
 
Si je fais la même génération aléatoire sans passé par une création d'instance d'objet carte
 
En gros
 

Code :
  1. System.Random rnd = new System.Random(DateTime.Now.Millisecond * DateTime.Now.Millisecond);
  2.              _numero = rnd.Next(1,53) ;


 
Et bien cela me donne bien 5 numéros distinct  :heink:  
 
Je doit avoir un problème avec mes instances d'objet mais je ne sais guère lequel  :pt1cable:

n°1758773
ccp6128
Syntax error
Posté le 12-07-2008 à 15:07:32  profilanswer
 

A chaque carte que tu crées, tu réinitialises ta séquence random avec la même seed (puisque tes cartes sont créées quasi simultanément), puis tu tires le premier numéro de la séquence.
 
Normal que ce soit à chaque fois le même.
 
Initialise rnd une seule fois au début de ton programme, et pas à chaque création d'une carte.
 
De plus, il est tout à fait admissible de tirer deux fois la même carte avec ton implémentation. Pour tirer des cartes toutes différentes, il te faut supprimer les cartes déjà tirées de ta pile. Il y a différentes implémentations pour ca, je te laisse chercher un moment.

n°1758782
massanu
Posté le 12-07-2008 à 15:28:27  profilanswer
 

Merci pour ta réponse :jap:
 
- Si j'ai réinitialisé le seed à chaque fois, c'est parcequ'en l'initialisant une seule fois au départ, j'obtenais les mêmes cartes également
 
Ce qui me laisse pensé que le problème viens bien quand j'initialise les cartes dans le constructeur de la classe Carte

n°1759594
MagicBuzz
Posté le 15-07-2008 à 13:56:01  profilanswer
 

massanu a écrit :


- Si j'ai réinitialisé le seed à chaque fois, c'est parcequ'en l'initialisant une seule fois au départ, j'obtenais les mêmes cartes également


 
impossible, tu t'es planté quelque part.
 
initialise ton random en dehors de ta classe, et passe-le en paramètre à ton constructeur.
 
ou alors crée une classe static avec comme variable privée static le random, que tu initialise dans le constructeur static et ajoute une méthode static public "NextValue" :
 

Code :
  1. using System;
  2.  
  3. namespace SandBoxConsole
  4. {
  5.    class Program
  6.    {
  7.        static void Main(string[] args)
  8.        {
  9.            Console.WriteLine(new Carte());
  10.            Console.WriteLine(new Carte());
  11.            Console.WriteLine(new Carte());
  12.            Console.WriteLine(new Carte());
  13.            Console.WriteLine(new Carte());
  14.            Console.ReadKey(true);
  15.        }
  16.    }
  17.  
  18.    static class MyRandomGenerator
  19.    {
  20.        private static Random rnd;
  21.  
  22.        static MyRandomGenerator()
  23.        {
  24.            rnd = new Random();
  25.        }
  26.  
  27.        public static int NextValue(int max)
  28.        {
  29.                return rnd.Next(0, max) + 1;
  30.        }
  31.    }
  32.  
  33.    public class Carte
  34.    {
  35.        int numero = 0;
  36.  
  37.        public Carte()
  38.        {
  39.            numero = MyRandomGenerator.NextValue(52);
  40.        }
  41.  
  42.        public override string ToString()
  43.        {
  44.            return string.Format("Carte numéro {0}.", numero);
  45.        }
  46.    }
  47. }


 
(les puristes POO aiment pas ce raccourci .NET pour faire des singleton, mais moi j'aime bien, je trouve ça super simple d'utilisation)
 
Sortie :


Carte numéro 42.
Carte numéro 6.
Carte numéro 8.
Carte numéro 10.
Carte numéro 52.


 


Carte numéro 10.
Carte numéro 33.
Carte numéro 32.
Carte numéro 50.
Carte numéro 31.


 


Carte numéro 10.
Carte numéro 18.
Carte numéro 1.
Carte numéro 44.
Carte numéro 49.


 


Carte numéro 24.
Carte numéro 4.
Carte numéro 37.
Carte numéro 47.
Carte numéro 19.


 
(pour le reste, +1 avec cpp6128, tu peux tirer des doublons, c'est mal)
 
passe plutôt par un List<Carte> trié aléatoirement, et tu tires les 5 premières, en plus ça se comportera comme en vrai...

Message cité 1 fois
Message édité par MagicBuzz le 15-07-2008 à 14:15:26
n°1759611
MagicBuzz
Posté le 15-07-2008 à 14:17:03  profilanswer
 

ps : et à la base pas besoin de spécifier un seed à ton random, le seed automatique est plus "aléatoire", ce qui réduit la prédictabilité du résultat.


Message édité par MagicBuzz le 15-07-2008 à 14:17:34
n°1759678
massanu
Posté le 15-07-2008 à 15:09:59  profilanswer
 

MagicBuzz a écrit :


 
impossible, tu t'es planté quelque part.
 
initialise ton random en dehors de ta classe, et passe-le en paramètre à ton constructeur.
 
ou alors crée une classe static avec comme variable privée static le random, que tu initialise dans le constructeur static et ajoute une méthode static public "NextValue" :
 

Code :
  1. using System;
  2.  
  3. namespace SandBoxConsole
  4. {
  5.    class Program
  6.    {
  7.        static void Main(string[] args)
  8.        {
  9.            Console.WriteLine(new Carte());
  10.            Console.WriteLine(new Carte());
  11.            Console.WriteLine(new Carte());
  12.            Console.WriteLine(new Carte());
  13.            Console.WriteLine(new Carte());
  14.            Console.ReadKey(true);
  15.        }
  16.    }
  17.  
  18.    static class MyRandomGenerator
  19.    {
  20.        private static Random rnd;
  21.  
  22.        static MyRandomGenerator()
  23.        {
  24.            rnd = new Random();
  25.        }
  26.  
  27.        public static int NextValue(int max)
  28.        {
  29.                return rnd.Next(0, max) + 1;
  30.        }
  31.    }
  32.  
  33.    public class Carte
  34.    {
  35.        int numero = 0;
  36.  
  37.        public Carte()
  38.        {
  39.            numero = MyRandomGenerator.NextValue(52);
  40.        }
  41.  
  42.        public override string ToString()
  43.        {
  44.            return string.Format("Carte numéro {0}.", numero);
  45.        }
  46.    }
  47. }


 
(les puristes POO aiment pas ce raccourci .NET pour faire des singleton, mais moi j'aime bien, je trouve ça super simple d'utilisation)
 
Sortie :


Carte numéro 42.
Carte numéro 6.
Carte numéro 8.
Carte numéro 10.
Carte numéro 52.


 


Carte numéro 10.
Carte numéro 33.
Carte numéro 32.
Carte numéro 50.
Carte numéro 31.


 


Carte numéro 10.
Carte numéro 18.
Carte numéro 1.
Carte numéro 44.
Carte numéro 49.


 


Carte numéro 24.
Carte numéro 4.
Carte numéro 37.
Carte numéro 47.
Carte numéro 19.


 
(pour le reste, +1 avec cpp6128, tu peux tirer des doublons, c'est mal)
 
passe plutôt par un List<Carte> trié aléatoirement, et tu tires les 5 premières, en plus ça se comportera comme en vrai...


 
 
Nickel chrome, Merci :jap:
 
Je vais utilisé ce bout de code pour la génération aléatoire, j'espere que sa pourra aider d'autre personne :)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  [DOTNET] Probleme improbable de Random

 

Sujets relatifs
Problème caractères spéciaux et CuteNews (é, à, ç...)gros probleme avec gettext sous fedora
[PHP-MySQL] Problème récupération dernier ID d'une table.Probleme d'automatisation en VBA sous Excel
[Xlib] Problème de focus de fenêtreProblème avec visual basic .net, usercontrol, validating/enter event
probléme $_SESSION dans IE7Problème variable
4875+0.2332 = 4875.233398 problème précision float?probleme de passage de parametre avec accent.
Plus de sujets relatifs à : [DOTNET] Probleme improbable de Random


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR