Problème puissance 4

Fermé
l XION l Messages postés 673 Date d'inscription jeudi 19 janvier 2012 Statut Membre Dernière intervention 24 novembre 2024 - Modifié le 7 janv. 2018 à 23:14
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 - 7 janv. 2018 à 23:30
Bonjour

Alors tout d'abord, comme le programme est assez long ( puissance 4 ça se comprend ) je l'ai hebergé ici, vous pourrez le télécharger, il fait 154 lignes. J'ai mis des commentaires pour que vous compreniez bien import java.util.*;

import java.util.*;

public class P4 {
    
    private final static int VIDE=0;
    private final static int JAUNE=1;
    private final static int ROUGE=2;
    
    public static Scanner saisie = new Scanner(System.in);
    
    public static void main(String[]args) {    
        
        int [][] grille = new int [6][7];
        
        initialise(grille);
        affiche(grille);
        
        int couleurJoueur = JAUNE;            // On décide que le joueur JAUNE commencera la partie.
        boolean gagne;                     // Boolean qui se mettra à true lorsque l'un des deux joueurs gagnera.
        
        do {
    
            demandeEtJoue(grille, couleurJoueur);        // On éxécute tout le processus du jeu
            
            affiche(grille);        // La grille s'affiche donc ....
            
            gagne = estCeGagne(grille, couleurJoueur);
            
            // Et tout simplement, on alterne la couleur du joueur pour changer de joueur.
            if (couleurJoueur==JAUNE)    // Si c'était JAUNE qui jouait :
                couleurJoueur=ROUGE;    // Eh bien cette fois-ci ROUGE jouera
            else couleurJoueur=JAUNE;    // Sinon si c'était ROUGE qui jouait, JAUNE jouera.
        } while (!gagne && !plein(grille)); // Tant que personne n'a gagné, le jeu continu 
        
        // On est sortie de la boucle, ce qui singifie  que soit un joueur à gagné, soit la grille est pleine et donc on ne peux plus jouer : Match nul ! :
        
        if (gagne) {    // Si la partie s'est terminé parce qu'un joueur à gagné : 
            if ( couleurJoueur == JAUNE)                                            // On alterne les couleurs !
                System.out.println("Le joueur 0 à gagné !");
            else System.out.println("Le joueur X à gagné !");
        }
        else System.out.println("Match nul"); // Si la partie c'est terminé et que personne n'a gagné car la grille est pleine, alors match nul !
    }
    
    // Ici, on initialise la grille, de sorte à ce qu'elle soit vide.
    public static void initialise(int[][] grille) {                
        for ( int i = 0; i < grille.length; i++) {                // Boucle imbriqué : Pour CHAQUE ligne de la grille.
            for ( int j = 0; j < grille[i].length; j++) {        // On incrémente, pour CHAQUE colonne de la ligne en question
                grille[i][j]=VIDE;                                // La valeur VIDE, soit 0.
            }
        }
    }
    
    // Ici, on affiche la grille. ( notamment à chaque tour de jeu ).
    public static void affiche(int[][] grille) {
        for ( int[] ligne : grille) {                // Boucle imbriqué : Pour CHAQUE ligne de la grille
            for (int cellule : ligne) {                // On incrémente, pour CHAQUE case de la ligne en question :                
                if (cellule==VIDE)                    // Si la case en question est vide :
                    System.out.print("|_");            // En caractère, on lui incrémente une case vide si contient VIDE (0).
                else if (cellule==ROUGE)            // Si la case en question contient un pion ROUGE(2):
                    System.out.print("|O");            // En caractère, on lui incrémente un pion ROUGE(2)
                else System.out.print("|X");        // Sinon, dernier cas : Pion JAUNE(1).
            }
            System.out.println();
        }
        System.out.println(" 1-2-3-4-5-6-7");
    }
    
