Exercice C++

Résolu
Pseudo2206 -  
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,

Est-ce qu'il y a quelqu'un qui peut me dire quel est le problème dans mon code:

Instructions:
Le jeu est composé d'un damier de 8 lignes et de 12 colonnes. L'objectif est en se déplaçant sur le damier, de découvrir 15 cases où il y a des $$$$ cachés, et bien sûr de ramasser ces $$$$. Le jeu se termine lorsqu'on a cumulé 15 point (ou si on ferme la fenêtre de jeu). Tout déplacement illégal sera signalé par un beep (tentative de déplacement hors du jeu ou sur une case de type mur noir).
Chaque case du jeu est visible sous une des formes suivant:
-pierre blanche;
-pierre grise;
-mur noir;
-$$$$;
Au début toutes les case forment un mur noir ou sont composées de pierre blanche. Lorsque vous quitterez une case pierre blanche, celle-ci deviendra pierre grise ou bien $$$$.
Si on découvre une case $$$, retournez-y pour amasser votre fortune. En quittant la case $$$$, celle-ci devient pierre grise.
Lorsqu'on quitte une case pierre grise elle devient mur noir et on ne peut plus passer par là.
___________________________________________________________________________

Diagramme d'action (avant première ébauche):
Afficher le jeu
Tant que point < 15
Lire ToucheValide (une touche valide étant une touche de déplacement)
Valider le déplacement
Calculer le nouvelle position courante (si le déplacement est valide)
Modifier le code de la nouvelle case courante (si le déplacement est valide)
Afficher le jeu (Si nécessaire)
___________________________________________________________________________

Jeu.cpp
#include <iostream>
#include <conio.h>
#include <iomanip>
#include "E://cvm.h"
using namespace std;

