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 :
ne fonctionne pas car indique une erreur de conversion
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()} }
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
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 #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.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 #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
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
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.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 #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
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.
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)); }
Je vous remercie de bien vouloir m'aider :/
Partager