Erreur morpion

Résolu/Fermé
dr_melik Messages postés 43 Date d'inscription vendredi 18 janvier 2008 Statut Membre Dernière intervention 16 octobre 2009 - 20 févr. 2008 à 20:33
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 21 févr. 2008 à 10:09
Bonjour,
j'ai fait un programme de morpion mais il y a une erreur au niveau de [void main] que jen'arrive pas à gérer ainsi que da'autres erreurs dans le test du gagnant
svp aidez moi
le programme:

#include<stdio.h>
#include<conio.h>
#define Lmax 3
#define Cmax 3
typedef int tab[Lmax][Cmax];
tab t;

void Miseazero(tab t)
{
int i,j ;
for(i=0;i<Lmax;i++)
for(j=0;j<Cmax;j++)
t[i][j]=0;
}

void affichetableau(tab t)
{
int i,j;
for(i=0;i<Lmax;i++){
for(j=0;j<Cmax;j++)
printf("%d ",t[i][j]);
printf("\n\n\n");
}
}

int coupvalide(tab t,int a,int b)
{
int trouve=0;
if(t[a][b]==0)
trouve=1;
else trouve=0;
return(trouve);
}

int ver(tab t)
{
int i,j,cond=0;
j=0;
do
{
for(i=0;i<Lmax;i++)
if (t[i][j]==1||t[i][j]==2)
cond=1;
j++;
}
while(j<3);
return(cond);
}

int lignehor(tab t)
{
int i,j,cond=0;
i=0;
do
{
for(j=0;j<Cmax;j++)
if(t[i][j]==1||t[i][j]==2)
cond=1;
i++;
}
while(i<3);
return(cond);
}

int lignediagD(tab t)
{
int i,cond=0;
for(i=0;i<Lmax;i++)
if(t[i][i]==1||t[i][i]==2)
cond=1;
return(cond);
}

int lignediagG(tab t)
{
int i,j,cond=0;
for(i=0;i<Lmax;i++)
for(j=2;j<1;j--)
if(t[i][j]==1||t[i][j]==2)
cond=1;
return(cond);
}

int saisieval(tab t,int a,int b,int numjoueur)
{
int cond=0;
if(coupvalide(t,a,b)==1)
{
t[a][b]=numjoueur;
cond=1;
}
else
cond=0;
return(cond);
}



void main()
{
int l,c,a,b,i=1;

Miseazero(t);
affichetableau(t);
getch();
do
{
if(i%2==1)
{
do{
printf("le joueur1 joue");
printf("\n taper l :");
scanf("%d",&l);
printf("\n taper c :");
scanf("%d",&c);
}
while((saisieval(t,l,c,1)==0)||((l>3)&&(c>3)));
affichetableau(t);
}
else
{
do
{
printf("le joueur2 joue");
printf("\n taper a :");
scanf("%d",&a);
printf("\n taper b :");
scanf("%d",&b);
}while((saisieval(t,a,b,2)==0)||((a>3)&&(b>3)));
affichetableau(t);
}
i++;
}
while((i<10)&&(ver(t)==0)&&(lignehor(t)==0)&&(lignediagD(t)==0)&&(lignediagG(t)==0));
if(i==9) printf("execo");
else if((i-1)%2==1) printf("le joueur1 a gagner");
else if((i-1)%2==0) printf("le joueur2 a gagner");
getch();
}

1 réponse

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
21 févr. 2008 à 10:09
Ton programme corrigé (enfin normalement :p)
#include  <stdio.h>
// ce header n'est pas standard évite de l'utiliser (en plus il sert à rien :p)
// #include  <conio.h>
#define LMAX 3
#define CMAX 3
#define CASE_VIDE 0 // doit impérativement être différent d'un id de joueur
#define NUM_JOUEUR 2

typedef unsigned tab[LMAX][CMAX];
//tab t; // pas de variable globale, c'est mal :)

void mise_a_zero(tab t){
    unsigned i,j ;
    for(i = 0;i < LMAX;i++){
        for(j = 0;j < CMAX;j++) t[i][j] = CASE_VIDE;
    }
}

void affiche_tableau(tab t){
    unsigned i,j;
    for(i = 0;i < LMAX;i++){
        for(j = 0;j < CMAX;j++) printf("%i ",t[i][j]);
        printf("\n");
    }
    printf("\n");
}

unsigned coup_valide(tab t,unsigned l,unsigned c){
    return  (l < LMAX) && (c < CMAX) && (t[l][c] == CASE_VIDE);
}