void main(void)
{
	const int BAS=80, HAUT=72, DROITE=77, GAUCHE=75, HD=73, HG=71, BG=79, BD=81; 
	const int NB_LIG=8, NB_COL=12; 
	int i=0, j=0, Lig=0, Col=0, Points=0; 

	// Matrice composant le damier du jeu : 
	// 0==Normal(Pierre blanche), 1==$$$$ caché, 2==$$$$ visible, 3==Pierre grise, 4==Mur Noir 
	int Mat[NB_LIG][NB_COL]={	{ 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 1}, 
								{ 0, 0, 4, 4, 0, 0, 0, 0, 0, 4, 0, 4}, 
								{ 0, 0, 4, 1, 4, 0, 0, 0, 0, 0, 4, 1}, 
								{ 0, 0, 4, 1, 4, 0, 0, 4, 4, 0, 4, 1}, 
								{ 1, 0, 4, 4, 4, 1, 4, 0, 4, 0, 4, 0}, 
								{ 1, 0, 1, 1, 0, 1, 4, 1, 4, 0, 4, 0}, 
								{ 1, 0, 1, 0, 0, 0, 4, 4, 4, 0, 4, 0}, 
								{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 
							}; 
	char Touche;
	bool TValide = false;
	bool DValide = false;

	cout << "D\x82" "couvrez et amassez 15 cases $$$$"<< setw(44) << "Points:" << Points;
	
	while (Points<15)
	{
		/* VALIDER LA TOUCHE */
		do
		{
			Touche = _getch();
			if (Touche==80 || Touche==72 || Touche==77 || Touche==75 || Touche==73 || Touche==71 || Touche==79 || Touche==81)
			{
				TValide = true;
			}
		} while(!TValide);

		/* VALIDER LE DÉPLACEMENT ET SE DÉPLACER */
		if (Touche == 80)
		{
			// Bas
			if (Mat[Lig+1][Col]==4 || Lig==NB_LIG-1)
				DValide = false;
			else
			{
				Lig++;
				DValide = true;
			}
		}
		if (Touche == 72)
		{
			// Haut
			if (Mat[Lig-1][Col]==4 || Lig==0)
				DValide = false;
			else
			{
				Lig--;
				DValide = true;
			}
		}
		if (Touche == 77)
		{
			// Droite
			if (Mat[Lig][Col+1]==4 || Col==NB_COL-1)
				DValide = false;
			else
			{
				Col++;
				DValide = true;
			}
		}
		if (Touche == 75)
		{
			// Gauche
			if (Mat[Lig][Col-1]==4 || Col==0)
				DValide = false;
			else
			{
				Col--;
				DValide = true;
			}
		}
		if (Touche == 73)
		{
			// Haut Droite
			if (Mat[Lig-1][Col+1]==4 || Lig==0 || Col==NB_COL-1)
				DValide = false;
			else
			{
				Lig--;
				Col++;
				DValide = true;
			}
		}
		if (Touche == 71)
		{
			// Haut Gauche
			if (Mat[Lig-1][Col-1]==4 || Lig==0 || Col==0)
				DValide = false;
			else
			{
				Lig--;
				Col--;
				DValide = true;
			}
		}
		if (Touche == 79)
		{
			// Bas Gauche
			if (Mat[Lig+1][Col-1]==4 || Lig==NB_LIG-1 || Col==0)
				DValide = false;
			else
			{
				Lig++;
				Col--;
				DValide = true;
			}
		}
		if (Touche == 81)
		{
			// Bas Droite
			if (Mat[Lig+1][Col+1] || Lig==NB_LIG-1 || Col==NB_COL-1)
				DValide = false;
			else
			{
				Lig++;
				Col++;
				DValide = true;
			}
		}

	// MODIFICATION DE LA MATRICE ET ACCUMULATION DE POINTS
	do
	{
		if (Mat[Lig][Col]==0)
			Mat[Lig][Col]=3;
		if (Mat[Lig][Col]==1)
			Mat[Lig][Col]=2;
		/* CETTE PARTIE N'A PAS L'AIR DE FONCTIONNER--------------
		if (Mat[Lig][Col]==2)
		{
			Mat[i][j]=3;
			Points++;
		}
		if (Mat[Lig][Col]==3)
			Mat[i][j]=4;
		---------------------------------------------------------*/
	} while (!DValide);

//--------------------------------------------------------------------------

	/* AFFICHER LE JEU */
	for (i=0; i<NB_LIG; i++) // Pierre blanche + $$$$ cache
	{
		for (j=0; j<NB_COL; j++)
		{	
			if (Mat[i][j]==0 || Mat[i][j]==1)
			{
				gotoxy(j*5+11, i*3+3);
				cout << (char) 178 << (char) 178 << (char) 178 << (char) 178;
				gotoxy(j*5+11, i*3+4);
				cout << (char) 178 << (char) 178 << (char) 178 << (char) 178;
			}
		}
	}
	for (i=0; i<NB_LIG; i++) // $$$$ visible
	{
		for (j=0; j<NB_COL; j++)
			{
				if (Mat[i][j]==2)
				{
					gotoxy(j*5+11, i*3+3);
					cout << "$$$$";
					gotoxy(j*5+11, i*3+4);
					cout << "$$$$";
				}
			}
	}
	for (i=0; i<NB_LIG; i++) // Pierre grise
	{
		for (j=0; j<NB_COL; j++)
			{
				if (Mat[i][j]==3)
				{
					gotoxy(j*5+11, i*3+3);
					cout << (char) 176 << (char) 176 << (char) 176 << (char) 176;
					gotoxy(j*5+11, i*3+4);
					cout << (char) 176 << (char) 176 << (char) 176 << (char) 176;
				}
			}
	}

	/* CURSEUR (POSITION INITIALE)*/
	gotoxy(Col*5+11, Lig*3+3);
	cout << (char) 201 << (char) 203 << (char) 203 << (char) 187;
	gotoxy(Col*5+11, Lig*3+4);
	cout << (char) 200 << (char) 202 << (char) 202 << (char) 188;

	} // Fin boucle while()
	_getch();
}

___________________________________________________________________________

Le problème... c'est que rendu à "// MODIFICATION DE LA MATRICE ET ACCUMULATION DE POINTS" lorsque la case $$$$ est dévoilée et je que repasse par dessus, la case ne devient pas grise pour ensuite devenir noire, au lieu, rien ne se passe. Tout comme lors d'un passage à une case grise, elle ne devient pas noire. Le curseur se déplace correctement mais, les cases ne changent pas de couleur.

3 réponses

Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Salut.
Je n'ai pas lu l'ensemble de ton programme, mais que la partie que tu pointes comme problématique :
do
	{
		if (Mat[Lig][Col]==0)
			Mat[Lig][Col]=3;
		if (Mat[Lig][Col]==1)
			Mat[Lig][Col]=2;
		/* CETTE PARTIE N'A PAS L'AIR DE FONCTIONNER--------------
		if (Mat[Lig][Col]==2)
		{
			Mat[i][j]=3;
			Points++;
		}
		if (Mat[Lig][Col]==3)
			Mat[i][j]=4;
		---------------------------------------------------------*/
	} while (!DValide);

Déjà, c'est une boucle infinie, ta condition de sortie c'est DValide, et cette variable n'est pas modifiée dans le do while. Ensuite, tu modifies Mat[i][j], mais je n'ai pas vu où les valeurs de i et de j prenaient des valeurs particulière. De ce que je vois i et j prennent les dernières valeurs de la boucle d'affichage.
En C++ tu peut déclarer tes variable dans les boucle, for(int i=0..., ce qui reduit ces variables muettes à la porté de la boucle et évite les erreurs d'utilisation ailleurs (à moins que ça soit ce que tu veuilles faire).

autre petite erreur : if (Mat[Lig+1][Col]==4 || Lig==NB_LIG-1)
qu'il vaut mieux écrire if ( Lig==NB_LIG-1 || Mat[Lig+1][Col]==4 ) car sinon dans le cas où Lig==NB_LIG-1 Mat[Lig+1]Col] sort tu tableau et tu risque une erreur de segmentation. Pareil pour les autres if et autre directions. D'ailleurs, à la place de tes if(Touche==num) tu devrais mettre un switch ça serai plus clair.
0
Pseudo2206
 
J'ai fait quelques modifications. Ça ne fonctionne toujours pas.

1) Lorsque je clique 2x sur les extrémités (ex: je suis au coin de départ Mat[0][0], je descend d'une case pour ensuite appuyer sur "haut" "haut") l'emprunte du curseur reste à la case Mat[0][0] mais, mon curseur se déplace quand même. Si je clique 3x sur une touche lorsque je suis à une extrémité, mon curseur ne se déplace plus.

2) Au départ, l'écran est noir avec seulement la ligne "cout << "D\x82" "couvrez et amassez 15 cases $$$$"<< setw(44) << "Points:" << Points;". Je dois appuyer sur une touche directionnelle pour afficher le jeu.

3) Les cases sont toutes grises au départ et aucun changement ne se fait lorsque je me déplace.

