@TheLittlePolo au lieu de mettre `std::` a chaque fois, ecris
using namespace std
`` juste apres les entetes (#include ).
Meme cet exercice je l'ai fais mais je vais plus commenter pour eviter les enguelades. Fais le en projet pour le scinder, moi je le trouvais trop long donc je l'ai fais,
Après ton conseil sur le random et celui-ci c'est quoi le prochain truc tout moisi que tu vas nous sortir ? L'utilisation des pointeurs nus peut-être ? Serait peut-être temps de te mettre à la page et de regarder un peu ce qui se fait (ou ne se fait plus) actuellement en C++.
Tiens un peu de lecture sur cette directive dont tu prônes l'utilisation :
> N'utilise pas std::vector::at(...) (je ne sais plus pourquoi mais c'est déconseillé), utilise l'opérateur fait pour [...]
les fonctions at des conteneurs de la stl lancent une exception si l'indice n'existe pas, alors qu'il faudrait le vérifier en amont. C'est davantage une erreur de programmation (donc assertion) que d'exécution (programmation défensive ici). Voir les 3 billets de Luc sur le sujet.
@TheLittlePolo:
std::array serait effectivement mieux que std::vector ici
pense à mettre les arguments de fonction en référence constante (i.e. const&) lorsqu'ils ne sont utilisés qu'en lecture. Cela évite les copies inutiles des "gros" objets (en gros, tous sauf les entiers, flottants et énumérations)
> Sinon ne t'embête pas si tu n'y arrives pas, demain c'est Lundi, les stagiaires de chez Openclassrooms seront là pour finir leur boulot sur l'éditeur.
OUI @Giut0Xx, c'est pour ca que je commente plus mon programme sur le tictac est comme plus pour lui dans ce cas. J'ai respecter et appliquer seulement C++.
Je parlais juste de faire ca dans un projet et d'y donner meme une icone si il veut. Mes commentaires ne sont pas tout pourri, je dis juste ce que je pense mais toi tu me contredis, a chacun son opinion tant que le programme final est leger et efficace.
En effet les grillades c'est pas trop le projet pour l'instant^^
Grill fait donc partie de l'horrible famille des mots anglais qui ressemblent aux mots français mais avec un sens totalement différent
Bon avec les modifs:
#include <iostream>
#include <array>
void Display_grid(std::array<char,9> const &content){
std::cout<<content[0]<<'|'<<content[1]<<'|'<<content[2]<<std::endl;
std::cout<<"-+-+-"<<std::endl;
std::cout<<content[3]<<'|'<<content[4]<<'|'<<content[5]<<std::endl;
std::cout<<"-+-+-"<<std::endl;
std::cout<<content[6]<<'|'<<content[7]<<'|'<<content[8]<<std::endl;
}
std::array<char,9> Update_grid(int const &nextMove, char const &sign, std::array<char,9> grid){
grid[nextMove-1]=sign;
return grid;
}
bool Someone_won(std::array<char,9>const &grid){//Conditions pour qu'un des deux joueurs gagne. Un peu barbare, mais je voyais pas comment faire autrement X)
bool win;
if((grid[0]==grid[1] && grid[1]==grid[2]) or (grid[0]==grid[3] && grid[3]==grid[6])
or (grid[0]==grid[1] && grid[2]==grid[8]) or (grid[1]==grid[4] && grid[4]==grid[7])
or (grid[2]==grid[5] && grid[5]==grid[8]) or (grid[2]==grid[4] && grid[4]==grid[6])
or (grid[3]==grid[4] && grid[4]==grid[5]) or (grid[6]==grid[7] && grid[7]==grid[8])){
win=true;
}
else{
win=false;
}
return (win);
}
int main(){
bool restart{false};
do{
int nextMove, movesCount=0;
bool gameOver{false};
bool player1Turn{true};
std::array<char,9>grid{'1','2','3','4','5','6','7','8','9'};
Display_grid(grid);
do{
//Demander le coup du joueur
if(player1Turn){
std::cout<<"Player1's turn: ";
std::cin>>nextMove;
}
else{
std::cout<<"Player2's turn: ";
std::cin>>nextMove;
}
std::cout<<std::endl;
//vérifier la validité de son coup
while(nextMove<1 or nextMove>9 or grid[nextMove-1]=='X' or grid[nextMove-1]=='O'){//Conditions d'invalidité de l'entrée du joueur
std::cout<<"Invalid entry"<<std::endl;
std::cin>>nextMove;
}
//Mettre à jour et la grille en fonction du coup du joueur et l'afficher
if(player1Turn){
grid=Update_grid(nextMove,'X',grid);
player1Turn=false;
}
else{
grid=Update_grid(nextMove,'O',grid);
player1Turn=true;
}
movesCount++;
Display_grid(grid);
if(Someone_won(grid)){
//déterminer quel joueur a gagné (le dernier à avoir joué)
if(grid[nextMove-1]=='X'){
std::cout<<"Player1 wins!"<<std::endl;
}
else{
std::cout<<"player2 wins!"<<std::endl;
}
gameOver=true;
//En cas d'égalité
}else if (movesCount==9){
std::cout<<"Draw!"<<std::endl;
gameOver=true;
}
}while(!gameOver);
std::cout<<"Restart?(0/1)";
std::cin>>restart;
}while (restart);
}
Edit: moi j'y comprends plus rien avec le code , là semble le formater...à moitié?
Bon j'ai trifouillé un peu ton code de mon côté, et certaines condition à base de if...else peuvent se simplifier en condition ternaire.
La fonction Update_grid() n'est pas vraiment nécessaire, d'autant plus que tu fais une copie inutile du tableau, un passage par référence serait bienvenue .
À la place de la fonction Display_grid(), j'aurai plutôt surchargé l'opérateur << . Ici tu crées une dépendance (à <ostream>) potentiellement invisible, bon là on voit le corps de la fonction donc on sait ce qu'il y a à l'intérieur mais ce ne sera pas toujours le cas.
Dans la fonction Someone_won(), le booléen et le if...else ne sont pas nécessaire, un if suffit .
Bon c'est à peu près tout (du moins ce que j'ai pu voir).
(T'embêtes pas avec le formatage du code de l'éditeur, ça fait l'affaire même en noir et blanc . D'ailleurs j'espère que les stagiaires finiront par trouver la panne)
#include <iostream>
#include <array>
void Display_grid(std::array<char,9> const &content){
std::cout<<content[0]<<'|'<<content[1]<<'|'<<content[2]<<std::endl;
std::cout<<"-+-+-"<<std::endl;
std::cout<<content[3]<<'|'<<content[4]<<'|'<<content[5]<<std::endl;
std::cout<<"-+-+-"<<std::endl;
std::cout<<content[6]<<'|'<<content[7]<<'|'<<content[8]<<std::endl;
}
bool Are_equal(char a, char b, char c){
return(a==b && b==c && a!=' ');
}
bool Someone_won(std::array<char,9>const &grid){
if(Are_equal(grid[0],grid[1],grid[2]) or Are_equal(grid[0],grid[4],grid[8])
or Are_equal(grid[0],grid[3],grid[6]) or Are_equal(grid[1],grid[4],grid[7])
or Are_equal(grid[2],grid[5],grid[8]) or Are_equal(grid[2],grid[4],grid[6])
or Are_equal(grid[3],grid[4],grid[5]) or Are_equal(grid[6],grid[7],grid[8])){
return true;
}
return false;
}
int main(){
bool restart{false};
do{
int nextMove, movesCount=0;
bool gameOver{false};
bool player1Turn{true};
std::array<char,9>grid{' ',' ',' ',' ',' ',' ',' ',' ',' '};
Display_grid(grid);
do{
if(player1Turn){
std::cout<<"Player1's turn: ";
std::cin>>nextMove;
}
else{
std::cout<<"Player2's turn: ";
std::cin>>nextMove;
}
std::cout<<std::endl;
while(nextMove<1 or nextMove>9 or grid[nextMove-1]=='X' or grid[nextMove-1]=='O'){
std::cout<<"Invalid entry"<<std::endl;
std::cin>>nextMove;
}
grid[nextMove-1] = (player1Turn) ? 'X' : 'O';
player1Turn = !player1Turn;
movesCount++;
Display_grid(grid);
if(Someone_won(grid)){
std::cout<<"player "<<((grid[nextMove-1]=='X')? "1":"2")<<" wins!"<<std::endl;
gameOver=true;
}else if (movesCount==9){
std::cout<<"Draw!"<<std::endl;
gameOver=true;
}
}while(!gameOver);
std::cout<<"Restart?(0/1)";
std::cin>>restart;
}while (restart);
}
J'ai fait en sorte d'avoir une grille vide (sans les indices des cases), je trouve simplement ça plus lisible lors d'une partie.
Pour cela, j'ai du rajouter une condition dans chaque cas d'égalité (pour que l'égalité entre caractères "espace" ne soit pas prise en compte.Voyant que cela devenait beaucoup trop touffu, j'ai crée une nouvelle fonction pour gérer l'égalité:
bool Are_equal(char a, char b, char c)
Je suis assez satisfait de ce que j'ai pu produire pour cet exercice, dans la mesure ou les principales erreurs relevées (par @GuitOXx, merci beaucoup d'ailleurs ) relèvent de notions que je ne connaissais tout simplement pas jusqu'à lors (faut dire que je prends vraiment vraiment mon temps pour lire ce cours :P)
En programmation, il existe une règle fondamentale qui est le principe de responsabilité unique connu sous le sigle SRP (Single Responsability Principle, en anglais). Ce principe consiste à dire qu'on ne doit donner qu'une seule tâche à une fonction (en POO, il est même étendu aux objets...). En très gros, s'il te faut plus d'une phrase simple (sujet+verbe+complément) pour dire ce que fait ta fonction, c'est très probablement qu'elle viole SRP. Ce principe est archi-connu, c'est le fameux "Diviser pour régner" ou sa version moins belliciste "Je ne sais faire qu'une seule chose, mais je la fais bien", l'idée est de découper un problème complexe (donc difficile, que je ne sais pas résoudre) en une combinaison de problèmes plus simples (que je sais résoudre).
Bien entendu, main étant une fonction, SRP doit s'appliquer
× 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.
...
...
Edit: moi j'y comprends plus rien avec le code , là semble le formater...à moitié?
...