unsigned ligne_hor(tab t,unsigned numjoueur){
    unsigned i,j,cond;
    for(i = 0;i < LMAX;i++){
        cond = 1;
        for(j = 0;j < CMAX;j++){
            if(t[i][j] != numjoueur){
                cond = 0;
                continue;
            }
        }
        if(cond) return 1;
    }
    return 0;
}

unsigned ligne_ver(tab t,unsigned numjoueur){
    unsigned i,j,cond;
    for(j = 0;j < CMAX;j++){
        cond = 1;
        for(i = 0;i < LMAX;i++){
            if(t[i][j] != numjoueur){
                cond = 0;
                continue;
            }
        }
        if(cond) return 1;
    }
    return 0;
}

unsigned ligne_diag_d(tab t,unsigned numjoueur){
    unsigned i,cond = 1;
    // attention si CMAX < LMAX : segfault !
    for(i = 0;i < LMAX;i++){
        if(t[i][i] != numjoueur) cond = 0;
    }
    return cond;
}

unsigned ligne_diag_g(tab t,unsigned numjoueur){
    unsigned i,cond = 1;
    // attention si LMAX < CMAX : segfault !
    for(i = 0;i < LMAX;i++){
        if(t[LMAX-i-1][i] != numjoueur) cond = 0;
    }
    return cond;
}

unsigned saisie_val(tab t,unsigned a,unsigned b,unsigned numjoueur){
    if(coup_valide(t,a,b)){
        t[a][b] = numjoueur;
        return 1;
    }
    return 0;
}

// retourne le numero du gagnant, 0 si pas de gagnant
unsigned joueur_gagnant(tab t){
    unsigned numjoueur;
    for(numjoueur = 1;numjoueur < NUM_JOUEUR+1;++numjoueur){
        if(ligne_hor(t,numjoueur) || ligne_ver(t,numjoueur)
        || ligne_diag_d(t,numjoueur) || ligne_diag_g(t,numjoueur)){
            return numjoueur;
        }
    }
    return 0;
}

// convertit le tour en numero de joueur
unsigned nb_tour2num_joueur(unsigned tour){
    unsigned mod = tour % NUM_JOUEUR;
    if(mod == 0) return NUM_JOUEUR;
    return mod;
}

int main(){
    unsigned numjoueur,l,c,i = 1,gagnant = 0;
    tab t; // c'est ici que t doit être déclarée :-)
    mise_a_zero(t);
    affiche_tableau(t);
//  getchar(); // préfère getchar() à getch() pour éviter d'inclure <curses.h>
    for(i = 1;i < LMAX*CMAX && (gagnant == 0);++i){
        numjoueur = nb_tour2num_joueur(i);
        do{
            printf("le joueur%i joue\n",numjoueur);
            printf("taper l : ");
            scanf("%d",&l);
            printf("taper c : ");
            scanf("%d",&c);
        }while(saisie_val(t,l,c,numjoueur) == 0);
        affiche_tableau(t);
        gagnant = joueur_gagnant(t);
        printf("gagnant = %i\n",gagnant);
    }
    if(i == LMAX*CMAX) printf("ex-aequo\n");
    else printf("le joueur%i a gagné\n",gagnant);
    printf("appuyez sur une touche pour quitter...\n");
    getchar();
    return 0;
}

Remarques globales:
- les #define sont suivies de macros/non de variable généralement en majuscule par convention
- les noms de fonctions s'écrivent en minuscule par convention, les _ peuvent améliorer la lisibilité
- préfère les unsigned aux unsigned quand les entiers sont positifs
- il vaut mieux pêcher par excès d'accolade que le contraire, afin que le programme soit plus lisible
- prunsignedf < => printf ?
- return n'est pas une fonction (donc pas de parenthèse)
- parfois certains "3" n'ont pas été corrigés par CMAX/LMAX
- certains de tes do..while devraient être des for..
- main() est sensé retourner un entier (le code d'erreur, 0 si tout va bien)
- idéalement il aurait fallu utiliser une structure à la place d'un tableau statique pour représenter le tableau et la créer avec un malloc, puis la libérer avec un free (mais tu n'as peut-être pas encore vu les pointeur ?)
    typedef struct _tab{
        unsigned nb_lig;
        unsigned nb_col;
        unsigned **tab;
    } tab;

- idéalement il faut éviter de passer des tableaux et des structures volumineuses en paramètre d'une fonction car chaque paramètre de fonction est recopié (donc si c'est gros, ça coute cher). en pratique on passe plutôt leur adresse (ou leur référence en C++)

Bonne chance
0