Code modifié:
#include <iostream>
#include <conio.h>
#include <iomanip>
#include "E://cvm.h"
using namespace std;

void main(void)
{
	const int BAS=80, HAUT=72, DROITE=77, GAUCHE=75, HD=73, HG=71, BG=79, BD=81; 
	const int NB_LIG=8, NB_COL=12; 
	int i=0, j=0, Lig=0, Col=0, Points=0; 

	// Matrice composant le damier du jeu : 
	// 0==Normal(Pierre blanche), 1==$$$$ caché, 2==$$$$ visible, 3==Pierre grise, 4==Mur Noir 
	int Mat[NB_LIG][NB_COL]={	{ 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 1}, 
								{ 0, 0, 4, 4, 0, 0, 0, 0, 0, 4, 0, 4}, 
								{ 0, 0, 4, 1, 4, 0, 0, 0, 0, 0, 4, 1}, 
								{ 0, 0, 4, 1, 4, 0, 0, 4, 4, 0, 4, 1}, 
								{ 1, 0, 4, 4, 4, 1, 4, 0, 4, 0, 4, 0}, 
								{ 1, 0, 1, 1, 0, 1, 4, 1, 4, 0, 4, 0}, 
								{ 1, 0, 1, 0, 0, 0, 4, 4, 4, 0, 4, 0}, 
								{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 
							}; 
	char Touche;
	bool TValide = false;
	bool DValide = false;

	cout << "D\x82" "couvrez et amassez 15 cases $$$$"<< setw(44) << "Points:" << Points;
	
	while (Points<15)
	{
		/* VALIDER LA TOUCHE */
		do
		{
			Touche = _getch();
			if (Touche==80 || Touche==72 || Touche==77 || Touche==75 || Touche==73 || Touche==71 || Touche==79 || Touche==81)
			{
				TValide = true;
			}
		} while(!TValide);

		/* VALIDER LE DÉPLACEMENT ET SE DÉPLACER */
		switch (Touche)
		{
		// Bas
		case 80:
			if (Lig==NB_LIG-1 || Mat[Lig+1][Col]==4)
				DValide = false;
			else
			{
				Lig++;
				DValide = true;
			}
			break;
		// Haut
		case 72:
			if (Lig==0 || Mat[Lig-1][Col]==4)
				DValide = false;
			else
			{
				Lig--;
				DValide = true;
			}
			break;
		// Droite
		case 77:
			if (Col==NB_COL-1 || Mat[Lig][Col+1]==4)
				DValide = false;
			else
			{
				Col++;
				DValide = true;
			}
			break;
		// Gauche
		case 75:
			if (Col==0 || Mat[Lig][Col-1]==4)
				DValide = false;
			else
			{
				Col--;
				DValide = true;
			}
			break;
		// Haut Droite
		case 73:
			if (Col==NB_COL-1 || Lig==0 || Mat[Lig-1][Col+1]==4)
				DValide = false;
			else
			{
				Lig--;
				Col++;
				DValide = true;
			}
			break;
		// Haut Gauche
		case 71:
			if (Lig==0 || Col==0 || Mat[Lig-1][Col-1]==4)
				DValide = false;
			else
			{
				Lig--;
				Col--;
				DValide = true;
			}
			break;
		// Bas Gauche
		case 79:
			if (Lig==NB_LIG-1 || Col==0 || Mat[Lig+1][Col-1]==4)
				DValide = false;
			else
			{
				Lig++;
				Col--;
				DValide = true;
			}
			break;
		// Bas Droite
		case 81:
			if (Lig==NB_LIG-1 || Col==NB_COL-1 || Mat[Lig+1][Col+1]==4)
				DValide = false;
			else
			{
				Lig++;
				Col++;
				DValide = true;
			}
			break;
		}

	// MODIFICATION DE LA MATRICE ET ACCUMULATION DE POINTS
	while (!DValide)
	{
		if (Mat[Lig][Col]==0){
			Mat[Lig][Col]=3;
			DValide = true;}
		if (Mat[Lig][Col]==1){
			Mat[Lig][Col]=2;
			DValide=true;}
		/* CETTE PARTIE N'A PAS L'AIR DE FONCTIONNER--------------*/
		if (Mat[Lig][Col]==2)
		{
			Mat[Lig][Col]=3;
			Points++;
			DValide = true;
		}
		if (Mat[Lig][Col]==3){
			Mat[Lig][Col]=4;
			DValide = true;}
		/*---------------------------------------------------------*/
	}

//--------------------------------------------------------------------------

	/* AFFICHER LE JEU */
	for (i=0; i<NB_LIG; i++) // Pierre blanche + $$$$ cache
	{
		for (j=0; j<NB_COL; j++)
		{	
			if (Mat[i][j]==0 || Mat[i][j]==1)
			{
				gotoxy(j*5+11, i*3+3);
				cout << (char) 178 << (char) 178 << (char) 178 << (char) 178;
				gotoxy(j*5+11, i*3+4);
				cout << (char) 178 << (char) 178 << (char) 178 << (char) 178;
			}
		}
	}
	for (i=0; i<NB_LIG; i++) // $$$$ visible
	{
		for (j=0; j<NB_COL; j++)
			{
				if (Mat[i][j]==2)
				{
					gotoxy(j*5+11, i*3+3);
					cout << "$$$$";
					gotoxy(j*5+11, i*3+4);
					cout << "$$$$";
				}
			}
	}
	for (i=0; i<NB_LIG; i++) // Pierre grise
	{
		for (j=0; j<NB_COL; j++)
			{
				if (Mat[i][j]==3)
				{
					gotoxy(j*5+11, i*3+3);
					cout << (char) 176 << (char) 176 << (char) 176 << (char) 176;
					gotoxy(j*5+11, i*3+4);
					cout << (char) 176 << (char) 176 << (char) 176 << (char) 176;
				}
			}
	}

	/* CURSEUR (POSITION INITIALE)*/
	gotoxy(Col*5+11, Lig*3+3);
	cout << (char) 201 << (char) 203 << (char) 203 << (char) 187;
	gotoxy(Col*5+11, Lig*3+4);
	cout << (char) 200 << (char) 202 << (char) 202 << (char) 188;

	} // Fin boucle while()
	_getch();
}


4) Devrais-je plutôt mette la "MODIFICATION DE LA MATRICE ET ACCUMULATION DE POINTS" dans un while ou dans aucune boucle?
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
un while est une boucle.
while (!DValide)
	{
		if (Mat[Lig][Col]==0){
			Mat[Lig][Col]=3;
			DValide = true;}
		if (Mat[Lig][Col]==1){
			Mat[Lig][Col]=2;
			DValide=true;}
		/* CETTE PARTIE N'A PAS L'AIR DE FONCTIONNER--------------*/
		if (Mat[Lig][Col]==2)
		{
			Mat[Lig][Col]=3;
			Points++;
			DValide = true;
		}
		if (Mat[Lig][Col]==3){
			Mat[Lig][Col]=4;
			DValide = true;}
		/*---------------------------------------------------------*/
	}
As tu conscience que le if ne sort pas de la boucle ?
Ta façon de faire est étrange :
si Mat vaut 0, à la fin du bloc elle vaudra 4
si Mat vaut 1, à la fin du bloc elle vaudra 4, Points est incrémenté
si Mat vaut 2, à la fin du bloc elle vaudra 4, Points est incrémenté
si Mat vaut 3, à la fin du bloc elle vaudra 4
Si c'est vraiment ce que tu veux faire, il y a plus simple pour l'écrire.

Le problème de ton code, c'est que tu ne traites pas le cas où le déplacement est invalide (sort du bloc). Tu lui dit de monter, la touche est valide tu sort donc du while Touche, et tu rentre dans le switch, qui du coup ne fais rien puisque tu tente de sortir du domaine. Ensuite tu rentres dans la boucle que j'ai recopié (attention d'ailleur, si ton déplacement est valide tu ne rentreras pas dans la boucle).
Revenons d'ailleurs sur cette boucle : elle ne sert à rien ! En effet, soit Mat vaut 0 1 2 ou 3 et tu sorts après le premier passage soit Mat vaut autre chose et tu boucle infiniment.
0