Partage
  • Partager sur Facebook
  • Partager sur Twitter

Probleme creation rectangle en assci

Sujet résolu
    10 juillet 2014 à 13:51:41

    Bonjour,

    je me suis lancé dans une IA de robots virtuels se déplaçant dans un rectangle, tout cela en console.

    J'ai commencé le programme mais je n'arrive pas a faire fonctionner 2 fonctions.

    La situation est la suivante, plus tard je voudrais pouvoir déplacer le robot dans ce carré en assci, vu que je suis sur console, pour pouvoir le déplacer dans le carré j'ai eu l'idée de créer une "map", cette map est contenue dans un vector(car je pense plus tard dans le programme donner la possibilité de modifier la taille du rectangle). Pour créer cette map j'utilise des boucles pour remplir la rangée du haut de "mur"(#), puis créer chaque rangée une par une avec un # et ensuite plein d'espace pour finir sur un #.

    Une fois le vector remplie, j'utilise une seconde fonction pour afficher ce vector.

    Il suffira ensuite pour bouger le robot de le bouger dans le vector par exemple:

    Le robot se situe à la case 50 = 'R', il va a droite on modifie la case 50 = ' ' et à la case 51 = 'R'.

    Le problème c'est qu'une fois que je lance le programme je n'ai pas d'erreur mais une seul ligne de # s'affiche après avoir relu mes boucles je me demande bien d'où vient le problème.

    Voici le code source:

    Du cpp:

    #include "Hud.h"
    
    using namespace std;
    
    Hud::Hud()
    {
    //besoin d'initialiser? comment initialiser un vector?
    }
    
    void Hud::creation()//on assigne a chaque case du vector un caractere
    {
        int i1=0,i2=0,i3=0;
    
        //creation d'un rectangle de 32*12
    
        while(i1<32)//on creer le mur du haut
        {
            m_map.push_back('#');
            i1++;
        }
        while(i2<10)//on creer tout l'interieur
        {
            m_map.push_back('#');//le mur gauche
            while(i3<30)
            {
                m_map.push_back(' ');//le vide
                i3++;
            }
            m_map.push_back('#');//le mur de droite
            i2++;
        }
        i1=0;
        while(i1<32)//on creer le mur du bas
        {
            m_map.push_back('#');
            i1++;
        }
    }
    
    void Hud::affichage() const//on affiche la map
    {
        int i=0,i2=0;
        while(i<12)//les 2 rangées
        {
            while(i2<32)//chaque ligne
            {
                cout<<m_map[i];
                i2++;
                i++;
            }
            cout<<endl;//passe une ligne pour la ligne suivante
            i2=0;
        }
    }
    

    Du h:

    #ifndef HUD_H_INCLUDED
    #define HUD_H_INCLUDED
    
    #include <iostream>
    #include <string>
    #include <vector>
    #include "Robots.h"
    
    class Hud
    {
        public:
        Hud();
        void creation();
        void affichage() const;
    
        private:
        std::vector<char> m_map;//map de 32*12
    
    };
    
    #endif // HUD_H_INCLUDED
    


    Voilà, je sais que c'est très brouillon si vous avez des idées pour rendre cela plus petit et plus pratique je suis preneur ^^.

    Merci d'avance pour vos réponses.

    • Partager sur Facebook
    • Partager sur Twitter
      10 juillet 2014 à 14:22:25

      Lu'!

      Tu pourrais créer une petite classe Matrix pour te simplifier la vie au niveau du rectangle. Quelques infos par là : Une classe Matrix.

      Avoir une telle structure, te simplifierai grandement la vie. La tu es obligé de faire des trucs tout tordu pour faire quelque chose simple comme remplir une map avec le vide et un contour fait avec des dièses.

      Il est également très curieux (et pas mal bancal) d'avoir une fonction "création" dans une classe (ou alors elle devrait être privée). C'est le rôle du constructeur de créer ;) .

      Autre chose : ne pré-déclare pas tes variables comme tu le fais. C'est toxique en C++, déclare la au moment précis où tu commences à en avoir besoin.

      L'idée serait d'avoir quelque chose comme ça (en imaginant que tu as déjà ta classe Matrix) :

      Hud(std::size_t w, std::size_t h) : m_map{ w, h, ' ' } {
        for(unsigned i{}; i < m_map.height(); ++i){
          for(unsigned j{}; j < m_map.width(); ++j)
            if(i == 0 || j == 0 || i == h-1 || j == w-1)
              m_map(i,j) = '#';
        }
      }

      L'idée pour créer le rectangle : si on est sur un bord, on doit mettre un # sinon, on doit laisser la valeur telle qu'elle.

      -
      Edité par Ksass`Peuk 10 juillet 2014 à 14:23:27

      • Partager sur Facebook
      • Partager sur Twitter

      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

        10 juillet 2014 à 14:28:20

        Merci pour ta réponse, donc en gros je dois créer la carte dans le constructeur, par contre je ne comprends pas ta classe matrix, je débute avec la poo, y a pas un moyen pour faire  moins compliqué?
        • Partager sur Facebook
        • Partager sur Twitter
          10 juillet 2014 à 15:06:47

          #include "Hud.h"
          
          using namespace std;
          
          Hud::Hud():m_map{384,' '}
          {
              int i=0,j=0,k=0;
              while(i<32)
              {
                  m_map[i]='#';
                  i++;
              }
          
              while(j<10)
              {
                  m_map[i]='#';
                  j++;
                  i+=31;
                  m_map[i]='#';
                  i++;
              }
          
              j=0;
              while(j<32)
              {
                  m_map[i]='#';
                  i++;
                  j++;
              }
          
          }
          
          void Hud::affichage() const//on affiche la map
          {
              int i=0,i2=0;
              while(i<384)//les 2 rangées
              {
                  while(i2<32)//chaque ligne
                  {
                      cout<<m_map[i];
                      i2++;
                      i++;
                  }
                  cout<<endl;//passe une ligne pour la ligne suivante
                  i2=0;
              }
          }

          Bon voilà, après pas mal s’essaie j'ai réussie, j'utilise finalement le même principe mais directement dans le constructeur.

          Merci pour ton aide ^^.

          • Partager sur Facebook
          • Partager sur Twitter
            10 juillet 2014 à 16:56:26

            @lex@ndre08 a écrit:

            Merci pour ta réponse, donc en gros je dois créer la carte dans le constructeur, par contre je ne comprends pas ta classe matrix, je débute avec la poo, y a pas un moyen pour faire  moins compliqué?

            Elle est très simple cette classe Matrix (il manque des choses, il faut juste les implémenter) :

            #ifndef _MATRIX
            #define _MATRIX
            
            #include <cassert>
            #include <ostream>
            #include <vector>
            
            //cette classe pourra contenir n'importe quel type
            //qu'on nommera "T" ici.
            template<class T>
            class Matrix{
            public:
              //on veut construire des matrices à partir de leur taille
              //w largeur, h hauteur
              //et d'un éventuel élément par défaut :
              Matrix(std::size_t w, std::size_t h, T const& t = T{}) :
                _w{ w }, _h{ h }, _data(_w*_h, t)
              {
            
              }
            
              //on veut pouvoir la copier
              Matrix(Matrix const& m) : _w{ m._w }, _h{ m._h }, _data(m._data){
            
              }
            
              //l'échanger avec une autre
              void swap(Matrix& m){
                std::swap(_w, m._w);
                std::swap(_h, m._h);
                std::swap(_data, m._data);
              }
            
              //l'affecter à une autre :
              Matrix& operator=(Matrix const& m){
                Matrix copy{ m };
                copy.swap(*this);
                return *this;
              }
            
              //accéder aux éléments en lecture :
              T const& operator()(unsigned x, unsigned y) const{
                //si c'est dans les bornes !
                assert(x < _w && y < _h && "Out of bound access !");
                return _data[y*_w + x];
              }
              
              //en écriture
              T& operator()(unsigned x, unsigned y){
                //si c'est dans les bornes !
                assert(x < _w && y < _h && "Out of bound access !");
                return _data[y*_w + x];
              }
              
              //on veut connaitre sa hauteur :
              std::size_t height() const{ return _h; }
            
              //on veut connaitre sa largeur :
              std::size_t width() const{ return _w; }
              
            private:
              std::size_t _w;
              std::size_t _h;
              std::vector<T> _data;
            };
            
            //et ajoutons un operateur pour afficher au passage :
            template<class T>
            std::ostream& operator<<(std::ostream& os, Matrix<T> const& m){
              for(unsigned i{}; i < m.height(); ++i){
                for(unsigned j{}; j < m.width(); ++j)
                  os << m(j,i) << ' ';
                os << std::endl;
              }
              return os;
            }
            
            #endif

            La seule chose, c'est qu'une classe template doit être intégralement présente dans son header. C'est tout.

            • Partager sur Facebook
            • Partager sur Twitter

            Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

              6 janvier 2015 à 13:19:00

              Tu n'as pas besoin d'écrire copie et affectation. Celles générées par défaut sont suffisantes (et conseillées) (et le préfixage par des tirets--bas n'est pas recommandé non plus)
              • Partager sur Facebook
              • Partager sur Twitter
              C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                6 janvier 2015 à 17:35:54

                Salut,

                lmghs a écrit:

                Tu n'as pas besoin d'écrire copie et affectation. Celles générées par défaut sont suffisantes (et conseillées) (et le préfixage par des tirets--bas n'est pas recommandé non plus)

                Pour être complet : la classe std::vector est suffisamment bien foutue pour être copiable et affectable lorsqu'elle contient des éléments qui ont sémantique de valeur (et qui peuvent donc être copiés et affectés).

                Du coup, le constructeur de copie et l'opérateur d'affectation implémenté par défaut par le compilateur agiront exactement de la manière dont on est en droit de s'y attendre.  Et, comme il serait dangereux de permettre la copie d'un tableau 2D dont les éléments n'auraient pas sémantique de valeur (et qui, par conséquent, ne pourraient -- par nature -- être ni copiés ni affectés), l'implémentation de l'ensemble de la forme canonique orthodoxe de Coplien que tu présente  s'avérerait carrément dangereuse avec de pointeurs sur un type de base, qu'il soient intelligent ou non ;) (note que, a priori, les pointeurs intelligents te permettraient de te rendre compte que tu ne peux pas utiliser l'implémentation que tu proposes pour la classe Matrix ;) )

                • Partager sur Facebook
                • Partager sur Twitter
                Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                  6 janvier 2015 à 23:53:18

                  lmghs a écrit:

                  Tu n'as pas besoin d'écrire copie et affectation. Celles générées par défaut sont suffisantes (et conseillées) (et le préfixage par des tirets--bas n'est pas recommandé non plus)

                  Ouiap. Pour le préfixage, je n'avais jamais vu ce point de la norme avant.

                  koala01 a écrit:

                  Et, comme il serait dangereux de permettre la copie d'un tableau 2D dont les éléments n'auraient pas sémantique de valeur (et qui, par conséquent, ne pourraient -- par nature -- être ni copiés ni affectés), l'implémentation de l'ensemble de la forme canonique orthodoxe de Coplien que tu présente  s'avérerait carrément dangereuse avec de pointeurs sur un type de base, qu'il soient intelligent ou non ;).

                  Ben ils auraient exactement la sémantique attendue pour la copie d'un conteneur de pointeurs si les pointeurs en questions sont nus (et pour unique, ils n'auraient pas de comportement du tout), c'est à dire un bon gros partage dégueux. Mais ça fait partie du fonctionnement d'approximativement tous les conteneurs. Donc je vois pas trop le problème que tu pointes.
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                  Probleme creation rectangle en assci

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown