package projet; import projet.Case; import projet.Cavalier; import projet.Deplacement; import projet.Fou; import projet.Piece; import projet.Pion; import projet.Reine; import projet.Roi; import projet.Tour; public class Echiquier { // plateau contenant les cases qui contienne les Pieces private Case[][] plateau; // construteur qui cree un plateau de 8x8, initialiser sans les pieces, donc vide public Echiquier() { plateau = new Case[8][8]; for (int ctr = 0; ctr <= 7; ctr++) for (int ctr1 = 0; ctr1 <= 7; ctr1++) plateau[ctr][ctr1] = new Case(); } //cette methode va permettre si la capture par un pion d'une piece sera possible, c'est a dire que le pion se trouve a la diagonale d'une case de la piece adverse en question public boolean captureParUnPionPossible(Deplacement deplacement) { //Je verifie si la piece est un pion if(plateau[deplacement.getDepart().getColonne()][deplacement.getDepart().getLigne()].getPiece() instanceof Pion) { //initialisation des variables, et savoir la couleur de la piece de depart et la case d'arrive. Case Arrive = plateau[(int)deplacement.getArrivee().getColonne()][(int)deplacement.getArrivee().getLigne()]; Couleur couleurDepart = plateau[(int)deplacement.getDepart().getColonne()][(int)deplacement.getDepart().getLigne()].getPiece().getCouleur(); //je verifie d'abord si la piece d'arrive existe et si elle est de la couleur contraire de celle de depart. if(Arrive.estOccupe(couleurDepart.couleurAdverse())) //on verifie si le deplacement est valide par le produit du deplacement des ordonner et absices et si cela fait 1 pour les noir ou -1 pour les blanc cela sera accepter return (deplacement.getDeplacementY() * Math.abs(deplacement.getDeplacementX()) == (couleurDepart==Couleur.noir ? 1 : -1)); } return false; } //methode qui permet de voire si le chemin de la piece a deplacer est libre public boolean cheminPossible(Deplacement deplacement) { Piece pieceDepart = plateau[(int)deplacement.getDepart().getColonne()][(int)deplacement.getDepart().getLigne()].getPiece(); //deux premieres conditions fondamentales, que la case d'arrivee sois libre ou qu'elle posseede une piece de couleur contraire a celle de la piece de depart if (!plateau[(int)deplacement.getArrivee().getColonne()][(int)deplacement.getArrivee().getLigne()].estOccupe(pieceDepart.getCouleur()) | deplacement.isNul()){ if (!(pieceDepart instanceof Cavalier)){ if(!(pieceDepart instanceof Pion)){ // cas spécial du roque if ( pieceDepart instanceof Roi ) { if (!pieceDepart.aDejaEteDeplaceUneFois() && Math.abs(deplacement.getDeplacementX())==2 ) { // on est entrain de tester si un roque est possible (on est sur le cas d'un déplacement de 2 cases) // on détermine la position de la tour int xtour; if( deplacement.getDeplacementX()<0 ) { // déplacement vers la gauche = grand roque = roque avec la tour gauche (vue des blancs) xtour=0; } else { // déplacement vers la droite = petit roque = roque avec la tour droite (vue des blancs) xtour=7; } Position positionTour=new Position(xtour, deplacement.getDepart().getLigne()); Piece piece = plateau[positionTour.getColonne()][positionTour.getLigne()].getPiece(); if ( piece instanceof Tour && !piece.aDejaEteDeplaceUneFois() ) { // dans le cas contraire le roque n'est pas possible // on simule un déplacement pour pouvoir utiliser la méthode de controle du roque Deplacement roque = new Deplacement(deplacement.getDepart(),positionTour); if ( isRoquePossible(roque) ) { // cette configuration autorise le roque // le déplacement est valide return true; } } return false; // dans tous les autres cas un déplacement de 2 cases du roi est bien entendu interdit } } //Je verifie que le deplacement est superieur a un. //instanceof permet permet de connaitre le type d'une variable if(!(Math.abs(deplacement.getDeplacementX()) - Math.abs(deplacement.getDeplacementY()) <= 1 && Math.abs(deplacement.getDeplacementX()) + Math.abs(deplacement.getDeplacementY()) <= 1)){ //JumpX et jumpY seront sois 0, 1 ou -1, ils indiquent l'incrementation que je devrai utiliser pour les valeurs X et Y pour verifier toute les cases entre le depart et l'arrivee int jumpX = deplacement.getDeplacementX() == 0 ? 0 : (int)(deplacement.getArrivee().getColonne() - deplacement.getDepart().getColonne()) /Math.abs((int)(deplacement.getArrivee().getColonne() - deplacement.getDepart().getColonne())); int jumpY = deplacement.getDeplacementY() == 0 ? 0 : (int)(deplacement.getArrivee().getLigne() - deplacement.getDepart().getLigne()) /Math.abs((int)(deplacement.getArrivee().getLigne() - deplacement.getDepart().getLigne())); //Je verifie succicessivement toutes les cases entre l'arrivee et le depart for (int ctrX = (int)deplacement.getDepart().getColonne() + jumpX, ctrY = (int)deplacement.getDepart().getLigne() + jumpY; ctrX != (int)deplacement.getArrivee().getColonne() | ctrY != (int)deplacement.getArrivee().getLigne(); ctrX += jumpX, ctrY += jumpY){ if (plateau[ctrX][ctrY].estOccupe()){ return false; } } return true; } else // Si le deplacement est egal il est automatiquement valide car il a passee les preecedents test. Puisque le deplacement est de 1, on a pas besoin de verifier les cases entre le depart et l'arrivee return true; } else { //Si c'est un pion, je verifie si la case est libre de toute piece. if ( !pieceDepart.aDejaEteDeplaceUneFois() ) { // si le pion n'a pas été déplacé, il peut avancer de 1 ou 2 case // donc on teste si la case devant lui est occupée int depY= (int) Math.signum(deplacement.getDeplacementY()); // on détermine le sens de déplacement (différent selon la couleur) if ( plateau[deplacement.getDepart().getColonne()][deplacement.getDepart().getLigne()+depY].estOccupe() ) { // si la case est occupée le pion ne peut pas avancer return false; } } // sinon on teste la case d'arrivée return !plateau[(int)deplacement.getArrivee().getColonne()][(int)deplacement.getArrivee().getLigne()].estOccupe(); } } else //je renvoie true car un cavalier peut sauter par dessus les autres pieces. return true; } else //Le deplacement est automatiquement invalide si la case d'arrive contient une piece de meme couleur que la piece de depart. return false; } public Case getCase(Position position) { return getCase(position.getColonne(),position.getLigne()); } public Case getCase(int colonne, int ligne) { return plateau[colonne][ligne]; } //place les pieces au debut public void debuter() { // effacement de l'echiquier vide(); // placement des pièces int ligne = 7; for (Couleur couleur : Couleur.values() ){ //J'initialise tout mes pieces de la premieres rangee (tour, cavalier etc...) plateau[0][ligne].setPiece(new Tour(couleur)); plateau[1][ligne].setPiece(new Cavalier(couleur)); plateau[2][ligne].setPiece(new Fou(couleur)); plateau[3][ligne].setPiece(new Reine(couleur)); plateau[4][ligne].setPiece(new Roi(couleur)); plateau[5][ligne].setPiece(new Fou(couleur)); plateau[6][ligne].setPiece(new Cavalier(couleur)); plateau[7][ligne].setPiece(new Tour(couleur)); //Je change de ligne int lignepion = ligne + (couleur==Couleur.blanc ? -1 : 1); //J'initialise tout mes pions. for (int colonne = 0; colonne <= 7; colonne++) plateau[colonne][lignepion].setPiece(new Pion(couleur)); ligne = 0; } } public void vide() { for(int colonne=0;colonne<8;colonne++) { for(int ligne=0;ligne<8;ligne++) { plateau[colonne][ligne].setPiece(null); } } } public boolean isRoquePossible(Deplacement deplacement) { return isPetitRoquePossible(deplacement) || isGrandRoquePossible(deplacement); } public boolean isGrandRoquePossible(Deplacement deplacement) { return isRoquePossible(deplacement,true); } public boolean isPetitRoquePossible(Deplacement deplacement) { return isRoquePossible(deplacement,false); } private boolean isRoquePossible(Deplacement deplacement, boolean grand) { Piece pieceDeDepart = getCase(deplacement.getDepart().getColonne(),deplacement.getDepart().getLigne()).getPiece(); Piece pieceDArrivee = getCase(deplacement.getArrivee().getColonne(),deplacement.getArrivee().getLigne()).getPiece(); if ( pieceDeDepart instanceof Roi && pieceDArrivee instanceof Tour ) { // les deux pièces doivent être de la même couleur if ( pieceDeDepart.getCouleur().equals(pieceDArrivee.getCouleur() ) ) { // aucune des deux pièces ne doit pas avoir bouger if ( !pieceDeDepart.aDejaEteDeplaceUneFois() && !pieceDArrivee.aDejaEteDeplaceUneFois() ) { // distance horizontale int distance = Math.abs(deplacement.getDepart().getColonne()-deplacement.getArrivee().getColonne()); if ( (distance==4 && grand) || (distance==3 && !grand) ) { // toutes les cases doivent être innocupées int ligneroque = deplacement.getDepart().getLigne(); // on pourrait utiliser la couleur de la pièce aussi // le grand roque va de 0 à 4 (donc les cases entre les deux sont 1,2,3 // le petit roque va de 4 à 7 (donc les cases entre les deux sont 5,6 int cased = grand?1:5; int casef = grand?3:6; for(int col=cased; col<=casef; col++) { if ( getCase(col, ligneroque).estOccupe() ) { return false; // case occupee roque impossible } } // on doit vérifier si les cases sont menacées // donc occupée par la couleur adverse... Couleur couleurAdverse = pieceDeDepart.getCouleur().couleurAdverse(); // ...est qui controle une des cases cased--; casef++; // on inclut les cases avec le roi et la tour int prisepion=couleurAdverse==Couleur.noir ? 1 : -1; // on précalcul cette valeur, parce qu'on va en avoir besoin plusieurs fois for(int col=cased; col<=casef; col++) { // on va simuler un déplacement avec toutes les cases adverses Position positionATester = new Position(col,ligneroque); for (int ligne = 0; ligne < 8; ligne++) { for (int colonne = 0; colonne < 8; colonne++) { if ( getCase(colonne, ligne).estOccupe(couleurAdverse) ) { Deplacement simuleDeplacement = new Deplacement(new Position(colonne, ligne), positionATester); if ( getCase(colonne, ligne).getPiece().estValide(simuleDeplacement) && cheminPossible(simuleDeplacement) ) { // la pièce peut se déplacer, la case est menacé return false; // le roque n'est pas possible } else if ( (simuleDeplacement.getDeplacementY() * Math.abs(simuleDeplacement.getDeplacementX()) == prisepion) ) { // le cas de la prise par le pion est traitée à part // et on ne peut pas utiliser la méthode captureParUnPionPossible(simuleDeplacement) car elle ne retourne true que si la case est occupée // on a simplement reprise la formule utilisée dans cette méthode (on pourrait faire une méthode spéciale pour ce calcul) return false; // le roque n'est pas possible } } } } } return true; } } } } /* ici on pourrait indiquer si le roque est possible par la tour else if (pieceDeDepart instance Tour && pieceDArrivee instanceof Roi) { ... } */ return false; } public boolean prisePionEnPassant(Deplacement deplacement, boolean affichage) { // Je verifie si la piece est un pion if (plateau[deplacement.getDepart().getColonne()][deplacement .getDepart().getLigne()].getPiece() instanceof Pion) { // on a besoin du dernier coup joué Partie.Coup dernierCoupJoue = Partie.getDernierCoupJoue(); if (dernierCoupJoue != null) { // si le coup est null, c'est le tout premier coup de la partie if (dernierCoupJoue.getPieceJouee() instanceof Pion) { // si le dernier coup joué l'était par un pion if (deplacement.getDeplacementY() == (dernierCoupJoue.getCouleur()==Couleur.noir ? -1 : 1)) { // et que le déplacement testé est une case en avant if (Math.abs(dernierCoupJoue.getDepart().getLigne() - dernierCoupJoue.getArrivee().getLigne()) == 2) { // et que le coup d'avant le pion s'est déplacé de 2 cases if (Math.abs(dernierCoupJoue.getArrivee() .getColonne() - deplacement.getArrivee().getColonne()) == 0) { // et que le déplacement testé arrive sur la colonne du pion du dernier coup joué if (dernierCoupJoue.getArrivee().getLigne() == deplacement .getDepart().getLigne()) { // et que les deux pions sont actuellement sur la même ligne return true; } } } } } } } return false; } /** * cherche la position de la case qui contient la pièce de classe et couleur spécifiée */ public Position getPosition(Class classPiece, Couleur couleur) { return getPosition(classPiece, couleur, 0); } /** * cherche la position de la case qui contient la pièce de classe et couleur spécifiée en position index (0 pour la première, 1 pour la deuxième, etc...) */ public Position getPosition(Class classPiece, Couleur couleur, int index) { for (int colonne = 0; colonne < 8; colonne++) for (int ligne = 0; ligne < 8; ligne++) if ( plateau[colonne][ligne].estOccupe(couleur) && classPiece.isInstance(plateau[colonne][ligne].getPiece())) { if (index<=0) return new Position(colonne,ligne); else index--; } return null; // on renvoit null si on ne trouve aucune pièce qui correspond aux critères spécifiés } public Echiquier copy() { Echiquier echiquier = new Echiquier(); for (int colonne = 0; colonne < 8; colonne++) for (int ligne = 0; ligne < 8; ligne++) echiquier.getCase(colonne, ligne).setPiece(getCase(colonne, ligne).getPiece()); return echiquier; } }