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;
}
}
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) :
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é?
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.
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)
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 )
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
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.
× 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.
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C