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 :

accesseurs retournant des valeurs aberrantes


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut accesseurs retournant des valeurs aberrantes
    Bonjour a tous,

    J'ai un souci de code où un accesseur retourne des valeurs ne correspondant pas à ce que j'ai écrit. J'écris ce programme dans la continuation du projet RPG d'un tutoriel. Voila l'histoire :

    Mon code comprend une classe Joueur qui possède un tableau de personnage en argument. J'y créé un certain nombre d'objet instances de la classe Personnage, que j'appelle dans le main dans un tableau de pointeurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        for (int i=0;i<joueurs.size();i++)
        {
            for (int j=0;j<joueurs[i].nbpersos();j++)
            {
                persos.push_back(joueurs[i].getpointeur(j));
            }
        }
    Jusque-là pas de souci. Ensuite je créé une boucle afin que les personnage jouent selon leur ordre d'initiative.

    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
    while (VerifVivant(persos))         //si au moins un perso est vivant
        {
            while (VerifActif(persos))      //si au moins un perso est actif
            {
                temps.compteurIncrem();     //incrémentation du compteur temps
                //printf("%i", temps.getCompteur());
     
                for ( int i=0 ; i<persos.size() ; i++)
                {
    printf("%i", persos[i]->getIni());
                    if (temps.getCompteur()==persos[i]->getIni())       //si l'initiative d'un perso vaut le compteur
                    {
                        do                       //alors le perso joue
                        {
                cout << "Tour de " << persos[i]->getName() << endl;
                action=choix(persos[i]->gettour());
     
                        if (action==1)              {persos[i]->attaquer();}
                        else if (action==2)         {persos[i]->deplacer();}
     
                        else if (action==3)         {persos[i]->changerArme();}
                        else if (action==4)         {persos[i]->utiliserConsommable();}
                        else if (action==5)         {persos[i]->recevoirDegats(1000);persos[i]->devientInactif();}
                        else if (action==6)         {persos[i]->nefaisrien();}
     
                        }while (persos[i]->estActif()==1);
                    }
                }
            }
     
            temps.compteurReinit();                                             //lorsque tous les persos ont joué, le compteur est remis à zéro
            for (int i=0;i<persos.size();i++)
            {
                persos[i]->devientActif();                                   //tous les persos sont réactivés
            }
        }
    Tous ça était correct jusqu'a il y a peu, mais lorsque je compile, je tombe sur une boucle infinie. Et lorsque le code arrive à la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%i", persos[i]->getIni());
    La console se remplit à l'infini de : 40268602. Alors que j'ai initialisé m_ini de chaque personnage à 20. Voici la fonction getIni:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //dans le .h
    int getIni() const;
     
    //dans le .ccp
    int Personnage::getIni() const {return m_iniB;}
    Et après quelques tests je me suis aperçu que ca me refaisait le coup avec d'autres accesseurs tels que la vie.

    Ca me paraît évident que la fonction getIni() renvoi l'adresse d'un pointeur mais je ne comprends pas pourquoi...Ai-je fait une erreur d'appel de fonction ou d'adressage?

    Merci d'avance de vos réponses.

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    J'ai plusieurs petites questions à te poser, concernant la partie du 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
    do{
        if (action==1){
            persos[i]->attaquer();
        }else if (action==2){
            persos[i]->deplacer();
        }else if (action==3){
            persos[i]->changerArme();
        }else if (action==4){
            persos[i]->utiliserConsommable();
        }else if (action==5){
            persos[i]->recevoirDegats(1000);
            persos[i]->devientInactif();
        }else if (action==6){
            persos[i]->nefaisrien();
        }
    }while (persos[i]->estActif()==1);
    • A ton avis, que fait ce code
    • Heu... dois-je comprendre que tu permet propose au joueur de demander à son personnage de s'auto-mutiler avec le choix 5

    Si tu trouves les bonne réponses, tu trouveras la solution à ton problème
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Merci pour cette réponse très rapide.

    Eh bien le but de ce code est de permettre au joueur de saisir l'action que va effectuer son personnage. Chaque action (numérotée) appelle une fonction idoine dans le code du personnage. Le personnage qui effectue l'action est désignée par persos[i], qui est un pointeur, d'ou le fait que j'utilise des fleches et par des points.

    Et il s'agit grosso modo d'un switch case mais avec des if, avec des comparaisons sur un entier. Et le personnage joue jusqu'a ce qu'un signal (quand estActif renvoi false) apparaisse, ici lorsque le joueur utilise l'action 7, "ne fais rien". J'ai bon?

    Et oui le choix 5 a été fait pour tester la condition de fin de combat, c'est à dire lorsqu'un personnage est mort. Et quel meilleur moyen que de louper son sort pour partir en fumée?

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par bl4cksky Voir le message
    Merci pour cette réponse très rapide.

    Eh bien le but de ce code est de permettre au joueur de saisir l'action que va effectuer son personnage. Chaque action (numérotée) appelle une fonction idoine dans le code du personnage. Le personnage qui effectue l'action est désignée par persos[i], qui est un pointeur, d'ou le fait que j'utilise des fleches et par des points.

    Et il s'agit grosso modo d'un switch case mais avec des if, avec des comparaisons sur un entier. Et le personnage joue jusqu'a ce qu'un signal (quand estActif renvoi false) apparaisse, ici lorsque le joueur utilise l'action 7, "ne fais rien". J'ai bon?
    Très bien, là, tu nous as joliment expliqué ce que tu voudrais que ton code fasse.

    (note au passage qu'avec de noms comme getpointeur, je m'étais en effet un tout petit peu douté que tu travaillais avec des pointeurs )
    Mais moi, je t'ai demandé "A ton avis, que fait ce code?".

    Pour ton malheur, ce que fait ton code ne correspond pas à ce que tu voudrais qu'il fasse, et tu n'as donc pas répondu à ma question

    Je vais donc te proposer un petit jeu: il s'appelle "joue à être aussi bête qu'un processeur".

    Le principe de ce jeu est très simple, tu verras:

    Tu prend une feuille de papier et tu indiques dessus les valeurs, par exemple du premier personnage (tu verras, un seul suffira ).
    Puis, tu joue le doule role du joueur (qui introduit des valeurs comprises entre 1 et 7, à l'exception de 5 et de 7) et tu suis toutes les étapes que tu as programmées.

    Si, à un moment, tu arrives à sortir de la boucle, tu as gagné.

    Sinon, tu finira surement par trouver l'origine de ton problème
    [EDIT]N'oublie pas de rentrer dans les fonctions de perso que tu appelles, histoire de voir ce qu'il devient

    Note que, dans le cas présent, une énumération et un switch case semblent particulièrement adaptés
    Et oui le choix 5 a été fait pour tester la condition de fin de combat, c'est à dire lorsqu'un personnage est mort. Et quel meilleur moyen que de louper son sort pour partir en fumée?
    C'est une idée comme une autre, après tout
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Ben j'ai pas mal essayé d'y repenser et je ne vois vraiment pas ou tu veux en venir...

    Le joueur définit une action par un entier et ensuite la boucle vérifie, si cet entier vaut 1 on appelle la fonction déplacer du personnage qui est en train de jouer. Ensuite on vérifie si l'entier vaut 2, on appelle la fonction attaquer du personnage, etc. Et si l'entier vaut 7, alors le personnage devient inactif et la boucle se termine.

    Je ne vois pas trop ce qui est conflictuel ici. Mais peut-être que je ne peux pas me rabaisser au niveau intellectuel d'un processeur (le pauvre, je suis sur qu'il écoute de la dubstep)...

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Bon, allez, je vais le faire pour toi...

    Comme je ne connais absolument pas le contenu de tes fonctions mais que j'ai repéré l'appel à devientInactif(), je vais partir du principe qu'aucune des fonctions appelée ne va modifier le statut d'activité des personnages

    Nous avons donc un personnage qui est actif au départ, si on est entré dans la boucle
    on peut donc dire que perso->estActif() renvoie 1

    tu introduis "1" lorsqu'on te le demande

    Le personnage se attaque... tout ce qu'il y a de plus naturel

    A ce moment là perso->estActif() renvoie... toujours 1, on rentre dans la boucle

    tu introduis cette fois "2", et le personnage se déplace, pas de problème

    Mais perso->estActif() renvoie combien Bah, 1, pourquoi est ce que cela aurait changé , on entre donc de nouveau dans la boucle

    Tu introduis pour changer "3" et le perso change d'arme, mais il est toujours actif, et... on retourne de nouveau dans la boucle

    Bon, soit, on introduit alors "4", et le perso et le perso boit une potion, mais... il est toujours actif et on retourne donc dans la boucle.

    Puis tu introduit 6 et le perso ne fait rien mais ... reste actif.

    Oui, mais, oh!!! A part s'il loupe son sort (le 5, si j'ai bien compris ) cela signifie que le personnage ne deviendra jamais inactif !!!

    Et pendant tout ce temps, les autres perso, bah, ils se tournent les pouces!

    Dés lors, la question se pose : pourquoi avoir plusieurs personnages et plusieurs joueur si, au final, il n'y en aura jamais qu'un qui pourra jouer, à moins de louper son sort

    En plus, pendant tout ce temps, les personnages attaqués vont en prendre "plein la gu..le"!!! tu ne crois pas

    Cela ne résoudra sans doute pas ton problème d'origine (au sujet duquel je pencherais vers un problème de buffer clavier non purgé), mais si tu résous ce problème, tu auras déjà fait un sérieux pas en avant
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Ah oui mais non je me suis mal exprimé. En fait la fonction nefaisrien() change l'attribut estActif du personnage. Cela dit c'est en regardant mon code suivant tes conseil que j'ai repéré qu'en fait j'ai simplement inversé deux variables en écrivant

    au lieu du contraire. Suis-je bête...Je suis vraiment con parfois. J'avais oublié que l'opérateur d'association = allait de gauche à droite.

    Merci d'avoir pris du temps pour me répondre

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

Discussions similaires

  1. [uib] asDLL retourne des valeurs étranges
    Par qi130 dans le forum Connexion aux bases de données
    Réponses: 8
    Dernier message: 12/10/2010, 19h00
  2. Détection des valeurs aberrantes
    Par Boolbola dans le forum R
    Réponses: 3
    Dernier message: 15/01/2009, 09h36
  3. Réponses: 4
    Dernier message: 24/11/2008, 20h47
  4. Connexion MySQL retourne des valeurs UNDEFINED !
    Par paricilas dans le forum Flash
    Réponses: 14
    Dernier message: 05/03/2007, 11h04
  5. Requête retournant des valeurs constantes prédéfinies
    Par hackrobat dans le forum Requêtes
    Réponses: 4
    Dernier message: 28/06/2006, 18h01

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