Voilà suite au morpion de nb1992, qui était toutefois un peu trop compliqué pour moi (notamment le fait que le tableau se réactualise dynamiquement, ça je sais pas encore comment il fait), j'ai voulu me faire mon propre morpion sans l'aide de personne, j'ai presque réussi. Bon alors pour ceux qui sont plus forts, ça va être la catastrophe parceque il est vrai que c'est pas très clair, mais au moins j'ai réussi à faire un truc qui fonctionne bien, je suis vraiment content, j'ai passé 3 heures dessus depuis ce matin, et le voir enfin fonctionné me fait plaisir.
J'ai essayé de le faire en programmation objet même si dans mon bouquin j'ai juste à peine commencé la programmation objet, donc excusez si c'est un peu fouilli ou de la "mauvaise" POO. Si vous avez des remarques pour comment rendre plus clair, et éventuellement réduire ce qu'il y a dans main, et d'améliorer l'affichage du tableau ^^, d'optimiser,...
J'ai juste quelques petits problèmes qui persistent. A la fin de chaque partie, j'aimerais écrire le nombre de victoire du joueur1 et celles du joueur2. J'ai donc créé une classe Joueurs (c'est bon, elle est faite), mais en fait je voudrais appeler des fonctions membres de la classe Joueur à partir de la classe TicTacToe. Je suppose que c'est un truc à base de fonction friend ou je sais pas quoi, mais j'ai pas encore vu ça, mais si c'est facile, n'hésitez pas.
J'ai mis en commentaire ce que je souhaiterai mettre, ça se passe dans la classe TicTacToe, dans la définition de la fonction vérifier (qui est pour l'instant const).
Voilà le code (sur les commentaires j'indique les trucs à corriger et/ou améliorer):
main() :
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include "tictactoe.h"
#include "joueurs.h"
void afficherRegles();
int main()
{
char jouer;
cout << "\t\t\t*********JEU DU MORPION********* (v 1.0)\n\n\n"
<< "Afficher les regles ? (o/n) ";
cin >> jouer;
if (jouer == 'o')
{
afficherRegles();
}
cout << endl << endl << endl;
Joueurs Personne1; // Créé les deux personnes qui jouent
Joueurs Personne2;
// Alors attention, ici c'est le bazar complet ^_^
do
{
TicTacToe tableJeu; // Créé un objet TicTacToe
bool etat = false;
tableJeu.dessiner();
// Reste dans la boucle tant que toutes les cases n'ont pas été remplies
// ou tant que Etat est false.
for (int i = 0 ; i < 9 && etat == false ; i++)
{
int colonne, ligne;
if (i % 2 == 0) // Permet à chaque joueur de jouer à tour de rôle
{
cout << "Joueur 1 (ligne colonne) : ";
cin >> ligne >> colonne;
tableJeu.remplir(ligne, colonne, 'X');
}
else
{
cout << "Joueur 2 (ligne colonne) : ";
cin >> ligne >> colonne;
tableJeu.remplir(ligne, colonne, 'O');
}
cout << endl;
tableJeu.dessiner();
// Vérifie qu'à partir du quatrième coup puisqu'il est impossible de
// gagner en trois coups. Maintenant je ne sais pas si c'est mieux
// de mettre cet opérateur ternaire plutôt que d'effectuer à chaque
// fois toutes les possibilitées.
i > 3 ? (etat = tableJeu.verifier()) : ' ';
}
etat == false ? cout << "Personne ne gagne, voulez-vous rejouer (o/n) ? " :
cout << "Voulez-vous rejouer (o/n) ? ";
cin >> jouer;
cout << endl << endl << endl;
}
while (jouer == 'o');
cin.ignore();
return 0;
}
// Affiche les règles, tout simplement ^^
void afficherRegles()
{
cout << "Vous devez aligner trois X ou trois O en diagonale, horizontale "
<< "ou verticale.\nPour valider une position, entrez d'abord la ligne "
<< "(0, 1 ou 2), puis la colonne (0, 1 ou 2) puis validez avec Enter."
<< endl << endl;
system("PAUSE");
}
TicTacToe.h :
// Class automatically generated by Dev-C++ New Class wizard
#ifndef TICTACTOE_H
#define TICTACTOE_H
class TicTacToe
{
public:
TicTacToe();
~TicTacToe();
void dessiner() const;
bool verifier() const;
void remplir(int, int, char);
private:
char tableauJeu [3][3];
};
#endif // TICTACTOE_H
TicTacToe.cpp (d'ailleurs comment on appelle ça ? Je crois que TicTactoe.h porte le nom d'en tête, mais ou on définit le tout, ça porte quel nom ?) :
// Class automatically generated by Dev-C++ New Class wizard
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
#include "tictactoe.h" // class's header file
#include "joueurs.h"
// Initialise le plateau de jeu à un caractère blanc
TicTacToe::TicTacToe()
{
for (int i = 0 ; i < 3 ; i++)
for (int j = 0 ; j < 3 ; j++)
tableauJeu [i][j] = ' ';
}
// Destructeur
TicTacToe::~TicTacToe()
{
}
// Dessine le tableau avec éventuellement des 'X' ou des 'O'.
// Méthode super pas clair du tout, à améliorer ^^.
void TicTacToe::dessiner() const
{
cout << " 0 1 2" << endl << endl;
for (int i = 0 ; i < 3 ; ++i)
{
cout << i << " ";
for (int j = 0 ; j < 3 ; ++j)
{
cout << " " << tableauJeu [i][j] << " |";
}
cout << endl << " ---|---|---|" << endl;
}
}
// Rempli le tableau à l'aide du caractère fourni. Si la ligne et la colonne
// demandé sont déjà prises par un caractère, un message d'erreur s'affiche.
void TicTacToe::remplir (int ligne, int colonne, char caractere)
{
while ( (tableauJeu [ligne][colonne] == 'X') ||
(tableauJeu [ligne][colonne] == 'O') )
{
int a, b;
cout << "Place deja occupee. Entrez une nouvelle place : ";
cin >> a >> b;
ligne = a;
colonne = b;
}
tableauJeu [ligne][colonne] = caractere;
}
// Vérifie tout simplement chaque possibilité de gagner.
bool TicTacToe::verifier() const
{
// Verification pour les 'X'
if ( (tableauJeu [0][0] == 'X' && tableauJeu [0][1] == 'X' && tableauJeu [0][2] == 'X') ||
(tableauJeu [1][0] == 'X' && tableauJeu [1][1] == 'X' && tableauJeu [1][2] == 'X') ||
(tableauJeu [2][0] == 'X' && tableauJeu [2][1] == 'X' && tableauJeu [2][2] == 'X') ||
(tableauJeu [0][0] == 'X' && tableauJeu [1][0] == 'X' && tableauJeu [2][0] == 'X') ||
(tableauJeu [0][1] == 'X' && tableauJeu [1][1] == 'X' && tableauJeu [2][1] == 'X') ||
(tableauJeu [0][2] == 'X' && tableauJeu [1][2] == 'X' && tableauJeu [2][2] == 'X') ||
(tableauJeu [0][0] == 'X' && tableauJeu [1][1] == 'X' && tableauJeu [2][2] == 'X') ||
(tableauJeu [0][2] == 'X' && tableauJeu [1][1] == 'X' && tableauJeu [2][0] == 'X') )
{
cout << "Joueur 1 gagne.\n\n";
// Ce que je voudrai insérer mais qui ne marche pas :
// Joueurs.setJoueur1() : incrémenterai la valeur de 1.
// Joueurs.lireJoueur()
return true;
}
// Verification pour les 'O'
if ( (tableauJeu [0][0] == 'O' && tableauJeu [0][1] == 'O' && tableauJeu [0][2] == 'O') ||
(tableauJeu [1][0] == 'O' && tableauJeu [1][1] == 'O' && tableauJeu [1][2] == 'O') ||
(tableauJeu [2][0] == 'O' && tableauJeu [2][1] == 'O' && tableauJeu [2][2] == 'O') ||
(tableauJeu [0][0] == 'O' && tableauJeu [1][0] == 'O' && tableauJeu [2][0] == 'O') ||
(tableauJeu [0][1] == 'O' && tableauJeu [1][1] == 'O' && tableauJeu [2][1] == 'O') ||
(tableauJeu [0][2] == 'O' && tableauJeu [1][2] == 'O' && tableauJeu [2][2] == 'O') ||
(tableauJeu [0][0] == 'O' && tableauJeu [1][1] == 'O' && tableauJeu [2][2] == 'O') ||
(tableauJeu [0][2] == 'O' && tableauJeu [1][1] == 'O' && tableauJeu [2][0] == 'O') )
{
cout << "Joueur 2 gagne.\n\n";
// Ce que je voudrai insérer mais qui ne marche pas :
// Joueurs.setJoueur2() : incrémenterai la valeur de 1.
// Joueurs.lireJoueur()
return true;
}
return false;
}
Joueurs.h :
// Class automatically generated by Dev-C++ New Class wizard
#ifndef JOUEURS_H
#define JOUEURS_H
class Joueurs
{
public:
Joueurs();
~Joueurs();
void setJoueur1() {joueur1++;}
void setJoueur2() {joueur2++;}
void lireJoueur() const;
private:
int joueur1;
int joueur2;
};
#endif // JOUEURS_H
Joueurs.cpp :
// Class automatically generated by Dev-C++ New Class wizard
#include <iostream>
using std::cout;
#include "joueurs.h" // class's header file
// Initialise le nombre de victoire de chaque joueur à 0
Joueurs::Joueurs()
{
joueur1 = 0;
joueur2 = 0;
}
Joueurs::~Joueurs()
{
}
void Joueurs::lireJoueur() const
{
cout << "Le joueur 1 a gagne " << joueur1 << " fois.\n"
<< "Le joueur 2 a gagne " << joueur2 << " fois.\n";
}
Merci beaucoup ^^.
NB : pendant que j'y suis, je viens d'apercevoir une petite faute. Quand on poste le message, il s'affiche : ( Votre sujet apparaîtra sur tout les forums des noeuds ascendant )
Sinon pour un premier prog en poo ca à l'air pas mal (j'ai lu pratiquement tout le cours de mon bouqin mais je l'ai jamais mis vraiment en pratique).
L'essentiel est que ton code soit clair et qu'on ai pas besoin de toi pour comprendre ce que le programme fait, ce qui est le cas et c'est tres bien!
Sinon, j'ai pas regardé l'implémentation de tes classes ( ce qui montre que ton code est bien fait), mais dans un header (un .h) la convention veut qu'il n'y ait aucune ligne de code, mais que des déclarations, comme tu l'as fait avec joueur.h et joueurs.cpp.
Sinon si tu trouves que ton main () est trop volumineux, tu peux faire un truc du genre :
int main()
{
accueil();
jeu();
return 0;
}
// avec :
accueil()
{
cout <<voulez vous voir l'aide??.
...
}
// et jeu() qui contient tout le code que t'as mis
ce qui peut etre sympa ca serait de pouvoir avoir acces à l'aide pendant la partie. Dans ce cas c'est pas tres utile vu que les regles sont megas simples mais bon ca t'entraine à le faire.
__________________________
L'élève heureux est celui qui, comme la rivère, suit son cours dans son lit.
Et n'oubliez pas :Seb, c'est bien!
Alors, j'ai regarder ton programme et j'ai vu, comme sebsheep que ton main() est en effet très volumineux :8): Il vaut mieux que tu coupes ton programme en plusieurs bouts ce qui le fera plus clair mais aussi plus simple à comprendre :wink:
sinon pour le programme en lui-même, il est bien foutu :wink:
j'espère arriver à sortir la v1.3 car la je me lance dans allegro et j'en oublie mon petit projet :oops:
toute facon, ce sera la dernière version :8): :8):
P.S je savais pas que ça existait ça:
[quote]cin >> ligne >> colonne;[/quote]
comme quoi, on en apprend tous les jours :lol:
__________________________
Le pouvoir de l'homme est l'obtention d'un cerveau, même si certains n'en profitent pas :wink:
ERREUR BBCODE SUR CE MESSAGE : - La valeur de la balise "quote" n'est pas correcte !
nb1992 > Pour le main en effet j'essayerai de le couper mais j'aimerais d'abord corriger le problème qui me gêne. Visiblement personne n'arrive à m'aider même sur developpez.net.
Je vais essayer de réexpliquer : c'est donc au niveau de la définition de la fonction membre verifier dans la classe TicTacToe. Elle verifie tout simplement à tour de rôle pour les X et pour les O. Ce que je veux tout simplement faire, c'est que quand le Joueur 1 (donc qui joue les X), gagne, son compteur de victoire soit incrémenté de 1, et quand joueur 2 gagne son compteur incrémenté de 1. A chaque fin de partie, on affiche les scores.
Au tout départ j'avais pensé à ajouter à même la classe du TicTacToe deux joueurs et des méthodes membres pour incrémenter la valeur et une méthode membre pour lire. Le problème : le tableau du tictactoe étant supprimé à chaque fin de partie (et éventuellement recréé si on fait une nouvelle partie), tout ce qu'il y a à l'intérieur donc les valeurs de joueur1 et joueur2, sont supprimées.
J'ai essayé de déclarer joueur1 et joueur2 static mais ça ne marche pas mieux, je vais peut-être essayé de les déclarer static et les méthodes membres correspondantes static aussi mais pas sûr que ça marche.
C'est pourquoi j'ai créer une classe Joueurs, ainsi j'instancie les deux joueurs au tout début du programme, ainsi quand ils sont supprimés, c'est dès que le programme se termine, donc ça arrange mes affaires.
Et donc on voit ce que je voudrais faire :
Personne1.setJoueur();
Personne1.lireJoueur();
Ca c'est dans la classe TicTacToe. En gros je voudrais utiliser des méthodes de la classe Joueurs dans la classe TicTacToe mais ça ne marche pas, même en la déclarant friend, alors je sias pas quoi faire :(.
sebsheep > Disons que le TicTacToe ce n'est pas très compliqué et c'est bien plus ludique que de calculer la suite de Fibonacci. J'ai pris bcp de plaisir à côdé ça alorsque les autres exercices du bouquin sur des trucs de math et tout, j'aime beaucoup moins (enfin c'est parceque j'y arrive pas ^^)
nb1992 > Tu fais allegro maintenant ? Tu utilises un bouquin pour l'apprendre ?
pourquoi n'incrémentes-tu pas simplement joueur1; ou joueur2; de 1 après la victoire
ensuite, tu n'a plus qu'a rappeller ces valeur
Pour allegro, déjà il faudrait que j'arrive à l'installer et c'est pas gagner, ça fait plusieurs jours que je patine et devc++ ne le reconnait pas alors que j'ai bien copier les fichiers au bon endroit bon allez, j'y retourne :():
__________________________
Le pouvoir de l'homme est l'obtention d'un cerveau, même si certains n'en profitent pas
Je ne vois pas ce que tu veux dire. Et puis les variables sont privates je peux pas les modifier comme ça je passe par une méthode membre. Le problème tu le verras, mets tout mon code et dans la définition de la fonction verifier tu vérifie les lignes de commentaires (tu les trouveras).
ok je vais regarder ton truc mais J'AI REUSSI A FAIRE UN PROG ALLEGRO
si ça peux me simplifier la vie, c'est dans lequelle de toute tes pages de codes :():
__________________________
Le pouvoir de l'homme est l'obtention d'un cerveau, même si certains n'en profitent pas
dans la classe tictactoe.cpp a la définition de la fonction verifier, tu le trouveras, il est en commentaire normalement. En fait je veux juste appelé les méthodes membres de la fonction joueurs DANS la fonction de la classe tictac.
Euh désolé en fait j'avais pas vu que t'avais un tictatoe.cpp et un tictactoe.h .... en passant pourquoi donner un nom si compliqué à ta classe??
Sinon pour ton probleme, tu pourrais faire une fonction qui te renvoie la vainqueur. Par exemple, elle renvoie 0 si personne ne gagne, 1 si le joueur 1 gagne, et 2 si le joueur 2 gagne.
Apres faut que tu fasses une fonction membre de joueurs , par exemple :
incremente_cpt_victoire()
{
cptr_victoire++;
}
que tu appelles lorsque l'un ou l'autre joueur gagne... tout simplement, et evidement tu gardes les mêmes instances joueurs1 et joueurs2 tout le long du jeu! C'est beaucoup plus simple.
Atention sur les variables statics... ce sont des variables qui ont la même valeur pour tous les objets de la classe, donc tu ne peux pas les utiliser ici
__________________________
L'élève heureux est celui qui, comme la rivère, suit son cours dans son lit.
Et n'oubliez pas :Seb, c'est bien!