Partage
  • Partager sur Facebook
  • Partager sur Twitter

Où est l'erreur dans ce puissance 4 ?

Sujet résolu
    19 novembre 2017 à 17:12:00

    Bonjour,

    Je suis en train de coder un puissance" 4 en C++ (sur la console) pour jouer à deux joueurs.

    J'ai donc fait 4 sous-programmes en plus de main qui gèrent respectivement : l'initialisation de la grille, son affichage, le jeu (placement des "pions") et les conditions de fin de partie.

    Mon problème est que quand je commence une partie, le pion ne se place pas et le partie est de suite considérée comme gagnée, or je ne vois pas où j'ai fait une erreur.

    Je joint le code en vous épargnant les deux premières procédures qui elles fonctionnent bien ainsi qu'une capture d'écran de ce qu'il se passe:

    char fin (char tab [15][15], char play)
    {
        char etat = '0';
    
        for (int i =1; i<8; i+=2) //victoire colone
        {
            for (int j=1; j<14; j+=2)
            {
               if (tab [i][j]!=' ' && tab [i][j]==tab [i+2][j] && tab [i][j]==tab [i+4][j] && tab [i][j]==tab [i+6][j])
                    etat = play;
            }
        }
    
        for (int i = 1; i<14; i+=2) //victoire ligne
        {
            for (int j = 1; j<8; j+=2)
            {
                if (tab [i][j]!=' ' && tab [i][j]==tab [i][j+2] && tab [i][j]==tab [i][j+4] && tab [i][j]==tab [i][j+6])
                    etat = play;
            }
        }
    
        for (int i = 1; i<8; i+=2) //victoire diagonale /
        {
            for (int j = 13; j>6; j-=2)
            {
                if (tab [i][j]!=' '&&tab [i][j]==tab [i+2][j-2] && tab [i][j]==tab [i+4][j-4] && tab [i][j]==tab [i+6][j-6])
                    etat = play;
            }
        }
    
        for (int i = 1; i<8; i+=2) /*victoire diagonale \  */
        {
            for (int j = 1; j<8; j+=2)
            {
                if (tab [i][j]!=' ' && tab [i][j]==tab [i+2][j+2] && tab [i][j]==tab [i+4][j+4] && tab [i][j]==tab [i+6][j+6])
                    etat = play;
            }
        }
    
        if (etat!=play &&
            tab [1][1]!=' ' && tab [1][3]!=' ' && tab [1][5]!=' ' && tab [1][7]!=' ' && tab [1][9]!=' ' && tab [1][11]!=' ' && tab [1][13]!=' ' &&
            tab [3][1]!=' ' && tab [3][3]!=' ' && tab [3][5]!=' ' && tab [3][7]!=' ' && tab [3][9]!=' ' && tab [3][11]!=' ' && tab [3][13]!=' ' &&
            tab [5][1]!=' ' && tab [5][3]!=' ' && tab [5][5]!=' ' && tab [5][7]!=' ' && tab [5][9]!=' ' && tab [5][11]!=' ' && tab [5][13]!=' ' &&
            tab [7][1]!=' ' && tab [7][3]!=' ' && tab [7][5]!=' ' && tab [7][7]!=' ' && tab [7][9]!=' ' && tab [7][11]!=' ' && tab [7][13]!=' ' &&
            tab [9][1]!=' ' && tab [9][3]!=' ' && tab [9][5]!=' ' && tab [9][7]!=' ' && tab [9][9]!=' ' && tab [9][11]!=' ' && tab [9][13]!=' ' &&
            tab [11][1]!=' ' && tab [11][3]!=' ' && tab [11][5]!=' ' && tab [11][7]!=' ' && tab [11][9]!=' ' && tab [11][11]!=' ' && tab [11][13]!=' ' &&
            tab [13][1]!=' ' && tab [13][3]!=' ' && tab [13][5]!=' ' && tab [13][7]!=' ' && tab [13][9]!=' ' && tab [13][11]!=' ' && tab [13][13]!=' ')
                {etat = 'N';}
    
        return etat;
    }
    
    void jouer (char tab [15][15], char play)
    {
        int colone;
    
        cout << "Joueur " << play << ", quelle colone ? : ";
       // do
       // {
            cin >> colone;
            colone = 2*(colone-1)+1;
    
       //     if (tab [1][colone]!=' ')
       //         cout << "Cette colone est pleine, choisissez-en une autre : ";
       // }while (tab [1][colone]!=' ');
    
        for (int i = 13; i>0; i-=2)
        {
            if (tab [i][colone]==' ')
            {
                tab [i][colone] = play;
                i=0;
            }
        }
    }
    
    int main()
    {
        char joueur, fini;
        char grille [15][15] = {' '};
        initialiser(grille);
    
        cout << "Bienvenue sur le jeu du puissance 4 ! \n\nOn numérote les colones de 1 a 7, joueur X commence !\n";
    
        do
        {
            joueur = 'X';
            affiche (grille);
            jouer (grille, joueur);
            affiche (grille);
            fini = fin(grille, joueur);
            if (fini=='0')
            {
                joueur = 'O';
                jouer (grille, joueur);
                affiche (grille);
                fini = fin (grille, joueur);
            }
        }while (fini=='0');
    
        if (fini=='N')
            cout << "Match nul !";
    
        else
            cout << "C'est joueur " << fini << " qui gagne ! GG";
    
        return 0;
    }


    Merci d'avance pour vos réponses ! :)

    edit : une condition de la procédure "jeu" est en commentaire pour l'isoler car je croyais que le problème venait d'elle.

    -
    Edité par KomkHOMBR 19 novembre 2017 à 17:14:34

    • Partager sur Facebook
    • Partager sur Twitter
    l'ouverture d’esprit n'est pas une fracture du crâne ...
      19 novembre 2017 à 19:58:54

      Tu devrais découper fin en plusieurs fonctions pour faire des tests individuels. Et remplacer le gros if par des boucles ou un compteur de coup.

      Et changer le type de retour pour un bool. Et changer le nom. Et utiliser std::array plutôt que les tableaux C tout pourris.

      • Partager sur Facebook
      • Partager sur Twitter
        19 novembre 2017 à 20:15:10

        D'accord je vais essayer merci ;) juste que je ne connais pas std::array j'ai un peu lâché le cours du site pour pas m'embrouiller avec mes cours de fac (des termes changent etc ...).

        En tout cas merci pour ta réponse.

        • Partager sur Facebook
        • Partager sur Twitter
        l'ouverture d’esprit n'est pas une fracture du crâne ...
          19 novembre 2017 à 23:35:30

          Bonjour,

          En travaillant directement sur une table qui contient à la fois l'affichage et le données à traiter, tu ne fait que complexifier l'écriture.
          Ta table est vraisemblablement mal initialisée, les cases vides ont autre chose que des ' ', et tes tests considèrent ce qui n'est pas une espace comme une valeur valide, d'où un gain immédiat.
          Tu devrais écrire ton code en C++ plutôt qu'en C avec cin/cout. Crée des objets 'Case' qui pourront se mettre dans tableau à 2 dimensions. Si tu souhaite conserver ton objet grille, il faudra synchroniser les 2 avant affichage.

          enum Case : char {
             X = 'X', O = 'O', VIDE = 0
          };
          class Grille {
             static const unsigned Lignes   = 5;
             static const unsigned Colonnes = 7;
             std::vector<Case> data;
          public:
             Grille() : data(Lignes*Colonnes,VIDE) {}
             Case& at(unsigned ligne, unsigned colonne) {
                assert(ligne<Lignes);
                assert(colonne<Colonnes);
                return data[ligne*Colonnes+colonne];
             }
             bool partieNulle()const {
                return std::all_of( data.begin(), data.end() );
             }
          };

          Ligne 9, on a une initialisation simple qui garantit que toutes les cases sont vides.
          Lignes 16, on a un test de partie nulle qui dit 'clairement' que la partie est nulle si toutes les cases ont été affectées

          • Partager sur Facebook
          • Partager sur Twitter

          En recherche d'emploi.

            21 novembre 2017 à 8:58:55

            Dalfab, je ne comprend pas pourquoi certaines cases vides ne sont pas des ' ' alors que j'ai initialisé la grille en block : char grille [13][15] = {' '}; mais en remplaçant les conditions :

            tab [i][j]==' '

            par des :

            tab [i][j]!='X' && tab [i][j]!='O'

            la procédure jeu fonctionne.

            Je ne voit pas d'utilité à découper fin en plusieurs fonctions de type bool mais je pense que le problème vient vraiment des conditions et non pas de le fonction elle même mais je ne vois pas pourquoi ça ne fonctionne pas.

            Voici le nouveau code (en entier) :D'ailleur je tiens à souligner le fait que j'ai inséré le compteur aussi dans les conditions de victoire mais qu'au premier tour le jeu considère la victoire. Peut être que le problème vient de main ?

            #include <iostream>
            
            using namespace std;
            
            void affiche (char tab [13][15])
            {
              for (int i = 0; i<13; i++)
                {
                    for (int j = 0; j<15; j++)
                    {
                        cout << tab [i][j];
                    }
            
                    cout << endl;
                }
            }
            
            void initialiser (char tab [14][15])
            {
                for (int i = 2; i<11; i+=2)
                {
                    for (int j = 2; j<13; j+=2)
                    {
                        tab [i][j]= 206;
                    }
                }
            
                for (int i = 2; i<11; i+=2)
                {
                    tab [i][0]=204;
                }
            
                for (int i = 2; i<11; i+=2)
                {
                    tab [i][14]= 185;
                }
            
                for (int i = 2; i<13; i+=2)
                {
                    tab [12][i]= 202;
                }
            
                for (int i = 2; i<13; i+=2)
                {
                    tab [0][i]= 203;
                }
            
                for (int i = 0; i<13; i+=2)
                {
                    for (int j = 1; j<14; j+=2)
                    {
                        tab [i][j]= 205;
                    }
                }
            
                for (int i = 1; i<12; i+=2)
                {
                    for (int j = 0; j<15; j+=2)
                    {
                        tab [i][j]= 186;
                    }
                }
            
                tab [0][0]=201;
                tab [0][14]=187;
                tab [12][0]=200;
                tab [12][14]=188;
            }
            
            char fin (char tab [13][15], char play, int nb)
            {
                char etat = '0';
            
                for (int i =1; i<6; i+=2) //victoire colone
                {
                    for (int j=1; j<14; j+=2)
                    {
                       if (nb>4 && tab [i][j]!='X' && tab [i][j]!='O' && tab [i][j]==tab [i+2][j] && tab [i][j]==tab [i+4][j] && tab [i][j]==tab [i+6][j])
                       {
                           etat = play;
                           i=6;j=14;
                       }
                    }
                }
            
                for (int i = 1; i<14; i+=2) //victoire ligne
                {
                    for (int j = 1; j<6; j+=2)
                    {
                        if (nb>4 && tab [i][j]!='X' && tab [i][j]!='O' && tab [i][j]==tab [i][j+2] && tab [i][j]==tab [i][j+4] && tab [i][j]==tab [i][j+6])
                        {
                            etat = play;
                            i=14;j=6;
                        }
                    }
                }
            
                for (int i = 1; i<6; i+=2) //victoire diagonale /
                {
                    for (int j = 13; j>6; j-=2)
                    {
                        if (nb>10 && tab [i][j]!='X' && tab [i][j]!='O' && tab [i][j]==tab [i+2][j-2] && tab [i][j]==tab [i+4][j-4] && tab [i][j]==tab [i+6][j-6])
                        {
                            etat = play;
                            i=6;j=6;
                        }
                    }
                }
            
                for (int i = 1; i<6; i+=2) /*victoire diagonale \  */
                {
                    for (int j = 1; j<8; j+=2)
                    {
                        if (nb>10 && tab [i][j]!='X' && tab [i][j]!='O' && tab [i][j]==tab [i+2][j+2] && tab [i][j]==tab [i+4][j+4] && tab [i][j]==tab [i+6][j+6])
                        {
                            etat = play;
                            i=6;j=8;
                        }
                    }
                }
            
                if (etat!=play && nb>42)
                {
                    etat = 'N';
                }
            
                return etat;
            }
            
            void jouer (char tab [13][15], char play)
            {
                int colone;
            
                cout << "Joueur " << play << ", quelle colone ? : "; //boucle à modifier pour les valeurs non comprises entre 1 et 7
               // do
               // {
                    cin >> colone;
                    colone = 2*(colone-1)+1; //pour que le joueur puisse rentrer son coup en numérotant les colones de 1 à 7
            
               //     if (tab [1][colone]!=' ')
               //         cout << "Cette colone est pleine, choisissez-en une autre : ";
               // }while (tab [1][colone]!=' ');
            
                for (int i = 11; i>0; i-=2)
                {
                    if (tab [i][colone]!='X' && tab [i][colone]!='O')
                    {
                        tab [i][colone] = play;
                        i=0;
                    }
                }
            }
            
            int main()
            {
                char joueur, fini = '0';
                char grille [13][15] = {' '};
                initialiser(grille);
                int compteur = 0;
            
                cout << "Bienvenue sur le jeu du puissance 4 ! \n\nOn numérote les colones de 1 a 7, joueur X commence !\n";
            
                do
                {
                    joueur = 'X';
                    affiche (grille);
                    jouer (grille, joueur);
                    compteur ++;
                    affiche (grille);
                    fini = fin(grille, joueur, compteur);
                    if (fini=='0')
                    {
                        joueur = 'O';
                        jouer (grille, joueur);
                        compteur++;
                        affiche (grille);
                        fini = fin (grille, joueur, compteur);
                    }
                }while (fini=='0');
            
                if (fini=='N')
                    cout << "Match nul !";
            
                else
                    cout << "C'est joueur " << fini << " qui gagne ! GG";
            
                return 0;
            }

            edit : mon prof de tp a trouvé l'erreur ! Ça venait des conditions de victoires qui vérifiaient si on avais une ligne/colonne/diagonale ... d'espaces.

            Merci pour votre aide :)

            -
            Edité par KomkHOMBR 21 novembre 2017 à 11:34:32

            • Partager sur Facebook
            • Partager sur Twitter
            l'ouverture d’esprit n'est pas une fracture du crâne ...

            Où est l'erreur dans ce puissance 4 ?

            × 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.
            • Editeur
            • Markdown