    public static boolean joue(int[][] grille, int colonne, int couleur) {                // Dans la grille, ou jouer (colonne) ? Et qui joue (ROUGE(2) ou JAUNE(1) ) ?
        // Il faut vérifier si la colonne ou le joueur souhaite rentrer son pion soit valide:
        if ( colonne >= grille[0].length)
            return false;
        // On parcourt la colonne qu'à choisit le joueur en partant du bas jusqu'à trouver une case vide ( dans laquel se mettra le pion ). 
        int ligne = grille.length-1;                                                 // La ligne tout en bas, c'est la ligne de départ.
        boolean pleine = false;                                                        // False quand la colonne n'est pas pleine ( remplit ), true quand elle l'est.
        while ((!pleine) && (grille[ligne][colonne]!=VIDE))                    // Tant que la colonne n'est pas pleine et que la ligne de la colonne souhaité n'est pas vide:
            if (ligne==0)                                                        //Cad que si on arrive à la première ligne du haut, ça veut dire que la colonne est pleine:
                pleine=true;                                                        // On met donc true à pleine
            else --ligne;                             // Sinon, si on est pas encore arrivé à la premirèe ligne du haut, on peux se permettre de monter de ligne, de un en un.
        // Une fois qu'une case vide est trouvé, on la remplit avec la couleur simplement:
        if (!pleine) {                                                                        // Si la colonne n'est pas pleine, alors:
            grille[ligne][colonne]=couleur;                                                    // On peut se permettre de la remplir avec un pion.
            return true;                                                                    // On return true pour indiquer qu'on a bien pu jouer.
        }
        else return false;                                                                    // Sinon on return false, le coup n'était pas valide.
    }
    
    public static void demandeEtJoue(int[][] grille, int couleurJoueur) {
        boolean valide;            // On déclare un boolean valide, qui indiquera si le coup est valide ou pas valide.
        do {
            if (couleurJoueur == JAUNE)        // Ici, en fonciton de si c'est ROUGE ou JAUNE, le symbole change (X ou 0) et on leur demande de jouer.
                System.out.println("Joueur X : Choisissez une colonne.");
            else System.out.println("Joueur 0 : Choisissez une colonne.");
            
            int colonne = Integer.parseInt(saisie.nextLine()); // On récupère le choix du joueur ( la colonne choisit ) mais ... 
            // Comme il y a une différence de 1 entre le numéro de la colonne vue par l'humain, et le numéro de la colonne vue par le language JAVA, il faut enlever 1.
            colonne--;
            valide = joue(grille, colonne, couleurJoueur);         // Via la fonction joue, on regarde si le coup est valide ou non.
            if (!valide)                // Si le coup n'est pas valide, bah on le fait savoir, sinon si le coup est valide, tant mieux.
                System.out.println("Coup non valide");
        } while(!valide);                                // Il faut refaire tant que le coup n'est pas valide ! Il faut bien qu'il façe un coup tout de même !
    }
    
    // Ici, on regarde si la grille est pleine:
    public static boolean plein(int[][] grille) {
        // Si on trouve une case vide sur la premlière ligne du haut, cela signifie que la grille n'est pas pleine:
        for (int caze : grille[0]) {        // grille[0} étant la première ligne du haut.
            if (caze==VIDE)                // Si la case est vide
                return false;            // Alors il est faux de dire que la grille est pleine, donc on return false.
        }
        return true;    // Si le programme arrive jusqu'ici, c'est qu'il a trouvé aucun case vide de la première du ligne du haut vide, donc la grille est pleine. True.
    }
    
