Désolé de la remonté du topic mais je veux comme-même posté ma création pour vos remarques-bugs-suggestions, je suis vraiment un débutant donc soyez indulgents pls..
J'ai essayé de faire l'IA mais je ne sais pas du tout comment faire, une aide ?
Mon code :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void AfficherTableau(char carre[]);
void PrenomDemander(char PrenomJ1[], char PrenomJ2[]);
int ChoixJ(char PrenomJ[]);
int Testerc(char carre[]);
int Testercases(int c[]);
int MenuChoix(int choix);
void regleDuJeu();
int main()
{
int recommencer = 0;
int gagne = 0;
int rejouer = 0;
int choixDebut = 0;
const int MIN = 1, MAX= 2;
srand(time(NULL));
int joueurCommence = (rand() % (MAX - MIN + 1)) + MIN;
int coupsJouer;
int cases[9] = {0};
int choixCase;
char PrenomJ1[30], PrenomJ2[30];
char carre[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
printf(" _______________________ \n");
printf("| |\n");
printf("| Morpion v0.1 by Keriz |\n");
printf("|_______________________|\n\n");
choixDebut = MenuChoix(choixDebut);
switch (choixDebut)
{
case 1:
do
{
char carre[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
gagne = 0;
PrenomDemander(PrenomJ1, PrenomJ2);
printf("\n%s, tu joue avec les 'O' et %s tu joue avec les 'X' ! \n\n", PrenomJ1, PrenomJ2);
AfficherTableau(carre);
if(joueurCommence == 1)
printf("\n%s, tu commence !", PrenomJ1);
else if(joueurCommence == 2)
printf("\n%s, tu commence !", PrenomJ2);
while (gagne != 1)
{
do
{
rejouer = 0;
if(joueurCommence == 1)
{
choixCase = ChoixJ(PrenomJ1);
}
else if(joueurCommence == 2)
{
choixCase = ChoixJ(PrenomJ2);
}
if (cases[choixCase] == 1)
{
printf("Desole, c'est deja jouer !\n\n");
rejouer = 1;
}
if (cases[1] == 0)
carre[1] = '1';
if (cases[2] == 0)
carre[2] = '2';
if (cases[3] == 0)
carre[3] = '3';
if (cases[4] == 0)
carre[4] = '4';
if (cases[5] == 0)
carre[5] = '5';
if (cases[6] == 0)
carre[6] = '6';
if (cases[7] == 0)
carre[7] = '7';
if (cases[8] == 0)
carre[8] = '8';
if (cases[9] == 0)
carre[9] = '9';
if (joueurCommence == 1)
{
printf("\nCoup joue ! Le 'O' a ete place.\n\n");
carre[choixCase] = 'O';
cases[choixCase] = 1;
joueurCommence = 2;
}
else
{
printf("\nCoup joue ! Le 'X' a ete place.\n\n");
carre[choixCase] = 'X';
cases[choixCase] = 1;
joueurCommence = 1;
}
AfficherTableau(carre);
if(Testerc(carre))
{
printf("\n\nTu as gagne !");
gagne = 1;
}
else
{
gagne = Testercases(cases);
}
}
while(rejouer == 1);
}
recommencer = 0;
printf("\n\n\n\nQue voulez-vous faire ?\n1.Refaire une partie\n2.Quitter le jeu\n\nVotre choix ? ");
scanf("%d", &recommencer);
}
while(recommencer != 2);
break;
case 2:
regleDuJeu();
break;
case 3:
break;
}
return 0;
}
void AfficherTableau(char carre[])
{
printf(" ____ ____ ____\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", carre[1], carre[2], carre[3]);
printf("|____|____|____|\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", carre[4], carre[5], carre[6]);
printf("|____|____|____|\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", carre[7], carre[8], carre[9]);
printf("|____|____|____|\n");
}
void PrenomDemander(char PrenomJ1[30], char PrenomJ2[30])
{
printf("\n\nQuel est ton prenom, joueur 1 ? ");
scanf("%s", PrenomJ1);
printf("\n\nQuel est ton prenom, joueur 2 ? ");
scanf("%s", PrenomJ2);
}
int ChoixJ (char PrenomJ[])
{
int choixCase = 0;
do
{
printf("\nA toi, %s ! Ou veux tu jouer ?\n\n", PrenomJ);
scanf("%d", &choixCase);
}
while(choixCase < 1 || choixCase > 10);
return choixCase;
}
int Testerc (char carre[])
{
int boolean = 0;
if( ((carre[1] == carre[2]) && (carre[2] == carre[3])) ||
((carre[4] == carre[5]) && (carre[4] == carre[6])) ||
((carre[7] == carre[8]) && (carre[8] == carre[9])) ||
((carre[1] == carre[4]) && (carre[4] == carre[7])) ||
((carre[2] == carre[5]) && (carre[5] == carre[7])) ||
((carre[3] == carre[6]) && (carre[6] == carre[9])) ||
((carre[1] == carre[5]) && (carre[5] == carre[9])) ||
((carre[3] == carre[5]) && (carre[5] == carre[7]))
)
{
boolean = 1;
}
return boolean;
}
int Testercases (int c[])
{
int gagne = 0;
if( ((c[1] == c[2]) && (c[2] == c[3])) &&
((c[4] == c[5]) && (c[5] == c[6])) &&
((c[7] == c[8]) && (c[8] == c[9]))
)
{
printf("\n\nMatch nul...\n\n");
gagne = 1;
}
return gagne;
}
int MenuChoix (int choixDebut)
{
printf("\n\nChoissisez votre action :\n\n1.Jouer\n2.Regles du jeu\n3.Quitter\n\nChoix : ");
scanf("%d", &choixDebut);
return choixDebut;
}
void regleDuJeu ()
{
printf("\n\nBut du jeu :\n\n\nAligner 3 'O' ou 'X' a la suite, verticalement, horizontalement ou en diagonale.\n\n");
printf("Ce jeu ne se joue qu'a deux joueurs, une fonctionnalite solo va etre ajoutee.\n\n");
printf("Chaque joueur joue l'un apres l'autre et le joueur qui commence est tire au sort, possibilite de faire plusieurs parties.\n\n");
}
| | | |
| O | O | X |
|____|____|____|
| | | |
| X | X | O |
|____|____|____|
| | | |
| O | O | X |
|____|____|____|
A toi, @che ! Ou veux tu jouer ?
Euh là ou il y a de la place ...
Sinon :
Coup joue ! Le 'X' a ete place.
____ ____ ____
| | | |
| O | X | O |
|____|____|____|
| | | |
| 4 | X | O |
|____|____|____|
| | | |
| 7 | X | 9 |
|____|____|____|
A toi, @che ! Ou veux tu jouer ?
J'aurais pas gagner là ?
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles- ♡ Copying is an act of love.
qnope >
Les cast dans create_Grid sont inutiles
Pourquoi utiliser un tableau dynamique ?
Pourquoi utiliser une boucle infinie ?
Pour ta fonction my_scanf, tu pourrais tout simplement retourner la valeur plutôt que prendre un pointeur. De plus, tu ne récupères qu'un seul nombre, donc le nom 'scanf' n'est pas très approprié.
x = numCase % grid->width;
y = numCase / grid->width;
/* Si tu regardes bien, tu as des tests inutiles */
if(x < 0 || x >= grid->width || y < 0 || y >= grid->height)
return false;
En fait, comme tu utilises un tableau 1D tu peux tout simplement écrire ta fonction en 3-4 lignes.
A quoi ça sert de calculer x et y ?
x = numCase % grid->width;
y = numCase / grid->width;
grid->grid[y * grid->width + x] = player;
On dit 'Le joueur à gagné'.
Tu peux simplement remplacer ta fonction end_Play par un compteur de pions.
A quoi te sert ta variable yBase ? /main.c:126:3 Value stored to 'yBase' is never read
sydzero >
Tu pourrais créer une fonction 'rejouer'
Pour initialiser ta grille, on préfèrera en général la notation 'i < 9' plutôt que 'i <= 8', c'est plus parlant dans la majorité des cas
Tu pourrais tirer le joueur qui commence aléatoirement
Quand tu appelles pour la première fois ta fonction 'testerCoup', coord vaut 0, donc arrivé dans ta fonction tu tentes d'accéder à l'indice -1 de ton tableau. Utilise une boucle 'do...while' pour régler ce problème
Tu pourrais largement simplifier ta fonction 'gagner' avec des (cond1 && cond2 && cond3) || (cond4 && etc.)
Tu pourrais retourner la valeur plutôt que de passer par un pointeur
Tu pourrais faire ton affichage de la personne qui a gagné dans une autre fonction
Il faudrait que tu vides ton buffer juste après chaque scanf, sinon tu risques de te retrouver à devoir taper 'entrée' avant de faire ta 'vraie' saisie
crushing >
Tu n'utilises pas les paramètres argc et argv du main, tu peux mettre 'void' à la place.
Tu peux rendre ton code plus portable simplement avec le préprocesseur
Pareil pour le 'system', un petit #if et tu l'enlèves si on est pas sous win
Le nom de ta fonction 'actualiser' est mal choisi
Pour ta fonction initTable, une boucle aurait été plus appropriée
Pourquoi utiliser une boucle infinie ?
Dans ta condition pour savoir si on joue à 1 ou 2 joueurs, tu pourrais utiliser toupper ou tolower pour éviter des tests
Tu pourrais simplifier tes 2 if de saisie en 1 seul
Mettre inttableau[9] dans tes prototypes n'a que peu d'intérêt, le 9 est ignoré purement et simplement par le compilateur. Tu peux mettre des chevrons sans rien dedans ou une étoile pour le pointeur : int*tableau
Tu pourrais éviter le 'continue' en faisant simplement une boucle sur la saisie. Tu pourrais aussi simplement créer une fonction pour la saisie et boucler tant que la saisie est incorrecte
Tu pourrais supprimer ta fonction matchNul simplement en vérifiant ta variable 'coups'.
Pour ta fonction IA, poste ton code ici : http://www.siteduzero.com/forum-83-597 [...] e-partie.html
Keriz >
Tu déclares plusieurs fois ta variable 'carre'
Tu n'utilises pas ta variable coupsJouer
On préfèrera déclarer les variables avant les appels de fonctions (srand).
On préfèrera utiliser un enum ou un #define pour les variables constantes (MIN, MAX)
Ce serait bien de pouvoir jouer après avoir affiché les règles du jeu.
Tu pourrais utiliser un tableau pour les prénoms
Tu pourrais faire plus de fonctions : rejouer, saisie, testerCoup, jouerCoup, etc.
Tu pourrais utiliser une boucle pour tes if case[1] == 0 etc.
Tu pourrais n'utiliser qu'un seul tableau
Tu pourrais utiliser une boucle pour ta fonction testerCases
(j'ai été indulgent, j'aurais pu en mettre le double )
Je te conseille d'améliorer ton morpion avant de passer à l'IA.
A Pouet, Pourquoi utiliser un tableau dynamique, tout simplement au cas ou si on demande a l'utilisateur de rentrer ses propres données
J'utilise une boucle infinie car je trouve ceci plus simple a gérer ce cas là(mauvaise raison surment mais bon) bien qu'il est possible de faire autrement ^^.
Ensuite pour le calcul des x et y, j'avou que, c'est vraiment pas mal comme idée que tu as eu ^^.
Pour les casts, c'est juste pour éviter le warning
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
typedef unsigned char bool;
enum{false, true};
enum{J1 = -1, J2 = -2};
typedef struct
{
int *grid;
int width, height, align;
}Grid;
void *my_malloc(size_t n);/*Malloc verificate*/
void my_saisie(int *place, char const *print);
Grid *create_Grid(unsigned width, unsigned height, unsigned align);
void delete_Grid(Grid *(*grid));
void print_Grid(Grid *grid);
void play(Grid *grid);
bool test_Case(Grid *grid, int numCase);
bool win(Grid *grid, int numCase, int player);
bool end_Play(Grid *grid);
void my_saisie(int *place, char const *print)
{
int c;
do
{
printf("%s", print);
c = scanf("%d", place);
while(getchar() != '\n');
}while (c != 1);
}
void *my_malloc(size_t n)
{
void *p;
if((p = malloc(n)) == NULL)
fprintf(stderr, "Erreur sur le malloc"), exit(1);
return p;
}
Grid *create_Grid(unsigned width, unsigned height, unsigned align)
{
unsigned x, y;
int n = 0;
Grid *grid = my_malloc(sizeof *grid);
grid->grid = my_malloc(sizeof *(grid->grid) * width * height);
grid->width = (int) width;
grid->height = (int) height;
grid->align = (int) align;
for(y = 0; y < height; y++)
for(x = 0; x < width; x++)
grid->grid[y * width + x] = ++n;
return grid;
}
void delete_Grid(Grid *(*grid))
{
free((*grid)->grid);
free(*grid);
*grid = NULL;
}
void print_Grid(Grid *grid)
{
int x, y;
for(y = 0; y < grid->height; y++)
{
for(x = 0; x < grid->width; x++)
printf("___");
putchar('\n');
for(x = 0; x < grid->width; x++)
{
if(grid->grid[y * grid->width + x] > 0)
printf("%2d|", grid->grid[y * grid->width + x]);
else
printf("%2c|", (grid->grid[y * grid->width + x] == J1)
? 'X' : 'O');
}
putchar('\n');
}
}
bool win(Grid *grid, int numCase, int player)
{
int xMin, xMax, yMin, yMax, x, y, xBase,
n = 0;
x = numCase % grid->width;
y = numCase / grid->width;
xMin = (x - grid->align + 1);
xMax = (x + grid->align);
yMin = (y - grid->align + 1);
yMax = (y + grid->align);
if(xMin < 0)
xMin = 0;
if(yMin < 0)
yMin = 0;
if(xMax >= grid->width)
xMax = grid->width;
if(yMax >= grid->height)
yMax = grid->height;
xBase = x;
for(x = xMin; x < xMax; x++)
{
if(grid->grid[y * grid->width + x] == player)
n++;
else
n = 0;
if(n == grid->align)
return true;
}/*Line*/
x = xBase;
n = 0;
for(y = yMin; y < yMax; y++)
{
if(grid->grid[y * grid->width + x] == player)
n++;
else
n = 0;
if(n == grid->align)
return true;
}/*Col*/
x = xMin;
n = 0;
for(y = yMin; y < yMax; y++)
{
if(grid->grid[y * grid->width + x] == player)
n++;
else
n = 0;
if(n == grid->align)
return true;
x++;
if(x >= grid->width)
x = xMax - 1;
}/*left right*/
x = xMax - 1;
n = 0;
for(y = yMin; y < yMax; y++)
{
if(grid->grid[y * grid->width + x] == player)
n++;
else
n = 0;
if(n == grid->align)
return true;
x--;
if(x < 0)
x = xMin;
}/*right left*/
return false;/*Else not win, return 0;*/
}
void play(Grid *grid)
{
int numCase;
int player = J1;
while(1)
{
print_Grid(grid);
printf("\nA vous de jouez joueur %d\n", -player);
do
{
my_saisie(&numCase, "Entrez le numero de case :\n");
}while(test_Case(grid, numCase) == false);
grid->grid[--numCase] = player;
if(win(grid, numCase, player) == true)
{
print_Grid(grid);
printf("\nLe joueur %d a gagner\n", -player);
break;
}
if(end_Play(grid) == true)
{
print_Grid(grid);
printf("\nIl y a match nul\n");
break;
}
if(player == J1)
player = J2;
else
player = J1;
}
}
bool test_Case(Grid *grid, int numCase)
{
numCase--;
if(numCase < 0 || numCase >= grid->width * grid->height)
return false;
return (grid->grid[numCase] > 0);
}
bool end_Play(Grid *grid)
{
bool end = true;
int x, y;
for(y = 0; y < grid->height; y++)
{
for(x = 0; x < grid->width; x++)
{
if(grid->grid[y * grid->width + x] > 0)
{
end = false;
return end;
}
}
}
return end;
}
int main(void)
{
Grid *grid = create_Grid(3, 3, 3);
play(grid);
delete_Grid(&grid);
return 0;
}
Edit : excusez moi
http://cpp-rendering.io : Vous trouverez tout ce dont vous avez besoin sur Vulkan / OpenGL et le rendu 3D !
bonjour à tous :
bon voici mon code apres quelques heures de galères, puisque je me suis pris un mal au crâne avec ma fonction
testGagnant qui ne fonctionne qu'avec une grille 3X3. J'ai pas encore reussi a ce jour a faire un truc "un peu plus generique" pour une grille nXn
#include <stdio.h>
#include <stdlib.h>
#define maxMatrice 3 //pour l'instant figer à 3 probleme dans la fonction testGagnant
typedef enum player player;
enum player
{
joueur0, joueur1, joueur2
// ordi , joueur1, joueur2
};
void viderBuffer(void)
{
int c=0;
while (c !='\n' && c!=EOF)
{
c=getchar();
}
}
int lireInt (void)
//fonction sécurisé pour lire un entier
{
int x;
int erreur=0;
while (erreur==0)
{
erreur=scanf("%d",&x);
if (erreur==0)
{
printf("Vous trompez pas saisissez un nombre ! RECOMMENCEZ\n");
}
viderBuffer();// ici vider buffer
}
return x;
}
void affichage(int matrice[maxMatrice][maxMatrice])
{
//affichage : Affiche le plateau de jeu
int i,j;
int motif[3];
motif[0]= 32;
motif[1]= 6;
motif[2]= 15;
//affichage cadre premiere ligne
printf("%c",201);
for (i=0; i<maxMatrice-1; i++)
{
printf("%c%c",205,203);
}
printf("%c%c\n",205,187);
//affichage des autres lignes
for (i=0; i<maxMatrice; i++)
{
for (j=0; j<maxMatrice; j++)
{
//ici affichage des objets
printf("%c%c",186,motif[matrice[i][j]]);
}
printf("%c\n",186);
if (i<maxMatrice-1)
{
printf("%c",204);
for (j=0; j<maxMatrice-1; j++)
{
printf("%c%c",205,206);
}
printf("%c%c\n",205,185);
}
}
//affichage cadre derniere ligne
printf("%c",200);
for (i=0; i<maxMatrice-1; i++)
{
printf("%c%c",205,202);
}
printf("%c%c\n",205,188);
}
void remplirMatriceAzero(int matrice[maxMatrice][maxMatrice])
{
int i,j;
for (i=0; i<maxMatrice; i++)
{
for (j=0; j<maxMatrice; j++)
{
matrice[i][j]=0;
}
}
}
void saisie(int joueur,int *x,int *y,int tableau[maxMatrice][maxMatrice])
{
int recommencer=1;
int test;
while (recommencer)
{
test=1;
printf("\n Joueur %d c'est a vous: \n",joueur);
while (test)
{
printf("Ligne? 0 a %d:",maxMatrice-1);
*x=lireInt();
if ((*x>=0) &&(*x<maxMatrice))
{
test=0;
}
}
test=1;
while (test)
{
printf("\nColonne? 0 a %d :",maxMatrice-1);
*y=lireInt();
if ((*y>=0) &&(*y<maxMatrice))
{
test=0;
}
}
if (tableau[*x][*y]==0)
{
tableau[*x][*y]=joueur;
recommencer=0;
}
else
{
printf("\n\nRecommencer la case est prise \n\n");
}
}
}
int testGagnant(int m[maxMatrice][maxMatrice])
{
/*
testerGagnant : Regarde si il y a un gagnant
*/
//test des trois lignes
if (m[0][0]!=0)
{
if((m[0][0]=m[0][1]) && (m[0][0]=m[0][2]))
{
return 1;
}
}
if (m[1][0]!=0)
{
if((m[1][0]=m[1][1]) && (m[1][0]=m[1][2]))
{
return 1;
}
}
if (m[2][0]!=0)
{
if((m[2][0]=m[2][1]) && (m[2][0]=m[2][2]))
{
return 1;
}
}
//test des trois colonnes
if (m[0][0]!=0)
{
if((m[0][0]=m[1][0]) && (m[0][0]=m[2][0]))
{
return 1;
}
}
if (m[0][1]!=0)
{
if((m[0][1]=m[1][1]) && (m[0][1]=m[2][1]))
{
return 1;
}
}
if (m[0][2]!=0)
{
if((m[0][2]=m[1][2]) && (m[0][2]=m[2][2]))
{
return 1;
}
}
//test des diagonales
if (m[0][0]!=0)
{
if((m[0][0]=m[1][1]) && (m[0][0]=m[2][2]))
{
return 1;
}
}
if (m[0][2]!=0)
{
if((m[0][2]=m[1][1]) && (m[0][2]=m[2][0]))
{
return 1;
}
}
return 0;
}
void jouer(int m[maxMatrice][maxMatrice])
{
//jouer : Contient la boucle principale du jeu
int coup=0;
int continuer=1;
int x,y;
int joueur=1;
remplirMatriceAzero(m);//initialisation de la matrice
affichage(m);
//qui commence
while (continuer)
{
//entrer coordonnees
saisie(joueur,&x,&y,m);
//test si gagné,afficher le gagnant,continuer=0
if (testGagnant(m) )
{
printf("\n\n joueur %d est gagnant \n\n",joueur);
continuer=0;//fin de la partie
}
else printf("test=%d \n",testGagnant(m));//pour controle
//affichage grille apres saisie
affichage(m);
if (joueur==joueur1)//on change de joueur
{
joueur=joueur2;
}
else
{
joueur=joueur1;
}
coup++;
if (coup == maxMatrice*maxMatrice)
{
printf("\n\n MATCH NUL \n\n");
continuer=0;//fin de partie
}
}
}
int main (void)
{
int continuer=1;
int grille[maxMatrice][maxMatrice];
while (continuer==1)
{
jouer(grille);
printf("\n\n Une autre partie 1=oui 0=non ? :");
continuer=lireInt();
printf("\n");
}
return 0;
}
tu as raison une petite tapes derriere l'oreille, pour me remettre dans les rails
merci
donc code rectifié :
#include <stdio.h>
#include <stdlib.h>
#define maxMatrice 3 //pour l'instant figer à 3 probleme dans la fonction testGagnant
typedef enum player player;
enum player
{
joueur0, joueur1, joueur2
// ordi , joueur1, joueur2
};
void viderBuffer(void)
{
int c=0;
while (c !='\n' && c!=EOF)
{
c=getchar();
}
}
int lireInt (void)
//fonction sécurisé pour lire un entier
{
int x;
int erreur=0;
while (erreur==0)
{
erreur=scanf("%d",&x);
if (erreur==0)
{
printf("Vous trompez pas saisissez un nombre ! RECOMMENCEZ\n");
}
viderBuffer();// ici vider buffer
}
return x;
}
void affichage(int matrice[maxMatrice][maxMatrice])
{
//affichage : Affiche le plateau de jeu
int i,j;
int motif[3];
motif[0]= 32;
motif[1]= 6;
motif[2]= 15;
//affichage cadre premiere ligne
printf("%c",201);
for (i=0; i<maxMatrice-1; i++)
{
printf("%c%c",205,203);
}
printf("%c%c\n",205,187);
//affichage des autres lignes
for (i=0; i<maxMatrice; i++)
{
for (j=0; j<maxMatrice; j++)
{
//ici affichage des objets
printf("%c%c",186,motif[matrice[i][j]]);
}
printf("%c\n",186);
if (i<maxMatrice-1)
{
printf("%c",204);
for (j=0; j<maxMatrice-1; j++)
{
printf("%c%c",205,206);
}
printf("%c%c\n",205,185);
}
}
//affichage cadre derniere ligne
printf("%c",200);
for (i=0; i<maxMatrice-1; i++)
{
printf("%c%c",205,202);
}
printf("%c%c\n",205,188);
}
void remplirMatriceAzero(int matrice[maxMatrice][maxMatrice])
{
int i,j;
for (i=0; i<maxMatrice; i++)
{
for (j=0; j<maxMatrice; j++)
{
matrice[i][j]=0;
}
}
}
void saisie(int joueur,int *x,int *y,int tableau[maxMatrice][maxMatrice])
{
int recommencer=1;
int test;
while (recommencer)
{
test=1;
printf("\n Joueur %d c'est a vous: \n",joueur);
while (test)
{
printf("Ligne? 0 a %d:",maxMatrice-1);
*x=lireInt();
if ((*x>=0) &&(*x<maxMatrice))
{
test=0;
}
}
test=1;
while (test)
{
printf("\nColonne? 0 a %d :",maxMatrice-1);
*y=lireInt();
if ((*y>=0) &&(*y<maxMatrice))
{
test=0;
}
}
if (tableau[*x][*y]==0)
{
tableau[*x][*y]=joueur;
recommencer=0;
}
else
{
printf("\n\nRecommencer la case est prise \n\n");
}
}
}
int testGagnant(int m[maxMatrice][maxMatrice])
{
/*
testerGagnant : Regarde si il y a un gagnant
*/
//test des trois lignes
if (m[0][0]!=0)
{
if((m[0][0]==m[0][1]) && (m[0][0]==m[0][2]))
{
return 1;
}
}
if (m[1][0]!=0)
{
if((m[1][0]==m[1][1]) && (m[1][0]==m[1][2]))
{
return 1;
}
}
if (m[2][0]!=0)
{
if((m[2][0]==m[2][1]) && (m[2][0]==m[2][2]))
{
return 1;
}
}
//test des trois colonnes
if (m[0][0]!=0)
{
if((m[0][0]==m[1][0]) && (m[0][0]==m[2][0]))
{
return 1;
}
}
if (m[0][1]!=0)
{
if((m[0][1]==m[1][1]) && (m[0][1]==m[2][1]))
{
return 1;
}
}
if (m[0][2]!=0)
{
if((m[0][2]==m[1][2]) && (m[0][2]==m[2][2]))
{
return 1;
}
}
//test des diagonales
if (m[0][0]!=0)
{
if((m[0][0]==m[1][1]) && (m[0][0]==m[2][2]))
{
return 1;
}
}
if (m[0][2]!=0)
{
if((m[0][2]==m[1][1]) && (m[0][2]==m[2][0]))
{
return 1;
}
}
return 0;
}
void jouer(int m[maxMatrice][maxMatrice])
{
//jouer : Contient la boucle principale du jeu
int coup=0;
int continuer=1;
int x,y;
int joueur=1;
remplirMatriceAzero(m);//initialisation de la matrice
affichage(m);
//qui commence
while (continuer)
{
//entrer coordonnees
saisie(joueur,&x,&y,m);
//test si gagné,afficher le gagnant,continuer=0
if (testGagnant(m) )
{
printf("\n\n joueur %d est gagnant \n\n",joueur);
continuer=0;//fin de la partie
}
else printf("test=%d \n",testGagnant(m));//pour controle
//affichage grille apres saisie
affichage(m);
if (joueur==joueur1)//on change de joueur
{
joueur=joueur2;
}
else
{
joueur=joueur1;
}
coup++;
if (coup == maxMatrice*maxMatrice)
{
printf("\n\n MATCH NUL \n\n");
continuer=0;//fin de partie
}
}
}
int main (void)
{
int continuer=1;
int grille[maxMatrice][maxMatrice];
while (continuer==1)
{
jouer(grille);
printf("\n\n Une autre partie 1=oui 0=non ? :");
continuer=lireInt();
printf("\n");
}
return 0;
}
Salut, j'ai enfin trouvé du temps pour programmer un peu. J'ai commencé les changements, mais je bug à la compilation et je pense que c'est à cause de mes tableaux, que je ne sais pas très bien envoyé aux fonction... Pour info il me dit que j'ai un problème à la fonction affichertableaux ( donc celle avec un tableau à deux dimensions.
Mon code :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void AfficherTableau(char carre[]);
void PrenomDemander(char PrenomJ1, char PrenomJ2);
int ChoixJ(char PrenomJ);
int Testerc(char carre);
int Testercases(int c);
int MenuChoix(int choix);
void regleDuJeu();
int main()
{
int recommencer = 0;
int gagne = 0;
int rejouer = 0;
srand(time(NULL));
int MAX = 2, MIN = 1;
int joueurCommence = (rand() % (MAX - MIN + 1)) + MIN;
int choixDebut = 0;
int choixCase;
int i, k;
char PrenomJ[2][30];
char carre[2][11] = { {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, {0} };
printf(" _______________________ \n");
printf("| |\n");
printf("| Morpion v0.1 by Keriz |\n");
printf("|_______________________|\n\n");
choixDebut = MenuChoix(choixDebut);
switch (choixDebut)
{
case 2:
regleDuJeu();
case 1:
do
{
for (i = 1; i <= 9; i++)
{
carre[1][i] = 0;
}
gagne = 0;
PrenomDemander(PrenomJ[0], PrenomJ[1]);
printf("\n%s, tu joue avec les 'O' et %s tu joue avec les 'X' ! \n\n", PrenomJ[0], PrenomJ[1]);
AfficherTableau(carre);
if(joueurCommence == 1)
printf("\n%s, tu commences !", PrenomJ[0]);
else if(joueurCommence == 2)
printf("\n%s, tu commences !", PrenomJ[1]);
while (gagne != 1)
{
do
{
rejouer = 0;
if(joueurCommence == 1)
{
choixCase = ChoixJ(PrenomJ[0]);
}
else if(joueurCommence == 2)
{
choixCase = ChoixJ(PrenomJ[1]);
}
for (i = 0; i <= 9; i++)
{
if (carre[0][i] == 0)
carre[0][i] = i + 1;
}
if (carre[1][choixCase] == 1)
{
printf("\nDesole, c'est deja joue !\n\n");
rejouer = 1;
}
else if (joueurCommence == 1)
{
printf("\nCoup joue ! Le 'O' a ete place.\n\n");
carre[0][choixCase] = 'O';
carre[1][choixCase] = 1;
joueurCommence = 2;
}
else
{
printf("\nCoup joue ! Le 'X' a ete place.\n\n");
carre[0][choixCase] = 'X';
carre[1][choixCase] = 1;
joueurCommence = 1;
}
AfficherTableau(carre);
if(Testerc(carre))
{
printf("\n\nTu as gagne !");
gagne = 1;
}
else
{
gagne = Testercases(carre);
}
}
while(rejouer == 1);
}
recommencer = 0;
printf("\n\n\n\nQue voulez-vous faire ?\n1.Refaire une partie\n2.Quitter le jeu\n\nVotre choix ? ");
scanf("%d", &recommencer);
}
while(recommencer != 2);
break;
case 3:
break;
}
return 0;
}
void AfficherTableau(char carre[])
{
printf(" ____ ____ ____\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", carre[0][1], carre[0][2], carre[0][3]);
printf("|____|____|____|\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", carre[0][4], carre[0][5], carre[0][6]);
printf("|____|____|____|\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", carre[0][7], carre[0][8], carre[0][9]);
printf("|____|____|____|\n");
}
void PrenomDemander(char PrenomJ1, char PrenomJ2);
{
printf("\n\nQuel est ton prenom, joueur 1 ? ");
scanf("%s", PrenomJ1[]);
printf("\n\nQuel est ton prenom, joueur 2 ? ");
scanf("%s", PrenomJ2[]);
}
int ChoixJ (char PrenomJ)
{
int choixCase = 0;
do
{
printf("\nA toi, %s ! Ou veux tu jouer ?\n\n", PrenomJ);
scanf("%d", &choixCase);
}
while(choixCase < 1 || choixCase > 10);
return choixCase;
}
int Testerc (char carre)
{
int boolean = 0;
if( ((carre[0][1] == carre[0][2]) && (carre[0][2] == carre[0][3])) ||
((carre[0][4] == carre[0][5]) && (carre[0][4] == carre[0][6])) ||
((carre[0][7] == carre[0][8]) && (carre[0][8] == carre[0][9])) ||
((carre[0][1] == carre[0][4]) && (carre[0][4] == carre[0][7])) ||
((carre[0][2] == carre[0][5]) && (carre[0][5] == carre[0][7])) ||
((carre[0][3] == carre[0][6]) && (carre[0][6] == carre[0][9])) ||
((carre[0][1] == carre[0][5]) && (carre[0][5] == carre[0][9])) ||
((carre[0][3] == carre[0][5]) && (carre[0][5] == carre[0][7]))
)
{
boolean = 1;
}
return boolean;
}
int Testercases (int c)
{
int gagne = 0;
if( ((c[1][1] == c[1][2]) && (c[1][2] == c[1][3])) &&
((c[1][4] == c[1][5]) && (c[1][5] == c[1][6])) &&
((c[1][7] == c[1][8]) && (c[1][8] == c[1][9]))
)
{
printf("\n\nMatch nul...\n\n");
gagne = 1;
}
return gagne;
}
int MenuChoix (int choixDebut)
{
printf("\n\nChoissisez votre action :\n\n1.Jouer\n2.Regles du jeu\n3.Quitter\n\nChoix : ");
scanf("%d", &choixDebut);
return choixDebut;
}
void regleDuJeu ()
{
printf("\n\nBut du jeu :\n\n\nAligner 3 'O' ou 'X' a la suite, verticalement, horizontalement ou en diagonale.\n\n");
printf("Ce jeu ne se joue qu'a deux joueurs, une fonctionnalite solo va etre ajoutee.\n\n");
printf("Chaque joueur joue l'un apres l'autre et le joueur qui commence est tire au sort, possibilite de faire plusieurs parties.\n\n");
}
J'ai apporté quelques améliorations à mon programme à savoir :
-tirer au sort le premier joueur
-choix de la taille du morpion
-vérifie si le morpion est plein
-utilisation d'un tableau à 2 dimensions
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#define MAX 2
#define MIN 1
void affichage(char** tableau, int tailleTab);
int saisie(int joueur);
int testerCoup(int coord, char** tableau, int tailleTab); // Si le coup est bon, il renvoie 1
void jouerCoup(char** tableau, int coord, int joueur, int tailleTab);
void gagner(char** tableau, int* gagne, int joueur, int tailleTab); //teste si un joueur a gagné, mais aussi si le tabealu est plein.
int main(void)
{
srand(time(NULL));
char jouer = 'O';
while (jouer == 'O')
{
int tailleTab = 0;;
printf("Quelle taille doit faire le tableau ?\n");
scanf("%d", &tailleTab);
while (getchar() != '\n');
int coord = 0;
int i = 0;
int j = 0;
int gagne = 0;
char** tableau = NULL;
int joueur = 1; //1 : joueur 1, 2 : joueur 2
tableau = malloc(tailleTab * sizeof(char *));
for (i = 0; i < tailleTab; i++)
tableau[i] = malloc(tailleTab * sizeof(char));
//Initialisation
for (i = 0 ; i < tailleTab; i++)
{
for (j = 0; j < tailleTab; j++)
tableau[i][j] = '.';
}
//Tirage au sort
joueur = (rand() % (MAX - MIN + 1)) + MIN;
while (!gagne)
{
//Affichage du tableau
affichage (tableau, tailleTab);
//Saisie des coordonnées et tester si le coup est permis
do
coord = saisie(joueur);
while(testerCoup(coord, tableau, tailleTab) == 0);
//On inscrit le coup dans le tableau
jouerCoup(tableau, coord, joueur, tailleTab);
//On change de joueur
if (joueur == 1)
joueur++;
else if (joueur == 2)
joueur--;
//Un joueur a gagné ?
gagner(tableau, &gagne, joueur, tailleTab);
}
printf("\n\nRejouer ? (O/N)\n");
scanf("%c", &jouer);
while (getchar() != '\n');
jouer = toupper(jouer);
}
return 0;
}
void affichage(char** tableau, int tailleTab)
{
int i = 0;
int j = 0;
int k = 0;
printf(" ");
for (k = 0; k < tailleTab; k++)
{
printf("_ ");
}
printf("\n");
for (i = 0; i < tailleTab; i++)
{
for (j = 0; j < tailleTab; j++)
{
printf("|%c", tableau[i][j]);
}
printf("|\n");
printf(" ");
for (k = 0; k < tailleTab; k++)
{
printf("- ");
}
printf(" \n");
}
}
int saisie(int joueur)
{
int coord2 = 0;
printf("\n\nJoueur n° %d : ", joueur);
scanf("%d", &coord2);
while (getchar() != '\n');
return coord2;
}
void gagner(char** tableau, int* gagne, int joueur, int tailleTab)
{
int count_1 = 0;
int count_2 = 0;
int i = 0;
int j = 0;
int casesPl = 0;
//Tests sur l'abscisse
for (i = 0; i < tailleTab; i++)
{
for (j = 0; j < tailleTab; j++)
{
if (tableau[i][j] == 'X')
count_1++;
else if (tableau[i][j] == 'O')
count_2++;
if (count_1 == tailleTab || count_2 == tailleTab)
{
i = tailleTab;
j = tailleTab;
if (count_1 == tailleTab)
printf("Joueur 1, vous avez gagné !!");
else if (count_2 == tailleTab)
printf("Joueur 2, vous avez gagné !!");
*gagne = 1;
}
}
count_1 = 0;
count_2 = 0;
}
count_1 = 0;
count_2 = 0;
//Tests sur l'ordonnée
for (j = 0; j < tailleTab; j++)
{
for (i = 0; i < tailleTab; i++)
{
if (tableau[i][j] == 'X')
count_1++;
else if (tableau[i][j] == 'O')
count_2++;
if (count_1 == tailleTab || count_2 == tailleTab)
{
if (count_1 == tailleTab)
printf("Joueur 1, vous avez gagné !!");
else if (count_2 == tailleTab)
printf("Joueur 2, vous avez gagné !!");
*gagne = 1;
break;
}
}
if (count_1 == tailleTab || count_2 == tailleTab)
break;
count_2 = 0;
count_1 = 0;
}
count_1 = 0;
count_2 = 0;
//Tests sur les diagonales
for (i = 0; i < tailleTab; i++)
{
if (tableau[i][i] == 'X')
count_1++;
else if (tableau[i][i] == 'O')
count_2++;
if (count_1 == tailleTab || count_2 == tailleTab)
{
if (count_1 == tailleTab)
printf("Joueur 1, vous avez gagné !!");
else if (count_2 == tailleTab)
printf("Joueur 2, vous avez gagné !!");
*gagne = 1;
break;
}
}
count_2 = 0;
count_1 = 0;
for (i = 1; i < tailleTab; i++)
{
if (tableau[i-1][tailleTab-i] == 'X')
count_1++;
else if (tableau[i][tailleTab-i] == 'O')
count_2++;
if (count_1 == tailleTab || count_2 == tailleTab)
{
if (count_1 == tailleTab)
printf("Joueur 1, vous avez gagné !!");
else if (count_2 == tailleTab)
printf("Joueur 2, vous avez gagné !!");
*gagne = 1;
break;
}
}
count_2 = 0;
count_1 = 0;
//Teste si toutes les cases sont pleines
for (i = 0; i < tailleTab; i++)
{
for (j = 0; j < tailleTab; j++)
{
if (tableau[i][j] == 'X' || tableau[i][j] == 'O')
casesPl++;
}
}
if (casesPl == (tailleTab*tailleTab) && *gagne != 0)
{
*gagne = 1;
printf("Personne n'a gagné");
}
}
int testerCoup(int coord, char** tableau, int tailleTab)
{
int x = 0, y = 0;
x = coord%tailleTab;
y = coord/tailleTab;
if (tableau[y][x] == 'X' || tableau[y][x] == 'O')
return 0;
else
return 1;
}
void jouerCoup(char** tableau, int coord, int joueur, int tailleTab)
{
int x = 0, y = 0;
x = coord%tailleTab;
y = coord/tailleTab;
if (joueur == 1)
{
tableau[y][x] = 'X';
}
else if (joueur == 2)
{
tableau[y][x] = 'O';
}
}
bonjour,
voici ma version finalisée, a savoir la gestion d'une grille N*N avec m pion alignes m€[1..N].
J'ai pas mal galere avec la fonction "testerGagnant"....si quelqu'un peut m'indiquer une autre façon que la mienne
je l'en remercie d'avance
bon maintenent je passe à la deuxieme partie
#include <stdio.h>
#include <stdlib.h>
#define maxMatrice 6
#define maxPionAligne 3
#define oui 1
#define non 0
typedef enum player player;
enum player
{
joueur0, joueur1, joueur2
// ordi , joueur1, joueur2
};
void viderBuffer(void)
{
int c=0;
while (c !='\n' && c!=EOF)
{
c=getchar();
}
}
int lireInt (void)
//fonction sécurisé pour lire un entier
{
int x;
int erreur=0;
while (erreur==0)
{
erreur=scanf("%d",&x);
if (erreur==0)
{
printf("Vous trompez pas saisissez un nombre ! RECOMMENCEZ\n");
}
viderBuffer();// ici vider buffer
}
return x;
}
void affichage(int matrice[maxMatrice][maxMatrice])
{
//affichage : Affiche le plateau de jeu
int i,j;
int motif[3];
motif[0]= 32;
motif[1]= 6;
motif[2]= 15;
//affichage cadre premiere ligne
printf("%c",201);
for (i=0; i<maxMatrice-1; i++)
{
printf("%c%c",205,203);
}
printf("%c%c\n",205,187);
//affichage des autres lignes
for (i=0; i<maxMatrice; i++)
{
for (j=0; j<maxMatrice; j++)
{
//ici affichage des objets
printf("%c%c",186,motif[matrice[i][j]]);
}
printf("%c\n",186);
if (i<maxMatrice-1)
{
printf("%c",204);
for (j=0; j<maxMatrice-1; j++)
{
printf("%c%c",205,206);
}
printf("%c%c\n",205,185);
}
}
//affichage cadre derniere ligne
printf("%c",200);
for (i=0; i<maxMatrice-1; i++)
{
printf("%c%c",205,202);
}
printf("%c%c\n",205,188);
}
void remplirMatriceAzero(int matrice[maxMatrice][maxMatrice])
{
int i,j;
for (i=0; i<maxMatrice; i++)
{
for (j=0; j<maxMatrice; j++)
{
matrice[i][j]=0;
}
}
}
void saisie(int joueur,int *x,int *y,int tableau[maxMatrice][maxMatrice])
{
int recommencer=1;
int test;
while (recommencer)
{
test=1;
printf("\n Joueur %d c'est a vous: \n",joueur);
while (test)
{
printf("Ligne? 0 a %d:",maxMatrice-1);
*x=lireInt();
if ((*x>=0) &&(*x<maxMatrice))
{
test=0;
}
}
test=1;
while (test)
{
printf("\nColonne? 0 a %d :",maxMatrice-1);
*y=lireInt();
if ((*y>=0) &&(*y<maxMatrice))
{
test=0;
}
}
if (tableau[*x][*y]==0)
{
tableau[*x][*y]=joueur;
recommencer=0;
}
else
{
printf("\n\nRecommencer la case est prise \n\n");
}
}
}
int testerGagnant(int m[maxMatrice][maxMatrice])
{
int i,j,condition;
//test sur les lignes
for (i=0; i<maxMatrice; i++)
{
condition=1;
for (j=0; j<maxMatrice-1; j++)
{
if ((m[i][j]== m[i][j+1]) && (m[i][j]!=0))
{
condition++;
if (condition==maxPionAligne)
{
return 1;
}
}
else
{
condition=1;
}
}
}
//test sur les colonnes
for (j=0; j<maxMatrice; j++)
{
condition=1;
for (i=0; i<maxMatrice-1; i++)
{
if ((m[i][j]== m[i+1][j]) && (m[i][j]!=0))
{
condition++;
if (condition==maxPionAligne)
{
return 1;
}
}
else
{
condition=1;
}
}
}
//test sur la premiere diagonale
for (i=0;i<maxMatrice-1;i++)
{
if ((m[i][i]== m[i+1][i+1]) && (m[i][i]!=0))
{
condition++;
if (condition==maxPionAligne)
{
return 1;
}
}
else
{
condition=1;
}
}
//test sur la deuxieme diagonale
condition=1;
for (i=0,j=maxMatrice-1;i<maxMatrice;i++,j--)
{
if ((m[i][j]== m[i+1][j-1]) && (m[i][j]!=0))
{
condition++;
if (condition==maxPionAligne)
{
return 1;
}
}
else
{
condition=1;
}
}
return 0;
}
void jouer(int m[maxMatrice][maxMatrice])
{
//jouer : Contient la boucle principale du jeu
int coup=0;
int continuer=1;
int x,y;
int joueur=1;
remplirMatriceAzero(m);//initialisation de la matrice
affichage(m);
//qui commence
while (continuer)
{
//entrer coordonnees
saisie(joueur,&x,&y,m);
//test si gagné,afficher le gagnant,continuer=0
if (testerGagnant(m) )
{
printf("\n\n joueur %d est gagnant \n\n",joueur);
continuer=0;//fin de la partie
}
//affichage grille apres saisie
affichage(m);
joueur=3-joueur;//pour changer de joueur
coup++;
if (coup == maxMatrice*maxMatrice)
{
printf("\n\n MATCH NUL \n\n");
continuer=0;//fin de partie
}
}
}
int main (void)
{
int continuer=1;
int grille[maxMatrice][maxMatrice];
while (continuer==1)
{
jouer(grille);
printf("\n\n Une autre partie 1=oui 0=non ? :");
continuer=lireInt();
printf("\n");
}
return 0;
}
Bonjour la correction se fera avec l'exo suivant?
Personne pour un feedback sur ma fonction
testGagnant?
J'ai regarde ton code Gurney, sans toutefois tout decrypter.
J'ai parcouru ton code rapidement.
Pour ta fonction testerGagnant, je la trouve pas mal du tout.
Juste, pour une grille N*N, et m pions alignés, tu peux avoir plus de 2 diagonales.
Cette ligne, et son équivalent pour les autres tests
if ((m[i][j]== m[i][j+1]) && (m[i][j]!=0))
Je trouve plus naturel d'inverser l'ordre des conditions.
if (m[i][j] != 0 && m[i][j] == m[i][j+1])
si la case est vide, le test s'arrête là.
Dans ta fonction affichage
int motif[3];
motif[0]= 32;
motif[1]= 6;
motif[2]= 15;
tu peux faire
int motif[] = {32, 6, 15};
Peut-être, devrais tu préférer des #define à la place de valeur comme 6, 15, 185, 188
#define ACK 6 /* acknowledge */
#define SI 15 /* shift in */
etc...
Ta fonction de saisie, réalise trop de chose, je pense.
Elle récupère les coordonnées x, y, et renseigne la grille.
Du coup x, y ne servent que dans cette fonction(sauf erreur de ma part).
Pourquoi, ne pas en faire des locales, dans ce cas.
Ou, actualiser la grille à un autre endroit?
Je poste mon code un peu tard, mais c'est parce-que j'ai vraiment pas beaucoup de temps et ce moment :
#define TA_GRILLE 3 // grille de 3x3 cases
#include <stdio.h>
#include <stdlib.h>
typedef enum {X, O} TourDeJeu; // Dit qui doit jouer
enum {RIEN = 0, MATCHNUL = 1, XGAGNE = 2, OGAGNE = 3};
typedef struct{int x, y} Pos;
void jeu ();
int main()
{
jeu();
return 0;
}
void afficheJoueur (char joueur[], TourDeJeu tour)
{
printf("\nAux %c de jouer\n\n", joueur[tour]);
}
void afficherGrille (char grille[])
{
printf(" -------------\n");
printf(" | %c | %c | %c |\n", grille[0], grille[1], grille[2]);
printf(" -------------\n");
printf(" | %c | %c | %c |\n", grille[3], grille[4], grille[5]);
printf(" -------------\n");
printf(" | %c | %c | %c |\n", grille[6], grille[7], grille[8]);
printf(" -------------\n");
}
void afficher (char grille[], char joueur[], TourDeJeu tour) // Cette fonction combine les deux précédentes
{
afficheJoueur(joueur, tour);
afficherGrille(grille);
}
void TabToMatr (char matrice[][TA_GRILLE], char grille[], Pos *derCoupMat, int dernierCoup) //conversion Tab/matrice et initialisation de la struct
{
int i, j;
derCoupMat->x = 0;
derCoupMat->y = 0;
for(i = 0; i < TA_GRILLE; i++)
{
for (j = 0; j < TA_GRILLE; j++)
{
matrice[i][j] = grille[(i*TA_GRILLE) + j];
}
}
// Initialisation de la struct
derCoupMat->x = dernierCoup % TA_GRILLE;
for (i = 1; i < TA_GRILLE; i++)
{
if (dernierCoup < (TA_GRILLE * i))
derCoupMat->y = (i - 1);
}
}
int fini (char grille[], int dernierCoup, int coupsRestant, char DernJoueur) // Renvoie une valeur de l'enum indéfinie
{
char matrice[TA_GRILLE][TA_GRILLE];
Pos derCoupMat;
dernierCoup--;
TabToMatr(matrice, grille, &derCoupMat, dernierCoup);
// Debut des tests proprement dits
if (coupsRestant == 0) // S'il n'y a plus de cases libres
return MATCHNUL;
// DernJoueur correspond au joueur ayant joué pour la dernière fois.
else if (matrice[0][derCoupMat.y] == DernJoueur && matrice[1][derCoupMat.y] == DernJoueur && matrice[2][derCoupMat.y] == DernJoueur) // Test de la ligne
{
if (DernJoueur == 'X')
return XGAGNE;
else
return OGAGNE;
}
else if (matrice[derCoupMat.x][0] == DernJoueur && matrice[derCoupMat.x][1] == DernJoueur && matrice[derCoupMat.x][2] == DernJoueur) // Test de la colonne
{
if (DernJoueur == 'X')
return XGAGNE;
else
return OGAGNE;
}
else if ((matrice[0][0] == DernJoueur && matrice[1][1] == DernJoueur && matrice[2][2] == DernJoueur) ||
(matrice[2][0] == DernJoueur && matrice[1][1] == DernJoueur && matrice[0][2] == DernJoueur)) // Test des diagonales
{
if (DernJoueur == 'X')
return XGAGNE;
else
return OGAGNE;
}
else
return RIEN;
}
int TestCase (char grille[], int CaSaisie) // Renvoie 0 si la case est vide, 1 si elle est pleine
{
CaSaisie --;
if (grille[CaSaisie] == 'X' || grille[CaSaisie] == 'O')
return 1;
else
return 0;
}
int saisie (char grille[]) // Renvoie la saisie du joueur
{
int caseChoisie;
printf("Quelle case voulez-vous occuper ? ");
scanf("%d", &caseChoisie);
if (caseChoisie < 1 || caseChoisie > (TA_GRILLE * TA_GRILLE)) // Si le nombre est incorrect
{
printf("Veillez choisir un nombre entre 1 et %d !\n", TA_GRILLE * TA_GRILLE);
caseChoisie = saisie(grille);
}
if (TestCase(grille, caseChoisie))
{
printf("Cette case est deja prise, choisissez un autre nombre\n");
caseChoisie = saisie(grille);
}
return caseChoisie;
}
void PlacerSigne (char grille[], int caseJ, TourDeJeu *tour, char joueur[])
{
caseJ--; // Pour nne pas avoir a rajouter -1 partout
grille[caseJ] = joueur[*tour]; // met la grille a jour
*tour = (*tour == X) ? O : X;
}
void IndiqueGagnant (int gagnant)
{
if (gagnant == MATCHNUL)
printf("\nMatch nul...\n");
else if (gagnant == XGAGNE)
printf("\nLes X ont gagnes ! bravo !\n");
else if (gagnant == OGAGNE)
printf("\nLes O ont gagnes ! bravo !\n");
}
void jeu ()
{
char grille[TA_GRILLE * TA_GRILLE] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
char joueur [2] = {'X', 'O'}; // Contient les deux joueurs
TourDeJeu tour = X;
int coupsRestant = 9; // Donne le nombre de cases non occupées
int gagne = RIEN; // Dit si on a gagné, mais aussi le gagnant
int coup; // Index du dernier coup joué
while(!gagne)
{
afficher(grille, joueur, tour);
coup = saisie(grille);
PlacerSigne(grille, coup, &tour, joueur);
coupsRestant--;
gagne = fini(grille, coup, coupsRestant, joueur[tour]);
}
IndiqueGagnant(gagne);
afficherGrille(grille);
}
J'aimerais comprendre pourquoi ce code me fait jouer 1 coup avant de remarquer que j'ai gagné...
Je pensais faire une correction avec la partie 2, mais vu le monde qui participe à la partie 2, je donnerai une correction pour la partie 1 et la partie 2 j'en donnerai sûrement une, mais sans commentaires.
Je commenterai vos code plus tard.
merci Gurney pour ton feedback.
Pour les diagonales je pensais avoir brosser tous les cas et mince ils en manquent
je tiens compte de tes remarques, et je corrige.....
Cela me fait penser que ma fonction testgagnant je m'y suis pas pris dans le bon sens :
au lieu de brosser tous les cas, je devrais m'orienter uniquement sur la ligne la colonne les 2 diagonales à partir du dernier coup joué !
je devrais m'orienter uniquement sur la ligne la colonne les 2 diagonales à partir du dernier coup joué !
C'est exactement ça qu'il faut faire.
Keriz >
Des confusions au niveau des tableaux. L'envoi du tableau à une fonction et la récupération de ce tableau, c'est pas clair. Revoies le cours sur les tableaux.
sydzero >
Tu pourrais créer une fonction 'rejouer'
Il doit te manquer quelque chose dans ton 'else' de ta fonction gagner :
if (tableau[i-1][tailleTab-i] == 'X')
count_1++;
else if (tableau[i][tailleTab-i] == 'O')
count_2++;
Pour un jeu de NxN cases, il n'y a pas que 2 diagonales à tester.
Tu pourrais tester tes allocations
Dans ta fonction gagner tu n'utilises pas ta variable 'joueur'
Dans l'ensemble, c'est pas trop mal, mais l'utilisation d'un tableau à 2 dimensions n'apporte rien de plus (si, te faire pratiquer ).
On préfèrera avoir des noms en majuscule pour les constantes
Tu pourrais faire une fonction rejouer
Mêmes remarques que GurneyH
nasta >
Il te manque un ';' dans ta structure
Les commentaires ne sont pas très utile, ils encombrent le code
Tu fais de la récursivité dans ta fonction 'saisie', utilises plutôt les boucles
Pourquoi convertir ton tableau en tableau 2D ? il n'y a aucune utilité à ça
Dans ta fonction 'fini' tu pourrais tout regrouper dans un seul if histoire de factoriser tout ça.
J'ai tenu compte de tes remarques (sauf les commentaires et le tableau 2D)
Je convertis en tableau 2D car j'ai trouvé que ça rendait les tests plus simples, et que ce sera plus facile à modifier lors d'un agrandissement.
#define TA_GRILLE 3 // grille de 3x3 cases
#include <stdio.h>
#include <stdlib.h>
typedef enum {X, O} TourDeJeu; // Dit qui doit jouer
enum {RIEN = 0, MATCHNUL = 1, XGAGNE = 2, OGAGNE = 3};
typedef struct{int x, y;} Pos;
void jeu ();
int main()
{
jeu();
return 0;
}
void afficheJoueur (char joueur[], TourDeJeu tour)
{
printf("\nAux %c de jouer\n\n", joueur[tour]);
}
void afficherGrille (char grille[])
{
printf(" -------------\n");
printf(" | %c | %c | %c |\n", grille[0], grille[1], grille[2]);
printf(" -------------\n");
printf(" | %c | %c | %c |\n", grille[3], grille[4], grille[5]);
printf(" -------------\n");
printf(" | %c | %c | %c |\n", grille[6], grille[7], grille[8]);
printf(" -------------\n");
}
void afficher (char grille[], char joueur[], TourDeJeu tour) // Cette fonction combine les deux précédentes
{
afficheJoueur(joueur, tour);
afficherGrille(grille);
}
void TabToMatr (char matrice[][TA_GRILLE], char grille[], Pos *derCoupMat, int dernierCoup) //conversion Tab/matrice et initialisation de la struct
{
int i, j;
derCoupMat->x = 0;
derCoupMat->y = 0;
for(i = 0; i < TA_GRILLE; i++)
{
for (j = 0; j < TA_GRILLE; j++)
{
matrice[i][j] = grille[(i*TA_GRILLE) + j];
}
}
// Initialisation de la struct
derCoupMat->x = dernierCoup % TA_GRILLE;
for (i = 1; i < TA_GRILLE; i++)
{
if (dernierCoup < (TA_GRILLE * i))
derCoupMat->y = (i - 1);
}
}
int fini (char grille[], int dernierCoup, int coupsRestant, char DernJoueur) // Renvoie une valeur de l'enum indéfinie
{
char matrice[TA_GRILLE][TA_GRILLE];
Pos derCoupMat;
dernierCoup--;
TabToMatr(matrice, grille, &derCoupMat, dernierCoup);
// Debut des tests proprement dits
if (coupsRestant == 0) // S'il n'y a plus de cases libres
return MATCHNUL;
// DernJoueur correspond au joueur ayant joué pour la dernière fois.
else if ((matrice[0][derCoupMat.y] == DernJoueur && matrice[1][derCoupMat.y] == DernJoueur && matrice[2][derCoupMat.y] == DernJoueur) ||
(matrice[derCoupMat.x][0] == DernJoueur && matrice[derCoupMat.x][1] == DernJoueur && matrice[derCoupMat.x][2] == DernJoueur) ||
(matrice[0][0] == DernJoueur && matrice[1][1] == DernJoueur && matrice[2][2] == DernJoueur) ||
(matrice[2][0] == DernJoueur && matrice[1][1] == DernJoueur && matrice[0][2] == DernJoueur))
{
if (DernJoueur == 'X')
return XGAGNE;
else
return OGAGNE;
}
else
return RIEN;
}
int TestCase (char grille[], int CaSaisie) // Renvoie 0 si la case est vide, 1 si elle est pleine
{
CaSaisie --;
if (grille[CaSaisie] == 'X' || grille[CaSaisie] == 'O')
return 1;
else
return 0;
}
int saisie (char grille[]) // Renvoie la saisie du joueur
{
int caseChoisie;
int nombreCorrect = 0;
do{
printf("Quelle case voulez-vous occuper ? ");
scanf("%d", &caseChoisie);
if (caseChoisie < 1 || caseChoisie > (TA_GRILLE * TA_GRILLE)) // Si le nombre est incorrect
printf("Veillez choisir un nombre entre 1 et %d !\n", TA_GRILLE * TA_GRILLE);
else if (TestCase(grille, caseChoisie))
printf("Cette case est deja prise, choisissez un autre nombre\n");
else
nombreCorrect = 1;
}while(!nombreCorrect);
return caseChoisie;
}
void PlacerSigne (char grille[], int caseJ, TourDeJeu *tour, char joueur[])
{
caseJ--; // Pour nne pas avoir a rajouter -1 partout
grille[caseJ] = joueur[*tour]; // met la grille a jour
*tour = (*tour == X) ? O : X;
}
void IndiqueGagnant (int gagnant)
{
if (gagnant == MATCHNUL)
printf("\nMatch nul...\n");
else if (gagnant == XGAGNE)
printf("\nLes X ont gagnes ! bravo !\n");
else if (gagnant == OGAGNE)
printf("\nLes O ont gagnes ! bravo !\n");
}
void jeu ()
{
char grille[TA_GRILLE * TA_GRILLE] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
char joueur [2] = {'X', 'O'}; // Contient les deux joueurs
TourDeJeu tour = X;
int coupsRestant = 9; // Donne le nombre de cases non occupées
int gagne = RIEN; // Dit si on a gagné, mais aussi le gagnant
int coup; // Index du dernier coup joué
while(!gagne)
{
afficher(grille, joueur, tour);
coup = saisie(grille);
PlacerSigne(grille, coup, &tour, joueur);
coupsRestant--;
gagne = fini(grille, coup, coupsRestant, joueur[tour]);
}
IndiqueGagnant(gagne);
afficherGrille(grille);
}
Par contre, je comprends toujours pas pourquoi ma fonction "fini" ne fonctionne que lors de la deuxième ligne terminée...
× 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.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
tu peux le changer par