Partage
  • Partager sur Facebook
  • Partager sur Twitter

Affichage position Joueur console POO

Sujet résolu
    11 mai 2022 à 16:22:35

    Salut à tous et à toutes :),

    Je suis en train de m'exercer à la POO en C++. 
    J'ai réussi à afficher une sorte de carte mais je me demande comment je peux lier ma classe Joueur avec la carte :euh:.

    Je vous mets mon code :

    Joueur.h

    #ifndef JOUEUR_H_INCLUDED
    #define JOUEUR_H_INCLUDED
    
    #include <iostream>
    #include <string>
    #include "carte.h"
    
    
    
    class Joueur
    {
    public:
        Joueur(); // constructeur
    
        void identiteJoueur();
        void interfaceJoueur () const;
        void positionJoueur();
    
    
    
    protected:
        std::string m_identite; //choix du nom de la faction du joueur
    
    };
    


    Joueur.cpp

    #include <iostream>
    #include <string>
    #include "joueur.h"
    
    
    Joueur::Joueur():m_niveauJoueur(0), m_QGduJoueur(1000)
    {
    
    }
    
    
    void Joueur::identiteJoueur() //permet au joueur de rentrer sa faction de combat
    {
    
        std::cout<<"Tout d abord, comment s'appelle ta faction ?"<<std::endl;
        std::cin>>m_identite;
    
    }
    
    
    
    
    void Joueur::interfaceJoueur() const
    {
        std::cout<<"Etat QG : "<< m_QGduJoueur <<std::endl;
    
    }
    
    void Joueur::positionJoueur()
    {
        //BLOCAGE
    }
    

    Carte.h

    #ifndef CARTE_H_INCLUDED
    #define CARTE_H_INCLUDED
    
    #include <iostream>
    #include <string>
    
    class Carte
    {
    public:
        Carte(); //constructeur
        void dessineCarte();
    
    
    protected:
    
        int i; //utilisation pour le tableau
        int j; // utilisation pour le tableau
        int m_okCarte;
        int m_longueur; //longueur du tableau
        int m_largeur; //largeur du tableau
        int m_pointX; //coordonnées X
        int m_pointY; //coordonées Y
        char m_grille[0][0];// grille de la carte
        int m_localisation; //grille de localisation
    
    
    
    };
    

    Carte.cpp

    #include <iostream>
    #include <string>
    #include "carte.h"
    
    Carte::Carte()//constructeur
    {
    
    }
    
    
    void Carte::dessineCarte()
    {
        do
        {
    
        m_okCarte=0;
        std::cout<<"Choisissez une taille de carte pour le combat entre 1 et 10 km"<<std::endl;
        std::cout<<"Taille : "<<std::endl;
        std::cin >>m_longueur;
        m_largeur=m_longueur;
    
        if (m_longueur<=10&&m_longueur>=0)
        {
    
            m_okCarte=1;
            std::cout<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl;
            std::cout<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl;
            std::cout<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl;
            std::cout<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl<<std::endl;
    
    
            for (i=0;i<m_longueur;i++)
            {
                for (j=0;j<m_largeur;j++)
                {
                    m_grille[i][j]='-';
                    std::cout<<"         ";
                    std::cout<<m_grille[i][j];
                }
                std::cout<<std::endl<<std::endl;
            }
        }
        else
    
        {
            std::cout<<"ERREUR DANS LA TAILLE DE LA CARTE"<<std::endl;
            std::cout<<"ENTRER UNE VALEUR ENTRE 1 ET 10"<<std::endl;
        }
        }while(m_okCarte!=1);
    }




    main.cpp

    #include <iostream>
    #include "joueur.h"
    #include "carte.h"
    
    int main()
    {
        std::cout << "-------------------------------------------------------------------------" << std::endl;
        std::cout << "-----------------------------| LE STRATEGE |-----------------------------" << std::endl;
        std::cout << "-------------------------------------------------------------------------" << std::endl<<std::endl<<std::endl;
        Joueur joueur1; //création de l'objet joueur 
        joueur1.identiteJoueur(); // obtention de l'identite du joueur
        std::cout << "Votre objectif est de detruire l'autre faction Commandant!"<<std::endl;
        joueur1.interfaceJoueur();
        std::cout << "L'etat de votre QG est ici a 100 %. S'il atteint 0, votre faction est detruite."<<std::endl;
        Carte cartedujeu;
        cartedujeu.dessineCarte();
    
        return 0;
    }
    



    En vous remerciant de votre aide qui me permettra de progresser :).



    • Partager sur Facebook
    • Partager sur Twitter
      11 mai 2022 à 17:54:25

      Salut,

      Vu tom implementation je sais pas trop. Mais tu peux considerer ta carte comme un ensemble de Points(Point etant une classe) et rajouter aussi une propriete Position a un joueur(private/public: Point m_position;) 

      • Partager sur Facebook
      • Partager sur Twitter
        11 mai 2022 à 18:02:45

        Je suis toujours étonné par les débutants qui arrivent à faire des trucs sans avoir à se poser des questions au préalable et rester coincer par ces mêmes questions, mais qu'ils se posent plus tard (trop tard).

        Si je comprends tes choix, c'est à "cartedujeu" de s'afficher ET d'afficher les joueurs ?

        Bin, le plus simple, c'est que la carte contienne la liste des joueurs, dans un champ 'm_joueurs' par exemple, et que sa fonction 'dessineCarte' dessine la carte et les joueurs en même temps.

        Pour que "cartedujeu" ait les informations nécessaires, vous pouvez les fournir dans les paramètres du constructeur, ou en implémentant une fonction membre 'addPlayer' à la classe "Carte".

        Pour afficher les joueurs en même temp que la carte, lors de la boucle, avant la ligne 36, on vérifie qu'il n'y  pas un joueur à cette place et on n'affiche autre chose que le "-".

        (mais bon, quitte à avoir une grille pleine dans la carte, pourquoi elle n'est pas automatiquement à jour ?)

        Moi, pour gérer correctement les "layers" d'affichage et faire du "SOLID", j'aurais un objet Renderer qui demanderait à "cartedujeu" de "se rendre/s'afficher" sur une surface, puis l'objet Renderer demanderait aux players de "se rendre/s'afficher" sur la même surface.

        RemarqueS :

        les membres i et j de la classe Carte, c'est une blague ?

        Ne fourrez pas ce genre de variable de boucle/locale dans les champs du classe, SVP.

        le membre 'm_okCarte', idem, un flag qui ne s'utilise/n'a de sens que dans une fonction, c'est une variable locale à la fonction, pas un champ.

        (Et vous prenez la tête pour rien, m_okCarte ne sert à rien si vous refléchissez un peu plus.)

        La fonction 'dessineCarte' ne devrait que dessiner la carte (et s'appeler 'dessine', parce qu'on sait que c'est une carte qui se dessine).

        Votre 'm_grille' est bien trop petite (et un tableau à la C, non "mais allo quoi"!) => plantage erratique.

        Elle devrait avoir la bonne taille dès la sortie du constructeur (donc dégager les modifications des champs de la taille de la grille dans 'dessineCarte', cf. "dessineCarte ne devrait que dessiner la carte").

        La taille de la grille devrait être connue avant l'instanciation de 'cartedujeu" et donc être un paramètre du constructeur de la classe "Carte".

        etc...

        (Dans les faits, votre "Carte" fait bien trop de choses => consulter les règles SOLID)

        • Partager sur Facebook
        • Partager sur Twitter
        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
          11 mai 2022 à 18:31:24

          bacelar a écrit:

          et un tableau à la C, non "mais allo quoi"!


          Il vaut mieux vomir un `std::array<std::array<char, 10>, 10> m_grille;` ??
          • Partager sur Facebook
          • Partager sur Twitter
            11 mai 2022 à 18:47:57

            Non, la taille de la grille n'est pas connue à la compilation, c'est donc un "m_grille = std::vector<char>(taille_grille * taille_grille,'-')", et pour le même prix, t'as la valeur par défaut et une linéarisation.

            Quand tu tires des boulets, essayes de viser "assez" juste @JadeSalina, STP.

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              11 mai 2022 à 19:00:48

              bacelar a écrit:

              Non, la taille de la grille n'est pas connue à la compilation, c'est donc un "m_grille = std::vector<char>(taille_grille * taille_grille,'-')", et pour le même prix, t'as la valeur par défaut et une linéarisation.

              Quand tu tires des boulets, essayes de viser "assez" juste @JadeSalina, STP.


              Ah oui j'avais pas vu que l'auteur faisait des choses bizarres, je croyais que c'était juste une faute de frappe d'avoir mis 0. Par contre si on voulait vraiment un tableau 2D avec une taille connue à la compilation il fallait quand même ne pas utiliser `char m_grille[10][10]` ?
              • Partager sur Facebook
              • Partager sur Twitter
                11 mai 2022 à 19:23:49

                Je ne comprends pas trop cette volonté de prendre les gens de haut alors que c'est tout l'intérêt du forum d'aider les personnes et de partager dans le respect 🤷‍♂️🤷‍♂️
                Je ne suis pas du tout un pro de la programmation j'essaie comme je peux d'apprendre en autodidacte 🤷‍♂️🤷‍♂️ J'ai bien conscience qu'il y a des erreurs mais de là à déverser des propos comme ça bohhh bravo la pédagogie quoi 🤷‍♂️🤷‍♂️
                Bref pour avoir des retours comme ça je me débrouillerai autrement parce qu'il n y a rien de bien constructif.
                • Partager sur Facebook
                • Partager sur Twitter
                  11 mai 2022 à 19:48:13

                  Mais non ne partez pas !! On va vous aider ! Certains disent les choses d'une manière assez "cash" mais il faut pas le prendre personnellement.

                  Par rapport aux variables, on aime bien 2 choses : qu'elles aient un nom explicite et clair (pas "a" ou "b") et qu'elles soient déclarées au plus proche de là où elles sont utilisées, parce que plus la variable est déclarée "tôt", plus il y a des chances de faire n'importe quoi avec, par exemple :

                  // Pas bien
                  void ma_fonction() {
                    int i = 0;
                  
                    // ... Plein de code ...
                  
                    for (i = 0; i < 10; i++) {
                    
                    }
                  
                    // ici la variable i existe toujours alors qu'on en
                    // avait besoin que pour la boucle
                  }
                  
                  
                  // Bien
                  void ma_fonction() {
                    // ... Plein de code (qui ne risque pas d'utiliser i par erreur)...
                  
                    for (int i = 0; i < 10; i++) {
                    
                    }
                  
                    // la variable i n'existe plus ici
                  }

                  Du coup ce serait bien de les déclarer directement dans la boucle. 

                  En C++ on ne peut pas déclarer des tableaux comme ça avec une taille de 0, ces tableaux là il faut obligatoirement leur donner une taille positive non nulle et qui doit être connue lors de la compilation. Donc là apparemment vous demandez à l'utilisateur la taille, c'est donc que vous ne la connaissez pas à la compilation. Ou alors vous connaissez une taille "maximale" et vous pouvez allouer un tableau de cette taille, mais ça utiliserait potentiellement trop de mémoire si l'utilisateur demande une petite grille et que vous aviez prévu beaucoup plus gros.

                  Dans la fonction dessineCarte, vous affichez la carte mais vous mettez aussi la case [i][j] à '-' ? Il faudrait plutôt initialiser la grille avec des '-' et quand vous voulez l'afficher, vous ne faites que l'afficher, sinon là vous écrasez à chaque fois les cases en mettant '-' dedans.

                  Pour "lier" la carte et le joueur, je ne peux pas vous aider, si c'était moi j'aurai commencé par faire ce que j'ai à faire juste en codant instruction par instrution, et ensuite en déduire que je vais avoir une classe "Joueur", une classe "Carte", et je saurai directement qui fait quoi puisque j'aurai déjà la solution sous les yeux. Donc la question "comment je lie les deux" ne se poserait pas, si il fallait les séparer puis les relier d'une manière ou d'une autre je verrai directement où et comment (directement en lisant le code!), et si au contraire il valait mieux qu'ils ne soient pas séparés en premier lieu (bah oui on y a pas pensé à celle là :)), eh bien dans ce cas je le verrai aussi



                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 mai 2022 à 20:34:07

                    Sergentdeveloppeur a écrit:

                    Je ne comprends pas trop cette volonté de prendre les gens de haut alors que c'est tout l'intérêt du forum d'aider les personnes et de partager dans le respect

                    M bacelar est comme cela. Le mieux c'est d'ignorer ses posts. Mais rassurez-vous toutes les personnes qui essais d'aider ne sont pas comme lui.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 mai 2022 à 20:35:01

                      Sergentdeveloppeur a écrit:

                      Je ne comprends pas trop cette volonté de prendre les gens de haut alors que c'est tout l'intérêt du forum d'aider les personnes et de partager dans le respect 🤷‍♂️🤷‍♂️

                      Je ne suis pas du tout un pro de la programmation j'essaie comme je peux d'apprendre en autodidacte 🤷‍♂️🤷‍♂️ J'ai bien conscience qu'il y a des erreurs mais de là à déverser des propos comme ça bohhh bravo la pédagogie quoi 🤷‍♂️🤷‍♂️
                      Bref pour avoir des retours comme ça je me débrouillerai autrement parce qu'il n y a rien de bien constructif.


                      Quand on veut apprendre on se rabaisse aussi.

                      Le fait qu'il te corrige et te traite de debutant ne devrais pas te deranger je pense, meme si y'a des passages "moqueur" tout cela c'est pour un but pedagogique, tire juste l'information qu'il veut te faire parvenir.

                      Pourquoi s'emballer ?

                      • Partager sur Facebook
                      • Partager sur Twitter
                        11 mai 2022 à 20:37:04

                        Asmitta a écrit:

                        Quand on veut apprendre on se rabaisse aussi.

                        Le fait qu'il te corrige et te traite de debutant ne devrais pas te deranger je pense, meme si y'a des passages "moqueur" tout cela c'est pour un but pedagogique, tire juste l'information qu'il veut te faire parvenir.

                        Pourquoi s'emballer ?

                        Et, il y a quand même des façon de le dire.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          11 mai 2022 à 21:56:12

                          Outre la forme, qu'est-ce que tu ne comprends pas dans mes remarques, STP ?

                          Désolé pour le "bruit" avec @JadeSalina, mais on dialogue entre intervenants, c'est aussi un avantage des forum.

                          Donc, si on reprend.

                          - Virez les membres "i", "j" et "m_okCarte" et utilise des variables locales à la place.

                          - Renommez la fonction "dessineCarte" en "dessine"

                          - Enlever de la fonction "dessine" tout ce qui n'a rien à voir avec l'action de "Dessiner" la carte.

                          - faire de "m_grille" un std::vector<char> et pas un tableau à la C.

                          - Initialiser le champ "m_grille" dans la liste d'initialisation du constructeur de la carte.

                          Donc, en gros:

                          Joueur.h :

                          #pragma once // l'include-guard est foireux, je me prend pas la tête
                          
                          #include <string>
                           
                          class Joueur
                          {
                          public:
                              Joueur(std::string id); // constructeur
                           
                          protected:
                              std::string m_identite; //choix du nom de la faction du joueur
                           
                          };


                          Joueur.cpp :

                          #include <iostream>
                          #include <string>
                          #include "joueur.h"
                           
                           
                          Joueur::Joueur(std::string id):m_identite{id},m_niveauJoueur{0}, m_QGduJoueur{1000}
                          {
                           
                          }
                           
                          void Joueur::dessine(std::ostream& output) const
                          {
                              output<<"Etat QG : "<< m_QGduJoueur <<std::endl;
                          }


                          Carte.h :

                          #pragma once // l'include-guard est foireux, je me prend pas la tête
                           
                          #include <iostream>
                          #include <vector>
                          #include <tuple>
                          
                          #include "Joueur.h"
                           
                          class Carte
                          {
                          public:
                              Carte(std::vector<std::<tuple<int,int,Joueur> > joueurs, size_t taille_grille_carree); //constructeur
                              Carte(std::vector<std::<tuple<int,int,Joueur> > joueurs, size_t longueur, size_t largeur); //constructeur
                              void dessine(std::ostream output);
                           
                           
                          protected:
                              size_t m_longueur; //longueur du tableau
                              size_t m_largeur; //largeur du tableau
                              std::vector<char> m_grille; // grille de la carte
                              std::vector<std::<tuple<int,int,Joueur> > m_joueurs; // liste des joueurs avec leur position x,y
                          };


                          Carte.cpp :

                          #include <iostream>
                          #include <string>
                          #include <vector>
                          #include <tuple>
                          #include <algorithm>
                          
                          #include "carte.h"
                           
                          Carte::Carte(std::vector<std::<tuple<int,int,Joueur> > joueurs, size_t taille_grille_carree):m_longueur{taille_grille_carree},m_largeur{taille_grille_carree},m_grille{taille_grille_carree*taille_grille_carree,'-'},m_joueurs{joueurs}//constructeur
                          {
                           
                          }
                          
                          Carte::Carte(std::vector<std::<tuple<int,int,Joueur> > joueurs, size_t longueur, size_t largeur):m_longueur{longueur},m_largeur{largeur},m_grille{longueur*largeur,'-'},m_joueurs{joueurs}//constructeur
                          {
                           
                          }
                          
                          Carte::Carte()://constructeur
                          {
                           
                          }
                           
                          void Carte::dessine(std::ostream& output)
                          { 
                              for (i=0;i<m_longueur;i++)
                              {
                                  for (j=0;j<m_largeur;j++)
                                  {
                                      auto found = find_if(begin(m_joueurs), end(m_joueurs), [ = ](auto&& e) { return get(e) == j && ; get(e) == i});
                                      
                                      if(found == end(m_joueurs))
                                      {
                                          m_grille[i*m_largeur+j] = '-'
                                      }
                                      else
                                      {
                                          m_grille[i*m_largeur+j] = '*'
                                      }
                          
                                      output<<"         ";
                                      output<<m_grille[i*m_largeur+j];
                                  }
                                  output<<std::endl<<std::endl;
                              }
                          }


                          main.cpp :

                          #include <iostream>
                          #include "joueur.h"
                          #include "carte.h"
                          
                          std::string getStringFromConsole(std::string& const prompt, std::istring& input,std::istring& output)
                          {
                              std::string ret{};
                              output << prompt <<std::endl;
                              input >> ret;
                          
                              return ret;
                          }
                          
                          size_t getNumFromConsole(std::vector<std::string>& const prompt_list, size_t min, size_t max, std::vector<std::string>& const prompt_error_list,std::istream& input,std::ostream& output)
                          {
                              size_t ret{};
                              bool value_ok = false;
                          
                              do
                              {
                                  for (auto const& e : std::as_const(prompt_list))
                                  {
                                      output << e << std::endl;
                                  }  
                                  input >> ret;
                                  if(ret>= min && ret<=max)
                                  {
                                      value_ok = true;
                                  }
                                  else
                                  {
                                      for (auto const& e : std::as_const(prompt_error_list))
                                      {
                                          output << e << std::endl;
                                      }
                                  }
                              }while(!value_ok)
                          
                              return ret;
                          }
                          
                          
                          int main()
                          {
                              std::cout << "-------------------------------------------------------------------------" << std::endl;
                              std::cout << "-----------------------------| LE STRATEGE |-----------------------------" << std::endl;
                              std::cout << "-------------------------------------------------------------------------" << std::endl<<std::endl<<std::endl;
                              std::string id_joueur = getStringFromConsole("Tout d abord, comment s'appelle ta faction ?",std::in,std::cout);
                          
                              Joueur joueur1{id_joueur}; //création de l'objet joueur
                              std::cout << "Votre objectif est de detruire l'autre faction Commandant!"<<std::endl;
                              joueur1.dessine(std::cout);
                              std::cout << "L'etat de votre QG est ici a 100 %. S'il atteint 0, votre faction est detruite."<<std::endl;
                              size_t taille_grille = getNumFromConsole({"Choisissez une taille de carte pour le combat entre 1 et 10 km","Taille : "},1,10,{"ERREUR DANS LA TAILLE DE LA CARTE","ENTRER UNE VALEUR ENTRE 1 ET 10"},std::in,std::cout);
                              Carte cartedujeu{{{0,0,joueur1}},taille_grille};
                              cartedujeu.dessine(std::cout);
                           
                              return 0;
                          }


                          EDIT :

                          Clairement, la très grande majorité des grosses boulettes de votre code initiale sont du à la qualité dû ou des cours que vous avez "subis".

                          Pourquoi diable utiliser un tableau C en C++ ?

                          Pourquoi mettre des variables qui devraient être locales comme des champs d'une classe ?

                          Le plus probable, c'est que vous avez lu un (très) mauvais cours de C/C++ (et pas de C++) qui était "à jour" il y a plus de 25 ans, comme cette calamité de cours C++ d'Openclassroom.

                          P.S.: le code que j'ai posté fait pas mal de changement pour vous montrer comment rendre votre code plus souple et modulaire. L'architecture n'est pas top car elle reste proche de la votre. Donc, ce n'est qu'une étape (code fait à l'arrache donc erreur de compilation dans tout les sens)

                          Courage

                          -
                          Edité par bacelar 11 mai 2022 à 22:14:47

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                          Affichage position Joueur console POO

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          • Editeur
                          • Markdown