package echiquier.plateau;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import echiquier.outils.Couleur;
import echiquier.outils.DeplacementEtat;
import echiquier.outils.Outils;
import echiquier.outils.Position;
import echiquier.pieces.Cavalier;
import echiquier.pieces.Fou;
import echiquier.pieces.Piece;
import echiquier.pieces.Pion;
import echiquier.pieces.Reine;
import echiquier.pieces.Roi;
import echiquier.pieces.Tour;
/**
* Classe représentant un échiquier. Il est le seul à connaitre la position des
* pièces
*
* @author Baptiste BOUCHEREAU <baptiste.bouchereau@cpe.fr>
* @author Eric GILLET <eric.gillet@cpe.fr>
*/
public class Echiquier {
private HashMap<Position, Piece> plateau;
private ArrayList<Piece> piecesNoires = new ArrayList<Piece>();
private ArrayList<Piece> piecesBlanches = new ArrayList<Piece>();
private List<Mouvement> historique;
public Echiquier() {
historique = new ArrayList<Mouvement>();
this.initPlateau();
}
/**
* Récupère la position du roi de la couleur correspondante
*
* @param Couleur
* c
* @return Roi roi
*/
public Position getRoiPosition(Couleur c) {
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
if (plateau.get(new Position(i, j)) != null
&& plateau.get(new Position(i, j)).getClass()
.getSimpleName().equals("Roi")
&& plateau.get(new Position(i, j)).getCouleur() == c) {
// System.out.println("Roi : "+new
// Position(i,j)+" "+c.toString());
return new Position(i, j);
}
}
}
return null;
}
/**
* Récupère la pièce à la position envoyée en paramètre. S'il n'y en a pas
* retourne la valeur null.
*
* @param Position
* position
* @return Piece piece
*/
public Piece getPieceAt(Position p) {
return plateau.get(p);
}
/**
* Récupère la position de la pièce envoyée en paramètre. S'il n'y en a pas
* retourne la valeur null.
*
* @param Piece
* piece
* @return Position position
*/
public Position getPiecePosition(Piece p) {
for (Position position : plateau.keySet()) {
if (plateau.get(position) != null
&& plateau.get(position).equals(p))
return position;
}
return null;
}
/**
* Vérifie qu'il n'y a pas une piece de la même couleur sur l'échiquier que
* celle envoyée en paramètre à la position indiquée.
*
* @param Position
* position
* @param Piece
* piece
* @return boolean
*/
public boolean estDeMemeCouleur(Position position, Piece piece) {
Piece piecePlacee = plateau.get(position);
if (piecePlacee == null) {
return false;
} else {
if (piecePlacee.getCouleur() == piece.getCouleur())
return true;
else
return false;
}
}
/**
* Vérifie s'il y a echec au roi ou non en fonction d'un déplacement.
*
* @param position
* @param piece
* @return
*/
public boolean roiEstEnDanger(Position pRoi) {
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
Piece piece = plateau.get(new Position(i, j));
if (piece != null
&& piece.getCouleur() != getPieceAt(pRoi).getCouleur()
&& getDeplacementEtat(getPiecePosition(piece), pRoi) == DeplacementEtat.SUCCES) {
return true;
}
}
}
return false;
}
/**
* Récupère l'état (résultat) d'un déplacement après test
*
* @param Position
* pi: position initiale
* @param Position
* pf: position finale
* @param Piece
* piece: la piece à deplacer
* @return DeplacementEtat etat: l'état du déplacement
*/
public DeplacementEtat getDeplacementEtat(Position pi, Position pf) {
Piece pieceInit = getPieceAt(pi);
if (pieceInit == null) {
return DeplacementEtat.PASDEPIECE;
}
if (!Outils.isInTheTableau(pf)) {
return DeplacementEtat.HORSDUPLATEAU;
}
if (!pieceInit.deplacementCorrect(pi, pf, pieceInit.getCouleur())) {
return DeplacementEtat.INCORRECT;
}
if (this.estDeMemeCouleur(pf, pieceInit)) {
return DeplacementEtat.DEJAOCCUPE;
}
Position before = this.getPiecePosition(pieceInit);
while (!before.equals(pf)) {
Position nextPosition = pieceInit.next(before, pf,
pieceInit.getCouleur());
if (!nextPosition.equals(pf) && getPieceAt(nextPosition) != null) {
return DeplacementEtat.COLLISION;
}
before = pieceInit.next(before, pf, pieceInit.getCouleur());
}
/***********************
* Cas spécial du pion *
* *********************/
if (pieceInit instanceof Pion) {
if (Outils.isDeplacementDiagonal(pi, pf)) {
if (getPieceAt(pf) == null)
return DeplacementEtat.INCORRECT;
} else if (getPieceAt(pf) != null)
return DeplacementEtat.INCORRECT;
}
/***************************
* Test de l'échec au roi *
***************************/
// Enregistrement des positions
Piece pieceF = getPieceAt(pf);
// simulation du déplacement
Piece pieceATester = pieceInit;
plateau.put(pf, pieceATester);
plateau.remove(pi);
if (roiEstEnDanger(getRoiPosition(pieceInit.getCouleur()))) {
// On remet comme avant quelque soit le résultat car la fonction
// "deplacer" est appelé après
plateau.put(pi, pieceInit);
plateau.put(pf, pieceF);
return DeplacementEtat.ECHECAUROI;
}
// Déplacement possible
// On remet comme avant quelque soit le résultat car la fonction
// "deplacer" est appelée après
plateau.put(pi, pieceInit);
plateau.put(pf, pieceF);
return DeplacementEtat.SUCCES;
}
/**
* Déplace réellement une pièce (après test)
*
* @param Position
* pi: position initiale
* @param Position
* pf: position finale
*/
@SuppressWarnings("unchecked")
public DeplacementEtat deplacer(Position pi, Position pf) {
Piece pieceF = getPieceAt(pf);
Piece pieceI = getPieceAt(pi);
System.out
.println("Déplacement du " + pieceI.getClass().getSimpleName()
+ " " + pieceI.getCouleur());
// si une piece est mangée on la met dans une liste
if (pieceF != null) {
if (pieceF.getCouleur() == Couleur.BLANC)
piecesBlanches.add(pieceF);
else
piecesNoires.add(pieceF);
}
//On effectue la permutation en reine s'il s'agit d'un pion en bout de course
if (pieceI.getClass().getSimpleName().equals("Pion")) {
if(pf.getY() == 0 && pieceI.getCouleur() == Couleur.NOIR) {
pieceI = new Reine(Couleur.NOIR);
}
if(pf.getY() == 7 && pieceI.getCouleur() == Couleur.BLANC) {
pieceI = new Reine(Couleur.BLANC);
}
}
plateau.put(pf, pieceI);
plateau.remove(pi);
historique.add(new Mouvement(pi, pf));
/**************************
* Test de l'échec et mat *
**************************/
// on vérifie que le déplacement met le roi adverse en danger
Couleur couleurEnnemie = Outils.getCouleurOppose(pieceI);
if (roiEstEnDanger(getRoiPosition(couleurEnnemie))) {
// on verifie qu'en deplacant n'importe lequel de ses pion
// l'adversaire est toujours en danger
HashMap<Position, Piece> plateauTest = new HashMap<Position, Piece>(
plateau);
for (Piece piece : plateauTest.values()) {
if (piece != null && piece.getCouleur() == couleurEnnemie) {
System.out.println(piece.getClass().getSimpleName());
// on parcours tout le plateau et on simule les déplacements
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
Position posF = new Position(i, j);
Position posI = getPiecePosition(piece);
if (getDeplacementEtat(posI, posF) == DeplacementEtat.SUCCES) {
// simulation du déplacement
plateau.put(posF, piece);
plateau.remove(posI);
if (!roiEstEnDanger(getRoiPosition(couleurEnnemie))) {
plateau = (HashMap<Position, Piece>) plateauTest
.clone();
if (pieceF != null) {
return DeplacementEtat.MANGE;
}
return DeplacementEtat.SUCCES;
}
plateau = (HashMap<Position, Piece>) plateauTest
.clone();
}
}
}
}
}
return DeplacementEtat.ECHECETMAT;
}
if (pieceF != null) {
return DeplacementEtat.MANGE;
}
return DeplacementEtat.SUCCES;
}
public HashMap<Position, Piece> getPlateau() {
return plateau;
}
public void setPlateau(HashMap<Position, Piece> plateau) {
this.plateau = plateau;
}
public void deplacer(Mouvement m) {
deplacer(m.getPI(), m.getPF());
}
/**
* Initialise l'échiquier (pose les pièces)
*/
public void initPlateau() {
historique.clear();
plateau = new HashMap<Position, Piece>();
for (int i = 0; i < 8; ++i) {
plateau.put(new Position(i, 1), new Pion(Couleur.BLANC));
plateau.put(new Position(i, 6), new Pion(Couleur.NOIR));
}
plateau.put(new Position(0, 0), new Tour(Couleur.BLANC));
plateau.put(new Position(7, 0), new Tour(Couleur.BLANC));
plateau.put(new Position(0, 7), new Tour(Couleur.NOIR));
plateau.put(new Position(7, 7), new Tour(Couleur.NOIR));
plateau.put(new Position(1, 0), new Cavalier(Couleur.BLANC));
plateau.put(new Position(6, 0), new Cavalier(Couleur.BLANC));
plateau.put(new Position(1, 7), new Cavalier(Couleur.NOIR));
plateau.put(new Position(6, 7), new Cavalier(Couleur.NOIR));
plateau.put(new Position(2, 0), new Fou(Couleur.BLANC));
plateau.put(new Position(5, 0), new Fou(Couleur.BLANC));
plateau.put(new Position(2, 7), new Fou(Couleur.NOIR));
plateau.put(new Position(5, 7), new Fou(Couleur.NOIR));
plateau.put(new Position(3, 0), new Roi(Couleur.BLANC));
plateau.put(new Position(3, 7), new Roi(Couleur.NOIR));
plateau.put(new Position(4, 0), new Reine(Couleur.BLANC));
plateau.put(new Position(4, 7), new Reine(Couleur.NOIR));
}
/**
* Affiche l'échiquier
*/
public void afficheTableau() {
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
System.out.print(j == 0 && i != 8 ? "|" : "");
if (plateau.get(new Position(j, i)) != null) {
System.out.print(plateau.get(new Position(j, i)).getClass()
.getSimpleName().substring(0, 2)
+ plateau.get(new Position(j, i)).getCouleur()
.toString().substring(0, 1) + "|");
} else {
System.out.print(" |");
}
}
System.out.println(" ");
System.out.println("---------------------------------");
}
}
public List<Mouvement> getHistorique() {
return historique;
}
}