IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

srand me donne des nombres croissants


Sujet :

C++

  1. #1
    Membre émérite Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Points
    2 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Points : 2 259
    Par défaut srand me donne des nombres croissants
    Bonjour à tous!
    J'ai un petit problème dont je ne comprend pas le "fonctionnement":
    Je me trouve présentement avec un classe Devinette qui réalise le simple jeux trouve le nombre.. trop petit... trop grand, je génère donc un chiffre aléatoire avec une classe Randomize, or il me génère bien des nombres aléatoire mais dans l'ordre croissant... Voici mes classes:
    Devinette
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    class Devinette
    {
    public :
        static enum {TROP_GRAND = 2, TROP_PETIT = -1, SUCCES = 1, AUCUN_TEST = 0};
        static enum {VALEUR_MINIMALE = 1, VALEUR_MAXIMALE = 100000};
        int iNombreAleatoire; 
    private :
        static Randomize GestionnaireAleatoire;
        unsigned int iNombreEssai;
        bool bReussite;
     
     
     
    public :
        Devinette();
        static bool EstNombreValide(int _nombre);
        int Essayer(int _nombre) ;
        bool EstReussi() const;
        unsigned int GetNombreEssais() const ;
     
    };
    Dans mon Devinette.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Randomize Devinette::GestionnaireAleatoire;
    Randomize
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    class Randomize
    {
     
    public:
     
        Randomize()
        {
           srand(static_cast<unsigned int>(time(0)));
        }
     
        static int GetRandomNumber(const int _max, const int _min)
        {
            return ((rand() % (_max - _min + 1)) + _min);
        }
    };
    Ayant passer pas mal de temps sur java, j'ai oublié un peu mes classiques de C++ .
    Ce que je ne comprend pas c'est pourquoi... Je ne pense pas qu'il s'agit d'un problème énorme... mais je ne vois pas le problème!
    Merci

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Points
    41 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Par défaut
    Tu devrais utiliser la formule passant par des floats, plutôt qu'un modulo.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Points
    3 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Par défaut
    il ne faut pas changer tout le temps le int en paramètre sinon tu réinitialises a chaque fois le générateur.

    The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand(). These sequences are repeatable by calling srand() with the same seed value.
    http://linux.die.net/man/3/srand

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Points
    41 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Par défaut
    Citation Envoyé par jabbounet Voir le message
    il ne faut pas changer tout le temps le int en paramètre sinon tu reinitiliser a chaque fois le générateur.
    Sauf qu'il s'agit d'une variable statique: Il n'est initialisé qu'une seule fois, ce qui est correct.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Points
    13 017
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Par défaut
    Bonjour,
    Il y a une discussion sur srand assez intéressante.

  6. #6
    Invité
    Invité(e)
    Par défaut
    A vue de nez, tu dois réinstancier ton générateur à chaque appel... (c'est la seule explication pour tes nombres croissants) Pour en etre sur, essaye de remplacer, dans le constructeur de randomize, time(0) par une valeur constante, et regarde si ton programme te renvoie toujours cette valeur...

    Si la valeur est toujours la même c'est forcément que GetRandomNumber() n'est pas appelée...

    Tu l'appelles comment GetRandomNumber()?

    Aussi, je ne suis pas certain de comprendre le static int devant sa déclaration... Ca en fait une fonction statique, je crois, mais sur une classe instanciée, dont on définit dans une autre classe une instance statique...

    Ca sent un peu le soufre, quoi...

    J'ai l'impression qu'un appel à srand() au début de l'application, puis des appels à rand(), sans cette classe Randomize qui semble être la cause de tous tes malheurs (et qui n'apporte rien) te mènerait assez loin.

    Francois

  7. #7
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Points
    3 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Par défaut
    Je confirme un utilisation incorrecte de la classe Randomize peux donner de mauvais résultats.

    Quand je recrée a chaque fois Randomize, j'ai un résultat constant (probablement due à la granularité de la fonction time).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    #include <iostream>
     
    class Randomize
    {
     
    public:
     
        Randomize()
        {
           srand(static_cast<unsigned int>(time(0)));
        }
     
      static int GetRandomNumber(const int _max, const int _min)
      {
        return ((rand() % (_max - _min + 1)) + _min);
      }
    };
     
     
    int getBadRand() {
      Randomize *r = new Randomize();
      //  sleep(1);
      int random = r ->  GetRandomNumber(1000000,0);
      delete r;
      return random;
    }
     
     
    int main(int argc,char* *argv)
    {
      Randomize *r = new Randomize();
     
      std::cout << "Correct random generation :"  << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl;
      delete r;
     
      std::cout << "Bad random generation :"  << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl;
     
      return 0;
    }
    g++ randomtest.cpp -o randomtest && ./randomtest
    Correct random generation :
    215328
    170112
    138454
    184037
    39074
    346258
    110469
    271663
    856304
    Bad random generation :
    856304
    856304
    856304
    856304
    856304
    856304
    856304
    856304
    856304

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Points
    41 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Par défaut
    En effet, pour ce genre de choses, il vaut mieux rendre la classe entièrement statique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <iostream>
     
    class Randomize
    { 
    private:
        Randomize()
        {
           srand(static_cast<unsigned int>(time(0)));
        }
     
        static Randomize instance;
    public:
      static int GetRandomNumber(const int _max, const int _min)
      {
        //je ne sais plus si c'est nécessaire,
        //mais je veux être sûr que l'instance soit créée.
        (void)instance;
        //Retourne une nouvelle valeur.
        //La version float serait préférable.
        return ((rand() % (_max - _min + 1)) + _min);
      }
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Randomize Randomize::instance;
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    En effet, pour ce genre de choses, il vaut mieux rendre la classe entièrement statique:
    Oui, mais alors, il va falloir qu'on m'explique l'intéret de la classe, par rapport à un bête srand() au début du programme et une fonction "libre" GetRand(min,max) qu'on appelle quand on a besoin...

    Une classe entièrement statique, sans données membres, et n'ayant qu'une fonction, j'avoue que je ne vois pas l'utilité.

    Francois

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Points
    41 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Par défaut
    Le seul avantage est que srand() est automatiquement appelé, ce qui en vaut pas forcément grand-chose.

    Les vraies classes Random sont supposées maintenir leur propre statut, ce qui permet d'avoir des données reproductibles sans déranger les autres parties du programme qui ont besoin de valeurs pseudo-aléatoires (et potentiellement reproductibles).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Points
    2 205
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Par défaut
    Ne jamais utilisé le modulo avec le résultat de rand(). (y'a bien une entrée de la faq là dessus non?)

  12. #12
    Membre habitué
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Points
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Points : 168
    Par défaut
    voui : la faq c
    --
    Jérémie

  13. #13
    Membre émérite Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Points
    2 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Points : 2 259
    Par défaut
    D'abord veuillez m'excuser pour le retard!( d'autres petits trucs à faire).
    Oui, mais alors, il va falloir qu'on m'explique l'intéret de la classe, par rapport à un bête srand() au début du programme et une fonction "libre" GetRand(min,max) qu'on appelle quand on a besoin
    Si j'ai fais comme ceci c'est que certaines restrictions m'étais posées:
    1_ ne pas appeler srand() dans le main
    2_ ne pas appeler srand() dans le constructeur de devinette (en cas de création multiple d'objet)
    3_ Le main m'était déjà fourni et je dois donc le faire fonctionner en créant la/les classes correctes.

    J'ai donc choisi cette solution.

  14. #14
    Membre émérite Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Points
    2 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Points : 2 259
    Par défaut
    Citation Envoyé par fcharton Voir le message
    A vue de nez, tu dois réinstancier ton générateur à chaque appel... (c'est la seule explication pour tes nombres croissants) Pour en etre sur, essaye de remplacer, dans le constructeur de randomize, time(0) par une valeur constante, et regarde si ton programme te renvoie toujours cette valeur...
    Lorsque je remplace par un nombre fixe , j'obtiens toujours la même valeur effectivement.

    Citation Envoyé par fcharton Voir le message
    Si la valeur est toujours la même c'est forcément que GetRandomNumber() n'est pas appelée...

    Tu l'appelles comment GetRandomNumber()?
    Je l'appel dans le constructeur de Devinette:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Randomize Devinette::GestionnaireAleatoire;
     
    Devinette::Devinette()
    {
        iNombreEssai = 0;
        bReussite = false;
        iNombreAleatoire = GestionnaireAleatoire.GetRandomNumber(VALEUR_MAXIMALE,VALEUR_MINIMALE);
    }
    Citation Envoyé par fcharton Voir le message
    Aussi, je ne suis pas certain de comprendre le static int devant sa déclaration... Ca en fait une fonction statique, je crois, mais sur une classe instanciée, dont on définit dans une autre classe une instance statique...
    Effectivement, j'ai retiré le static de la fonction GetRandomNumber qui n'avais aucun intérêt (oublie de ma part).

    Citation Envoyé par jabbounet Voir le message
    Je confirme un utilisation incorrecte de la classe Randomize peux donner de mauvais résultats.

    Quand je recrée a chaque fois Randomize, j'ai un résultat constant (probablement due à la granularité de la fonction time).
    Je ne vois vraiment pas la différence entre la fonction GetRandomNumber et ton getBadRand(), a part le faite que srand sois toujours rappelé. Mais mon but est de l'appeller une seule fois. De créer plusieur objet si je le désire de Devinette mais que srand ne sois appelé que 1 seule et même fois dans tout la durée de vie du programme.
    Donc j'ai pensé à le faire dans un contexte static de la fonction Devinette afin que le constructeur de Randomize ne sois appelé qu'une seule fois.

    Voici comment il est utilisé dans le main ( Auquel je ne dois rien toucher ):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    int main ()
    {
       cout << "Bienvenue au jeu des devinettes" << endl;
       cout << "Entrez un nombre entre "
            << Devinette::VALEUR_MINIMALE
            << " et "
            << Devinette::VALEUR_MAXIMALE
            << " inclusivement: ";
       Devinette d;
       int Nombre;
       do
       {
          while (!(std::cin >> Nombre && Devinette::EstNombreValide (Nombre)))
          {
             cerr << "Entrez un nombre entre "
                  << Devinette::VALEUR_MINIMALE
                  << " et "
                  << Devinette::VALEUR_MAXIMALE
                  << " inclusivement: ";
          }
          switch (d.Essayer (Nombre))
          {
          case Devinette::TROP_GRAND:
             cout << "Le nombre " << Nombre
                  << " est trop grand; essayez à nouveau" << endl;
             break;
          case Devinette::TROP_PETIT:
             cout << "Le nombre " << Nombre
                  << " est trop petit; essayez à nouveau" << endl;
             break;
             // les autres cas possibles sont SUCCES et AUCUN_TEST
          }
       }
       while (!d.EstReussi ());
       cout << "Vous avez réussi en "
            << d.GetNombreEssais ()
            << " essais" << endl;
    }

  15. #15
    Membre émérite Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Points
    2 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Points : 2 259
    Par défaut
    Je viens d'essayer aussi avec la méthode de la FAQ!
    J'obtiens exactement le même problème, nombre croissant...
    J'ai fais aussi un autre essaye en instanciant 3 Devinettes et j'obtiens 3 résultats totalement différents, mais quand je relance le programme, les résultats sont bien différents mais tous reçoivent la même incrémentation...

    Le faite de lancer le programme, puis de l'éteindre, puis de la relancé, ne devrait-il pas recréer des nombres aléatoires mais pas croissant... ou est-ce un des problèmes des fonctions srand() et rand() qui travail sur le nombre de seconde depuis plusieurs années et me donne du pseudo-aléatoire(ce qu'elle fais) que me donne toujours un premier chiffre proche avec quelque "seconde"/"indice" de plus sur le nombre généré?

    Je me demande si c'est pas ça le problème ^^

  16. #16
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Points
    2 205
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Par défaut
    Tu le relances vraiment vite? Si oui alors cherche pas c'est ça. La graine de départ est très proche...

  17. #17
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Points
    3 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Par défaut
    Je ne vois vraiment pas la différence entre la fonction GetRandomNumber et ton getBadRand(), a part le faite que srand sois toujours rappelé. Mais mon but est de l'appeller une seule fois. De créer plusieur objet si je le désire de Devinette mais que srand ne sois appelé que 1 seule et même fois dans tout la durée de vie du programme.
    la différence est simple :
    * Dans le premier cas, j'appelle une seule et unique fois le constructeur de Randomize ensuite j'appelle getRandomNumber() à chaque fois que je veux un nombre
    * Dans le second cas, avec getBadRand(), je reconstruis l'objet Randomize à chaque fois ce qui fait que le générateur relance srand à chaque fois qui fait que le générateur se fait réinitialiser à chaque fois....


    Donc en fonction de l'utilisation que tu fais de la classe Randomize que tu as fournis, avec son implémentation actuelle, tu peux avoir le comportement attendu ou pas.


    pour résoudre ton problème il faut que tu trouve le moyen d'appeler srand une seule et unique fois dans ton programme, voici deux solution pour ça assez proches en fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    class Randomize
    {
    private:
      static bool isInitialized; // A initialiser à false dans le .c    
    public:
     
        Randomize() {
           if (isInitialized == false) {  
                  srand(static_cast<unsigned int>(time(0)));
                  isInitialized = true;
          }
        }
     
        static int GetRandomNumber(const int _max, const int _min) {
            return ((rand() % (_max - _min + 1)) + _min);
        }
    };
    Ou alors en faire un singleton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    class Randomize
    {
    private:
      static Randomize * _randomize;// A initialiser a NULL dans le .c
      Randomize() {
          srand(static_cast<unsigned int>(time(0)));
      }
      ~Randomize () {
          if (_randomize != NULL) { delete _randomize; }
      }
     
    public:
      static Randomize *getInstance() {
          if (_randomize == NULL) {
              _randomize = new Randomize();
          }
          return _randomize;
      } 
     
      static void destroyInstance() {
          if (_randomize != NULL) {
              delete _randomize;
              _randomize = NULL;
          }
          return _randomize;
      } 
     
      static int GetRandomNumber(const int _max, const int _min) {
          return ((rand() % (_max - _min + 1)) + _min);
      }
    };
    Je n'ai pas de compilo sous la main aujourd'hui donc j'ai pu faire des coquilles.


    et donc dans ton appli a chaque fois que tu as besoin du générateur tu en demande une instance avec getInstance() ce qui te retourne le générateur déjà initialisé et prêt à être réutilisé.


    à la fin de ton programme avant de quitter tu nettoie avec destroyInstance() qui ne devrais normalement être appelé qu'une seule fois dans toute ton appli.

  18. #18
    Membre émérite Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Points
    2 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Points : 2 259
    Par défaut
    Citation Envoyé par Goten
    Tu le relances vraiment vite? Si oui alors cherche pas c'est ça. La graine de départ est très proche...
    Oui assez vite, quelque seconde ou minute de décalage.

    A jabbounet:
    Est-ce vraiment utile sachant que cette classe est implémentée de façon statique dans ma classe Devinette, donc à chaque création d'objet Devinette, srand ne sera appelé que 1 seule fois et chaque objet pourra demander son propre numéro alétoire avec GetRandomNumber.

  19. #19
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Points
    3 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Par défaut
    Citation Envoyé par Astraya Voir le message
    Oui assez vite, quelque seconde ou minute de décalage.

    A jabbounet:
    Est-ce vraiment utile sachant que cette classe est implémentée de façon statique dans ma classe Devinette, donc à chaque création d'objet Devinette, srand ne sera appelé que 1 seule fois et chaque objet pourra demander son propre numéro alétoire avec GetRandomNumber.
    As tu vérifié que srand était vraiment appelé une seule fois (trace, debugger)? car chez moi quand je ne l'appelle qu'une seule fois je n'ai pas de problème, par contre j'ai un problème similaire quand je l'appelle plusieurs fois.

    Tu peux aussi t'arranger pour que ta graine sois moins linéaire / prévisible qu'un appel a time en appliquant une fonction dessus. tu peux aussi utiliser une fonction avec une granularité plus fine genre gettimeofday en reprenant la partie en microseconde de la structure comme graine.

    Autrement tu peux jeter un oeil du coté d'autre fonction de génération genre lrand48

  20. #20
    Membre émérite Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Points
    2 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Points : 2 259
    Par défaut
    oui oui, je suis sur qu'il ne l'appel que une seule fois! Lorsque j'instancie plusieurs fois Devinette dans le même programme je n'ai pas de problème.

    Je n'ai un problème que lorsque je relance l'application, sachant que c'est un jeu, l'utilisateur ouvre le jeu, fait la devinette et ce ferme, mais si il décide d'en refaire une autre, il relance l'application, et obtiens un nombre aléatoire qui est à quelque chiffre au dessus.

    Je sais que le mieux aurait été de demander à la fin si le joueur voulais rejouer mais je n'ai pas choisi mon main()!

    Le problème doit se situer au niveau de la graine qui est proche comme Goten et toi le faisais savoir. Je vais me renseigner sur ce que tu m'a apporté!

    En attendant merci à tous pour votre aide!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. donne le nombre des mois entre deux dates
    Par Sokol dans le forum SAS Base
    Réponses: 1
    Dernier message: 09/11/2009, 13h55
  2. [Batch] Trier des nombres ordre croissant dans fichier texte
    Par AZzjeioafh dans le forum Scripts/Batch
    Réponses: 20
    Dernier message: 01/11/2009, 11h22
  3. algo qui affiche par ordre croissant des nombres
    Par jeremdu69300 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 19/09/2008, 00h16
  4. Réponses: 1
    Dernier message: 09/11/2007, 19h40
  5. Probleme de tri croissant pour des nombres
    Par sebastien_oasis dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 11/08/2007, 11h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo