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 :

[C++14] L'aléatoire, le retour


Sujet :

C++

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut [C++14] L'aléatoire, le retour
    EDIT : Bon finalement ma question se résume à comment initialisé un générateur en attribut d'une classe avec std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count() car ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class x
    {
    ....
    private:
    std::default_random_engine engin{std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count()}
     
    }
    ne fonctionne pas car indique une erreur de conversion


    Bonjour à tous, il y a peu j'ai commencé à vouloir mettre en place un système de génération aléatoire pour diverses choses. L'aléatoire en lui-même n'est pas vraiment un problème. Où le définir par contre, en est un. En fait, j'ai testé environ une vingtaine de combinaison différente pour créer de l'aléatoire dans mon jeu, et en allant au bout de chacun de ces chemins je me suis retrouvé envers des impasses. J'ai tout essayé et tout à un gros problème :

    - 1 Déclaré une seed prenant un rapport au temps, en attributs de classe. -> Très bien, mais le générateur est déclaré dans un membre donc forcément à chaque itération les nombres sont les mêmes vu que la seed ne change pas et que le générateur recommence depuis le début.
    - 2 Déclaré une seed prenant un rapport au temps, en attributs de classe mais créer une fonction pour la mettre à jour à chaque fois qu'on utilise le générateur. -> Super aussi, sauf que la fonction qui utilise le générateur est const ( et ne peux que rester comme ceci )( Mais il y a mutable ).
    - 3 Déclaré un générateur en attributs de classe -> Et la seed pour l'aléatoire alors ?
    - 4 Déclaré un générateur en attributs de classe avec une seed prenant un rapport au temps -> Non, les erreurs de conversions qui n'était pas présente en créant une variable auto et en la mettant en seed, le sont désormais .
    - 5 Déclaré un générateur en attributs de classe avec une seed qui est aussi un attribut de classe prenant un rapport au temps -> Bah non, car auto c'est pas static .
    - 6 Déclaré un générateur en attributs de classe avec une seed static qui est aussi un attribut de classe prenant un rapport au temps et en l'initialisant dans le constructeur -> Et .... Non ! erreur de conversion aussi bizarrement
    - 7 *Rollback* Déclaré un générateur dans le main, initialisé avec une seed temporelle pour pouvoir par la suite via je ne sais quel méthode utilisé le générateur pour une classe en attribut d'une autre classe -> Bah là clairement c'est pas propre et je vois pas trop comment faire ça sauf en utilisant une chiadées de références.
    - 8, 9, et cetera... -> Bla bla bla, bla bla.. fonctionne pas !

    Donc bon pour le coups j'avais jamais utilisé correctement l'aléatoire pour ce genre de choses mais alors là je suis encore plus perdu pour l'utilisé tout court.

    Bon maintenant voici quelques choses importantes :
    - Je travail avec à la norme 2014 du C++
    - J'utilise et je doit utilisé un générateur non-déterministe prenant une seed temporelle qui doit être précise (donc pas de std::time(nullptr) car rapport en seconde, il me faut un rapport en millisecondes minimum ).
    - C'est un RPG.
    - C'est du brouillon tout frais, sans commentaires mais il n'y à pas beaucoup de lignes.

    Et maintenant le fameux code ( Je l'ai mit de façon qu'il fonctionne pour que vous puissiez tester mais il ne donne pas le résultat attendu évidemment. Les endroits avec écrit "/// ERREUR DE CONCEPTION" sont les parti qui devront donc ne plus exister quand j'aurais la solution ) :

    main.cpp


    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
     
    #include <iostream>
    #include "Player.hpp"
    #include "Monster.hpp"
     
    using namespace std;
     
    int main()
    {
        /*non utilisé*/
        auto const seed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
        std::default_random_engine engin{seed};
        ///... ref/np/ ca ?
     
        /// TEST MONSTRE
        std::vector<Spell> spells;
        Spell spell_1("Coup de pied", 3, 8, 4, 20 );
        Spell spell_2("Coup de poing", 1, 10, 5, 12 );
        spells.push_back(spell_1);
        spells.push_back(spell_2);
        Monster monster( "Lutin", 1, 100, 46, 100, 1, spells );
     
        std::vector<std::tuple<std::string, unsigned int, bool>> monster_atk{monster.attack()};
        for( size_t i{0}; i < monster_atk.size(); ++i )
        {
            std::cout << monster.name() << " utilise " << std::get<0>(monster_atk[i]) << " et vous inflige " << std::get<1>(monster_atk[i]) << " degats";
            if( std::get<2>(monster_atk[i]) == true )
                std::cout << ", coup critique !" << std::endl;
            else
                std::cout << '.' << std::endl;
        }
     
        /// TEST JOUEUR // prévoir serial de la class // éléments // focntion affich          /** Effacer ce code et include Player pour tester le code **/
        Player player( "Xyliaris", 100 );
        cout << player.name() << " vie : " << player.life() << '/' << player.lifeMax() << endl;
        player.setLife(50);
        cout << player.name() << " vie : " << player.life() << '/' << player.lifeMax() << endl;
        return 0;
    }
    Monster.hpp


    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
     
    #ifndef Monster_included
    #define Monster_included
     
    #include <iostream>
    #include <vector>
    #include <tuple>
    #include <random>
    #include <chrono>
     
    #include "Spell.hpp"
     
    class Monster
    {
    public:
     
        Monster();
        Monster( std::string const &name, unsigned int const &level, unsigned short const &actions, unsigned int const &life, unsigned int const &xpToDrop, float const &force, std::vector<Spell> const &spells );
        ///constructeur copie
        std::string name() const;
        std::vector<std::tuple<std::string, unsigned int, bool>> attack() const;
        unsigned int getXp() const;
        unsigned int life() const;
        unsigned int maxLife() const;
        unsigned int level() const;
        bool isAlive() const;
     
    private:
     
        std::string const monster_name;
        unsigned int monster_life_max;
        unsigned int monster_life;
        unsigned int const monster_drop_xp;
        unsigned int const monster_level;
        float monster_force;
        std::vector<Spell> monster_spells;
        unsigned short monster_actions;
        float monster_critical_chance;
     
    };
     
    #endif // Monster_included
    Monster.cpp


    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
    59
    60
    61
    62
    63
    64
    65
    66
     
    #include "Monster.hpp"
     
    Monster::Monster() : monster_name{"???"}, monster_life_max{0}, monster_life{0}, monster_drop_xp{0}, monster_level{0}, monster_force{0}, monster_actions{0}, monster_critical_chance{0}
    {
        monster_spells.push_back(Spell());
    }
     
    Monster::Monster( std::string const &name, unsigned int const &level, unsigned short const &actions, unsigned int const &life, unsigned int const &xpToDrop, float const &force, std::vector<Spell> const &spells ) : monster_name{name}, monster_life_max{life}, monster_life{life}, monster_drop_xp{xpToDrop}, monster_level{level}, monster_force{force}, monster_spells{spells}, monster_actions{actions}
    {
        monster_critical_chance = 90.0f;
    }
     
    std::string Monster::name() const
    {
        return monster_name;
    }
     
    std::vector<std::tuple<std::string, unsigned int, bool>> Monster::attack() const
    {
        std::vector<std::tuple<std::string, unsigned int, bool>> attacks;
     
        auto const seed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); /// ERREUR DE CONCEPTION
     
        std::default_random_engine engin{ seed }; /// ERREUR DE CONCEPTION
        std::uniform_int_distribution<> distrib( 0, monster_spells.size() - 1);
        std::uniform_int_distribution<> crit(static_cast<int>(monster_critical_chance),100); // pas d'erreur de conception, ce n'est pas du pourcentage mais float porte à confusion
        unsigned int selector{0};
     
        for( size_t i{0}; i < monster_actions; ++i )
        {
            selector = distrib(engin);
            if( crit(engin) == 100 )
                attacks.push_back(std::make_tuple(monster_spells[selector].name(), static_cast<unsigned int>(monster_spells[selector].dmgCrit() * monster_force), true ));
            else
                attacks.push_back(std::make_tuple(monster_spells[selector].name(), static_cast<unsigned int>(monster_spells[selector].dmg() * monster_force), false ));
        }
        return attacks;
    }
     
    unsigned int Monster::getXp() const
    {
        return monster_drop_xp;
    }
     
    unsigned int Monster::life() const
    {
        return monster_life;
    }
     
    unsigned int Monster::maxLife() const
    {
        return monster_life_max;
    }
     
    unsigned int Monster::level() const
    {
        return monster_level;
    }
     
    bool Monster::isAlive() const
    {
        bool b{false};
        b = monster_life == 0 ? false : true;
        return b;
    }
    Spell.hpp


    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
     
    #ifndef Spell_included
    #define Spell_included
     
    #include <iostream>
    #include <random>
    #include <chrono>
     
    class Spell
    {
    public:
     
        Spell();
        Spell( std::string const &name, unsigned short const &dmgMin, unsigned short const &dmgMax, unsigned short const &dmgCritMin, unsigned short const &dmgCritMax );
     
        std::string name() const;
        unsigned short dmg() const;
        unsigned short dmgCrit() const;
     
    private:
     
        std::string const spell_name;
        unsigned short const spell_dmg_min;
        unsigned short const spell_dmg_max;
        unsigned short const spell_dmg_crit_min;
        unsigned short const spell_dmg_crit_max;
    };
     
    #endif // Spell_included
    Spell.cpp


    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
     
    #include "Spell.hpp"
     
    Spell::Spell() : spell_name{"???"}, spell_dmg_min{0}, spell_dmg_max{0}, spell_dmg_crit_min{0}, spell_dmg_crit_max{0}
    {
     
    }
     
    Spell::Spell( std::string const &name, unsigned short const &dmgMin, unsigned short const &dmgMax, unsigned short const &dmgCritMin, unsigned short const &dmgCritMax ) : spell_name{name}, spell_dmg_min{dmgMin}, spell_dmg_max{dmgMax}, spell_dmg_crit_min{dmgCritMin}, spell_dmg_crit_max{dmgCritMax}
    {
     
    }
     
    std::string Spell::name() const
    {
        return spell_name;
    }
     
    unsigned short Spell::dmg() const
    {
        auto const seed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); /// ERREUR DE CONCEPTION
        std::default_random_engine engin{seed}; /// ERREUR DE CONCEPTION
        std::uniform_int_distribution<> distrib( spell_dmg_min, spell_dmg_max );
        return static_cast<unsigned short>(distrib(engin));
    }
     
    unsigned short Spell::dmgCrit() const
    {
        auto const seed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); /// ERREUR DE CONCEPTION
        std::default_random_engine engin{seed}; /// ERREUR DE CONCEPTION
        std::uniform_int_distribution<> distrib( spell_dmg_crit_min, spell_dmg_crit_max );
        return static_cast<unsigned short>(distrib(engin));
    }
    Donc bon j'ai vraiment besoin d'aides car je ne sais plus quoi faire, même si j'ai des solutions, je ne les trouves pas propres.
    Je vous remercie de bien vouloir m'aider :/

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Y'a pas 500 solutions.
    Soit tous les objets ont leur propre générateur, soit ils en partagent un. Ca dépend juste de la granularité voulue.
    Et s'ils le partagent, le mettre en static de leur class c'est surement un bon endroit.
    Quant à l'utilisation du générateur dans une fonction const, c'est eaxctement à ça que sert mutable.

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Y'a pas 500 solutions.
    Soit tous les objets ont leur propre générateur, soit ils en partagent un. Ca dépend juste de la granularité voulue.
    Et s'ils le partagent, le mettre en static de leur class c'est surement un bon endroit.
    Quant à l'utilisation du générateur dans une fonction const, c'est exactement à ça que sert mutable.
    Merci, mais si je déclare ma seed mutable et que deux sorts sont demandé trop rapidement alors j'ai la même valeur, donc il reste le problème du générateur, si je le met en attribut de class, même si il est static, alors dans ce cas ma seed sert à rien vue que je peux pas le changé de seed ? Ou alors j'utilise pas de seed et je l'init direct avec une seed... mais ça ça me donner des erreurs de conversion...
    Désolé si je comprend pas grand chose à <random>

    Edit: enfaite il aurai fallu pourvoir faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class x
    {
     
    public:
     
       x();
     
    private:
     
       std::default_random_engin endin{std::time(nullptr)};
     
    };
    Et ça serai réglé, mais ça fonctionne pas
    alors que si je fait ceci dans une fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
       auto const seed = std::time(nullptr);
       std::default_random_engin endin{seed};
    ça fonctionne.. Pourtant auto ne fait pas de conversion ? ou alors c'est pas un problème de conversion mais mon compilo me dit ça ? ( toujours faire confiance au compilo donc je pense pas ).
    Enfin bref si tu peux me donner du code en exemple et m'expliquer pourquoi ça fonctionne et aussi m'expliqué le truc avec auto ce serais cool ( j'ai cherché de la doc (cppreference) et j'avoue que ça m'a pas vraiment aider ).

    Ps: et enfaîte j'essaye de n'avoir pratiquement rien dans mon main donc c'est pour ça que je veux que les class ai leur propre générateur

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Un générateur ça s'initialise 1 fois avec 1 seed, pas à chaque appel

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    bah oui ? le sort n'est créé q'une seul fois, donc si le générateur est en attribut ce n'est pas un problème vu qu'il n'y auras pas à chaque fois de nouvelle instance, donc je comprend pas trop pourquoi tu dit ça ? :/ Si tu parle de la fonction, c'était un exemple

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 580
    Points : 7 712
    Points
    7 712
    Par défaut
    On reprend :
    Un générateur ça s'initialise 1 fois avec 1 seed, pas à chaque appel.

    On ne peut pas faire std::default_random_engin endin{std::time(nullptr)}; pour définir un membre car un membre ne peut être préinitialisé que par une constante entière de compilation, et std::time(0) ne l'est certainement pas.
    On peut créer le générateur dans l'objet (en static) et faire le seed une unique fois. Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class X {
       static std::default_random_engin endin;
    public:
       static void preInit() { endin.seed( std::time(nullptr) ); }
    };
    int main() {
       X::preInit(); // init une fois pour toute
    }

  7. #7
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Okkk je comprend mieux maintenant, je vais aérai tout mon code et bon seul défaut c'est que je suis obligé d’appelé une fonction dans mon main mais si je n'ai pas le choix alors tempis, au pire je ferais une class Game pour mettre tout ces bouts d'initialisation etc dedans. Je te remercie ( et merci aussi à bousk :p ), ça paraît toujours logique dès qu'on à la solution x). Bien, sujet résolue

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 163
    Points
    17 163
    Par défaut
    Une variante serait de passer par une capsule singleton du générateur, pour ne pas avoir besoin d'un appel magique dans le main.

  9. #9
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Moi je préfère l'appel à un endroit déterminé, ça a l'avantage d'être... déterministe.

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Sauf cas particulier genre RTS multijoueur où utilisation pour replay, on se moque dans 99% des cas de la seed et englober le générateur dans une classe qui l'initialise via son simple constructeur est tout à fait légitime imo.

  11. #11
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 163
    Points
    17 163
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    Moi je préfère l'appel à un endroit déterminé, ça a l'avantage d'être... déterministe.
    C'est bien pour cela que je parlais de variante

  12. #12
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Citation Envoyé par dalfab Voir le message
    On reprend :
    Un générateur ça s'initialise 1 fois avec 1 seed, pas à chaque appel.

    On ne peut pas faire std::default_random_engin endin{std::time(nullptr)}; pour définir un membre car un membre ne peut être préinitialisé que par une constante entière de compilation, et std::time(0) ne l'est certainement pas.
    On peut créer le générateur dans l'objet (en static) et faire le seed une unique fois. Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class X {
       static std::default_random_engin endin;
    public:
       static void preInit() { endin.seed( std::time(nullptr) ); }
    };
    int main() {
       X::preInit(); // init une fois pour toute
    }
    Bonjour, je suis rentré de vacances et j'ai tester ce code et il ne fonctionne malheureusement pas j'ai juste l'erreur undefined reference to `Spell::engin'| :/

  13. #13
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 580
    Points : 7 712
    Points
    7 712
    Par défaut
    Il y a une fôte de frappe (il manque un 'e') et il manque en effet des lignes (des include et les static doivent être définis en plus d'être déclarés)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <random>                   // pour acceder a default_random_engine
    #include <time.h>                     // pour acceder a time()
    class X {                           // dans un fichier H
       static std::default_random_engine endin;
    public:
       static void preInit() { endin.seed( std::time(nullptr) ); }
    };
     
    std::default_random_engine X::endin; // dans un fichier cpp
     
    int main() {
       X::preInit(); // init une fois pour toute
    }

  14. #14
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Il y a une fôte de frappe (il manque un 'e') et il manque en effet des lignes (des include et les static doivent être définis en plus d'être déclarés)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <random>                   // pour acceder a default_random_engine
    #include <time.h>                     // pour acceder a time()
    class X {                           // dans un fichier H
       static std::default_random_engine endin;
    public:
       static void preInit() { endin.seed( std::time(nullptr) ); }
    };
     
    std::default_random_engine X::endin; // dans un fichier cpp
     
    int main() {
       X::preInit(); // init une fois pour toute
    }

    J'avais bien vue les fautes et les include manquante mais même en corrigeant ça ne fonctionne pas :/, j'ai ce code :
    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
     
    #ifndef Spell_included
    #define Spell_included
     
    #include <vector>
    #include <random>
    #include <ctime>
     
    enum DmgType{ Undefined, Basic, Heal, Neutral, Shadow, Light, Wind, Dirt, Water, Fire };
     
    struct DmgRoll
    {
        DmgRoll( short const &dmgMin, short const &dmgMax, DmgType const &type ) : dmg_min{dmgMin}, dmg_max{dmgMax}, dmg_type{type}{}
        short const dmg_min;
        short const dmg_max;
        DmgType const dmg_type;
    };
     
    class Spell
    {
    public:
     
        Spell( std::string const &name, std::vector<DmgRoll> const &dmg, std::vector<DmgRoll> const &dmgCrit ) : spell_name{name}, spell_dmg{dmg}, spell_dmg_crit{dmgCrit}{}
        static void preInit() { engin.seed( std::time(nullptr) ); }
     
    private:
     
        static std::default_random_engine engin;
        std::string const spell_name;
        std::vector<DmgRoll> const spell_dmg;
        std::vector<DmgRoll> const spell_dmg_crit;
     
    };
     
    #endif // Spell_included
    Par contre je vien de lire ceci : "std::default_random_engine X::endin; // dans un fichier cpp" du coup cela fonctionne

    Je te et je vous remercie à tous pour votre aide

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

Discussions similaires

  1. Influencer un nombre aléatoire (le retour)
    Par memento80 dans le forum Langage
    Réponses: 10
    Dernier message: 26/12/2011, 19h49
  2. Retour Hibernate aléatoire
    Par _Babar_ dans le forum Hibernate
    Réponses: 22
    Dernier message: 16/08/2010, 17h26
  3. Retour à la ligne avec fichier à accès aléatoire
    Par mehdiyou dans le forum VB.NET
    Réponses: 11
    Dernier message: 29/04/2008, 14h57
  4. Retour aléatoire sur la page d'accueil
    Par ThunderBolt_ dans le forum Langage
    Réponses: 2
    Dernier message: 09/01/2007, 10h00

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