    // Ici, on regarde si le joueur à gagné via des parcours de la grille et un comptage de pion aligné (4 pour gagner)
    public static boolean estCeGagne(int[][] grille, int couleurJoueur) {
        for (int ligne = 0; ligne < grille.length; ligne++) {                    // Pour chaque ligne de la grille;
            for ( int colonne = 0; colonne<grille[ligne].length; colonne++) {        // Pour chaque colonne de la ligne en question : 
                int couleurCase=grille[ligne][colonne];                         // Cette variable sert à stocker quelque part la couleur de la case sur laquel on est.
                if (couleurCase==couleurJoueur) {                        // Si on tombe sur une case comportant un pion du joueur en question, il faut maintenant compter:
                    if (
                    // en diagonale, vers le haut et la droite:
                    (ligne >= 4 && colonne <= grille[ligne].length-4 && compte(grille, ligne, colonne, -1, +1)>=4)    ||    // -1 ( parce qu'on veut monter d'une ligne ! (on monte les lignes  en soustraction, +1 ( parce qu'on veut aller à droite ) Ce qui donne haut-droit.
                    // horizontalement, vers la droite:                    
                    (colonne <= grille[ligne].length-4 && compte(grille, ligne, colonne, 0, +1)>=4)    ||        // 0 ( on ne change pas de ligne ) et +1 pour aller à droite.
                    // en diagonale, vers le bas et la droite:
                    (ligne <= grille.length-4 && colonne <= grille[ligne].length-4 && compte(grille, ligne, colonne, +1, +1)>=4) ||        // +1 ( on descend d'une ligne ) +1 ( pour aller à droite ).
                    // verticalement, vers le bas:
                    (ligne <= grille.length-4 && compte(grille, ligne, colonne, +1, 0)>=4)) {        // +1 ( on descend d'une ligne ) 0 ( on ne change pas de colonne ).
                        return true;
                    }
                }
            }
        }
        // Si on a parcouru toute la grille sans trouver au moins 4 pions
        // alignes, le joueur n'a pas gagne, du moins pas encore.
        return false;
    }
    
    // Ici, on compte le nombre de pions alignés:
    public static int compte (int[][] grille, int ligneDepart, int colonneDepart, int dirLigne, int dirColonne) {
        int compteur=0;
        int ligne=ligneDepart;
        int colonne=colonneDepart;
        
        // on part de la case (ligneDepart, colonneDepart) et on parcourt la grille dans la direction donnée par (dirLigne, dirColonne)
        // tant qu'on trouve des pions de la même couleur que le pion de depart.
        while (grille[ligne][colonne]==grille[ligneDepart][colonneDepart] && ligne>=0 && ligne < grille.length && colonne >=0 && colonne<grille[ligne].length) {
            compteur++;
            ligne+=dirLigne;
            colonne+=dirColonne;
        }
        return compteur;
    }
}

Alors le problème c'est que ça me met erreur lorsque je tente d'aligner 4 pions ainsi : ( tout les autres cas fonctionnent )


J'ai relus et relus la logique de mes méthodes/fonctions, mais je ne vois pas ou est le problème.

Merci beaucoup
A voir également:

1 réponse

KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
7 janv. 2018 à 23:30
Bonjour,

Quand Java plante, il t'indique précisément où est l'erreur, ce qui te permet de corriger le problème.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
	at P4.compte(P4.java:147)
	at P4.estCeGagne(P4.java:128)
	at P4.main(P4.java:27)

À la ligne 147, tu as :
while (grille[ligne][colonne]==grille[ligneDepart][colonneDepart] && ligne>=0 && ligne < grille.length && colonne >=0 && colonne<grille[ligne].length) {


Or Java lit les conditions de gauche à droite, et il plante à
grille[ligne][colonne]
quand
ligne 
vaut 6. Pourtant la condition
ligne < grille.length
aurait pu lui dire de s'arrêter, mais elle est après, donc trop tard.

Il faudrait mettre les conditions dans le bon ordre :
while (ligne>=0 && ligne < grille.length && colonne >=0 && colonne<grille[ligne].length && grille[ligne][colonne]==grille[ligneDepart][colonneDepart]) {


Remarque : je n'ai testé que le cas suivant.
|_|_|_|_|_|_|_
|_|_|_|_|_|_|_
|X|_|_|_|_|_|_
|X|O|_|_|_|_|_
|X|O|_|_|_|_|_
|X|O|_|_|_|_|_
1-2-3-4-5-6-7
Le joueur X à gagné !
0