Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    janvier 2019
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 19
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : janvier 2019
    Messages : 1
    Points : 1
    Points
    1

    Par défaut Vérification de partie gagnée dans un Puissance 4

    Bonjour,

    Alors je suis en train de réaliser un programme qui permet de jouer au jeux Puissance 4. J'ai presque fini, mais j'ai un soucis au niveau de la vérification d'une partie gagnée. C'est-à-dire que lorsque 4 pions sont aligné (vertical,horizontal,diagonal).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    /* Appel de bibliothèque C */
    #include <stdio.h>
    #include <math.h>
     
    #define J1 'X'
    #define J2 'O'
    #define VIDE ' '
     
    #define COL 7
    #define LIG 6
     
    int choix_colonne , choix_ligne ;
    int C , L ;
    char grille[LIG][COL];
    int win , ega ;
    char re ;
    int v , n ;
     
    int main(void)
    {
        // DECLARATION DES FONCTIONS APPELLEES
        void initialiser_grille ( char (*grille)[COL] ) ;
        void affiche_grille ( char (*grille)[COL] ) ;
        int verification_colonne ( char (*grille)[COL] , int choix );
        int verification_egalite ( char (*grille)[COL] );
        int demande_colonne_joueur ( int k );
        int verication_partie_gagne ( char (*grille)[COL] , int y , int x);
        void inserer_pion ( char (*grille)[COL] , char symbole , int choix_colonne );
     
        // DECLARATION DES VARIABLES de la fonction main
        int f ;
        // INITIALISER LES VARIABLES
        f=1 ;
        // APPEL DES FONCTIONS
        do
        {
            initialiser_grille ( grille );
     
            do
            {
     
                printf("\nJoueur 1 a vous de jouer!\n");
                inserer_pion ( grille , J1 , demande_colonne_joueur ( COL-1 ) );
     
                win = verication_partie_gagne(grille,L,C);
     
                if ( win == 1 )
                {
                    printf("Felicitations! Joueur 1 , vous remportez la partie!");
                }
     
                if ( win != 1 )
                {
                    printf("\nJoueur 2 a vous de jouer!\n");
                    inserer_pion ( grille , J2 , demande_colonne_joueur ( COL-1 ) );
     
                    if ( win == 1 )
                    {
                        printf("Felicitations! Joueur 2 , vous remportez la partie!");
                    }
                }
     
                ega = verification_egalite (grille) ;
                if ( ega == 1)
                {
                    printf("\nMatch Nul!");
                }
            }
            while( ega != 1 );
     
     
            printf("Voulez-vous rejouer la partie? Si oui saisir 1. Choix :", re);
            scanf("%d", &re);
        }
     
        while ( re == 'o');
     
        //SAISIE DES DONNEES
     
        //TRAITEMENT DES DONNEES
     
        //EDITION DES RESULTATS
     
        // SORTIR DE LA FONCTION main()
        printf("\n\n");
        return(0) ;
    }
     
    // AUTRES FONCTIONS
     
    void initialiser_grille ( char (*grille)[COL] )
    {
        // Remplissage de la grille pour le debut du jeu : chaque case contient un espace
        int i , j ;
     
        for(i=0 ; i<LIG ; i++)
        {
            for(j=0 ; j<COL ; j++)
            {
                grille[i][j] = VIDE ;
            }
        }
    }
     
    void affiche_grille ( char (*grille)[COL] )
    {
        // Affichage de la grille
        int a , b ;
     
        printf("\n| 0 | 1 | 2 | 3 | 4 | 5 | 6 |\n");
        printf("|---|---|---|---|---|---|---|\n");
        for(a=0; a<LIG; a++)
        {
            printf("|");
            for(b=0 ; b<COL ; b++)
            {
                printf(" %c |", grille[a][b]);
            }
            printf("\n");
            printf("|---|---|---|---|---|---|---|\n");
        }
        printf("| 0 | 1 | 2 | 3 | 4 | 5 | 6 |\n");
    }
     
    int verification_colonne ( char (*grille)[COL] , int choix_colonne )
    {
        if ( ( grille [0][choix_colonne] == J1 ) || ( grille [0][choix_colonne] == J2 ) )  //Verifie si colonne est pleine
        {
            printf("\nLa colonne est pleine!");
            return 1 ;
        }
     
     
        if ( ( choix_colonne > 6 ) || ( choix_colonne < 0 ) )  //Verifie si la saisie de colonne est correcte
        {
            printf("\nVueillez saisir une colonne correcte!");
            return 1 ;
        }
    }
     
    int verification_egalite ( char (*grille)[COL] )
    {
        if ( ( grille[0][0] == J1 || grille[0][0] == J2 ) && ( grille[0][1] == J1 || grille[0][1] == J2 ) && ( grille[0][2] == J1 || grille[0][2] == J2 ) && ( grille[0][3] == J1 || grille[0][3] == J2 )
                && ( grille[0][4] == J1 || grille[0][4] == J2 )&& ( grille[0][5] == J1 || grille[0][5] == J2 )&& ( grille[0][6] == J1 || grille[0][6] == J2 )  )
            return 1 ;
    }
     
     
    int demande_colonne_joueur ( int k )
    {
        // Demande saisi de colonne à l'utilisateur tant que la colonne choisi n'est pas valide
        do
        {
            affiche_grille ( grille );
            printf ("\nChoisissez colonne a jouer : ");
            scanf( "%d" , &choix_colonne );
        }
        while ( verification_colonne ( grille , choix_colonne ) == 1 );
        return choix_colonne;
    }
     
    void inserer_pion ( char (*grille)[COL] , char symbole , int choix_colonne )
    {
     
        for ( choix_ligne=5 ; choix_ligne>=0 ; choix_ligne-- )
        {
            if ( grille[choix_ligne][choix_colonne]==VIDE)
            {
                if ( symbole==J1 )
                {
                    grille[choix_ligne][choix_colonne]=J1;
                    break ;
                }
     
                if ( symbole==J2 )
                {
                    grille[choix_ligne][choix_colonne]=J2;
                    break ;
                }
            }
        }
    }
     
    int verication_partie_gagne ( char (*grille)[COL] , int y , int x)
    {
        int k ;
     
        for(k=0 ; k<COL ; k++)
        {
            if ( y>=3 ) //Verification alignement vertical
            {
                if( grille[y][x]==J1 && grille[y-1][x]==J1 && grille[y-2][x]==J1 && grille[y-3][x]==J1
                        || grille[y][x]==J2 && grille[y-1][x]==J2 && grille[y-2][x]==J2 && grille[y-3][x]==J2)
                    return 1 ;
            }
     
     
            else if ( x<=3 ) //Verification alignement horizontal
            {
                if( grille[y][x]==J1 && grille[y][x+1]==J1 && grille[y][x+2]==J1 && grille[y][x+2]==J1
                        || grille[y][x]==J2 && grille[y][x+1]==J2 && grille[y][x+2]==J2 && grille[y][x+2]==J2)
                    return 1 ;
            }
     
     
     
            else if ( y>=3 ) //Verification alignement diagonal montant
            {
                if( grille[y][x]==J1 && grille[y-1][x+1]==J1 && grille[y-2][x+2]==J1 && grille[y-3][x+3]==J1
                        || grille[x][y]==J2 && grille[x+1][y-1]==J2 && grille[x+2][y-2]==J2 && grille[x+3][y-3]==J2)
                    return 1 ;
            }
     
     
            else if ( y<=2 ) //Verification alignement diagonal montant
            {
                if( grille[y][x]==J1 && grille[y+1][x+1]==J1 && grille[y+2][x+2]==J1 && grille[y+3][x+3]==J1
                        || grille[y][x]==J2 && grille[y+1][x+1]==J2 && grille[y+2][x+2]==J2 && grille[y+3][x+3]==J2)
                    return 1 ;
            }
     
            else
                return 0 ;
        }
    }
    Merci de votre aide

  2. #2
    Expert confirmé
    Inscrit en
    mars 2005
    Messages
    1 404
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 1 404
    Points : 4 102
    Points
    4 102

    Par défaut

    Et donc, quel est le souci rencontré ?

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    6 889
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 6 889
    Points : 19 608
    Points
    19 608
    Billets dans le blog
    1

    Par défaut

    Ben je pense que le souci c'est que la fonction vérifie si 4 pions sont alignés indifféremment pour un joueur ou l'autre donc sans vraiment dire qui gagne. Ca signifie que ensuite il faudra refaire une seconde vérification pour dire qui a gagné.

    Un autre souci se situe dans l'utilisation sans nécessité de variables globales. Les globales c'est une fausse facilité car ensuite on perd mille fois plus de temps à débugguer (la preuve !!!)

    Donc c'est bien de vouloir découper mais faut aussi un peu réfléchir à la façon de découper. Moi j'aurais fait une fonction qui vérifie juste si un joueur X ou Y a 4 pions alignés (joueur donc paramètre de la fonction) et je l'aurais appelée 2 fois. Mais bon, c'est juste une réflexion à chaud sans être dans le code.

    Il y a aussi cette partie de code qui me chagrine...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if ( win != 1 )
                {
                    printf("\nJoueur 2 a vous de jouer!\n");
                    inserer_pion ( grille , J2 , demande_colonne_joueur ( COL-1 ) );
     
                    if ( win == 1 )
                    {
                        printf("Felicitations! Joueur 2 , vous remportez la partie!");
                    }
                }
    ... parce que j'ai beau me creuser le citron, je n'arrive pas à m'imaginer comment "win", différent de 1 quand on entre dans ce cas, peut alors subitement passer à "égal à 1". En plus c'est une variable globale donc je suis allé vérifier si "inserer_pion()" ne la modifiait pas (un des défauts de l'utilisation de variables globales !!!) mais non, "win" ne change pas.

    Et aussi la déclaration des fonctions se fait hors du main. Dans le main c'est possible mais ça veut dire que c'est le main qui appelle tout. Interdit par exemple d'avoir une fonction "fctX()" qui appellerait une autre fonction "fctY()".

    Après il y a des trucs qui ne sont pas des soucis mais qui peuvent aider. Si par exemple tu transformes ta "grille" en tableau 1D (passer de char grille[LIG][COL] à char grille[LIG * COL]) alors ça te simplifie les paramètres car tu n'es plus obligé de te trimballer "COL" dans toutes tes fonctions (void initialiser_grille ( char (*grille)[COL] ) devient simplement void initialiser_grille ( char *grille)). Juste ensuite un calcul pour passer d'un indice 1D à un indice 2D (si "i" balaye la grille alors x=i/COL et y=i%COL) et l'inverse pour passer de 2D à 1D (si tu as x et y alors i=x*COL + y). Et ça devrait aussi te permettre d'optimiser tes recherches d'alignement. Plutôt que de te battre avec des "&&" dans tous les sens, un petit truc à base de boucle en regardant à chaque tour si le grille[i] est identique au grille[i-1] pourrait être à la fois plus élégant et à la fois plus évolutif (facile de passer d'un "puissance 4" à un "puissance 5" par exemple)...

    Et enfin il y a le must: arriver à détacher ce qui est "calcul" de ce qui est "affichage". Les calculs se font dans une grille remplie de 0, de 1 et de 2 et l'affichage, lui, affiche des "X", des "O" ou autres. Ca c'est le fin du fin...
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    26 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 26 876
    Points : 39 694
    Points
    39 694

    Par défaut

    Ben je pense que le souci c'est que la fonction vérifie si 4 pions sont alignés indifféremment pour un joueur ou l'autre donc sans vraiment dire qui gagne. Ca signifie que ensuite il faudra refaire une seconde vérification pour dire qui a gagné.
    Cette partie n'est pas forcément un problème car si on vérifie à chaque coup, le seul gagnant possible est le joueur qui vient de jouer (un coup ne peut pas donner la victoire à l'adversaire, sauf le genre "machin gagne au prochain tour", mais pour tester ça c'est une autre paire de manches).

    Pour tout le reste de ton message, je suis d'accord.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    6 889
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 6 889
    Points : 19 608
    Points
    19 608
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par Médinoc Voir le message
    Cette partie n'est pas forcément un problème car si on vérifie à chaque coup, le seul gagnant possible est le joueur qui vient de jouer
    Bien vu
    La seule opposition que je puisse faire, c'est que dans ce cas, en moyenne, la moitié du travail de la fonction est fait pour rien.

    Citation Envoyé par Médinoc Voir le message
    Pour tout le reste de ton message, je suis d'accord.
    Trop d'honneur
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

Discussions similaires

  1. Réponses: 2
    Dernier message: 05/03/2014, 19h49
  2. Problème au niveau de la puissance
    Par adri0706 dans le forum Langage
    Réponses: 8
    Dernier message: 11/06/2012, 13h53
  3. Réponses: 1
    Dernier message: 01/06/2010, 20h21
  4. Problème au niveau d'unité de programme
    Par Bayoro dans le forum Sql*Plus
    Réponses: 19
    Dernier message: 08/04/2008, 19h20
  5. Réponses: 1
    Dernier message: 13/05/2007, 14h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo