/** * IsMateDetected() * * Détecte l'absence ou la présence d'un échec sur le plateau * En cas d'échec, les coordonnées des pièces menaçant le roi d'une couleur sont stockées dans une liste initialisée dans le constructeur * Cette liste est vidée à chaque début d'exécution de la fonction * * @return bool * true si échec * false si absence d'échec * * @author Axel Floquet-Trillot * */ private bool IsMateDetected() { Coordinates WhiteKing = King.locateKing(GameBoard, Piece.Color.White); Coordinates BlackKing = King.locateKing(GameBoard, Piece.Color.Black); WhiteMateThreats.Clear(); BlackMateThreats.Clear(); //Exception levée si un des rois n'est pas trouvé if (WhiteKing == null || BlackKing == null) { throw (new Exception("Un des rois n'a pas pu être trouvé")); } //Double boucle pour parcourir chaque case du plateau for (int x = 0; x < GameBoard.GetLength(0); x++) { for (int y = 0; y < GameBoard.GetLength(1); y++) { if (GameBoard[x, y] != null) { //Détection des pièces pouvant manger le roi List <Coordinates> PossibleMovesOfCurrentPiece = GameBoard[x, y].GetPossibleMoves(GameBoard, new Coordinates(x, y)); foreach (Coordinates Coord in PossibleMovesOfCurrentPiece) { if (Coord.X == WhiteKing.X && Coord.Y == WhiteKing.Y && GameBoard[x, y].PieceColor == Piece.Color.Black) { WhiteMateThreats.Add(new Coordinates(x, y)); } if (Coord.X == BlackKing.X && Coord.Y == BlackKing.Y && GameBoard[x, y].PieceColor == Piece.Color.White) { BlackMateThreats.Add(new Coordinates(x, y)); } } } } } //Si une des deux liste contient un élement, renvoie true if (WhiteMateThreats.Count() > 0 || BlackMateThreats.Count() > 0) { return(true); } else { return(false); } }
/** * VirtualMoveAndMateTest(Origin, Destinations) * * Effectue un mouvement fictif et détecte si ce mouvement provoque un échec, sans impacter le GameBoard principal * * @return bool * true si échec détecté * false si mouvement sans échec provoqué * * @author Axel Floquet-Trillot * */ private bool VirtualMoveAndMateTest(Coordinates Origin, Coordinates Destination) { bool MateDetected = false; //Mouvement demandé effetcué sur une copie de l'échiquier Piece [,] GameBoardCopy = MakeCopyOfGameBoard(); GameBoardCopy[Destination.X, Destination.Y] = GameBoardCopy[Origin.X, Origin.Y]; GameBoardCopy[Origin.X, Origin.Y] = null; Coordinates WhiteKing = King.locateKing(GameBoardCopy, Piece.Color.White); Coordinates BlackKing = King.locateKing(GameBoardCopy, Piece.Color.Black); //Exception levée si un des rois n'est pas trouvé if (WhiteKing == null || BlackKing == null) { throw (new Exception("Un des rois n'a pas pu être trouvé")); } for (int x = 0; x < GameBoardCopy.GetLength(0); x++) { for (int y = 0; y < GameBoardCopy.GetLength(1); y++) { if (GameBoardCopy[x, y] != null) { //Détection des pièces pouvant manger le roi avec le mouvement demandé List <Coordinates> PossibleMovesOfCurrentPiece = GameBoardCopy[x, y].GetPossibleMoves(GameBoardCopy, new Coordinates(x, y)); foreach (Coordinates Coord in PossibleMovesOfCurrentPiece) { if (PlayingNow == Piece.Color.White && Coord.X == WhiteKing.X && Coord.Y == WhiteKing.Y && GameBoardCopy[x, y].PieceColor == Piece.Color.Black) { MateDetected = true; } if (PlayingNow == Piece.Color.Black && Coord.X == BlackKing.X && Coord.Y == BlackKing.Y && GameBoardCopy[x, y].PieceColor == Piece.Color.White) { MateDetected = true; } } } } } return(MateDetected); }
/** * FindPiecesCoordinatesAndMovesToProtectMyKing() * * Analyse la totalité du plateau afin de trouver toutes les pièces et leur déplacement(s) associé(s) permettant de protéger le roi en cas d'échec * * @return List<Coordinates>[] * FindPiecesCoordinatesAndMovesToProtectMyKing()[0] permet de récupérer les pièces pouvant protéger un roi * FindPiecesCoordinatesAndMovesToProtectMyKing()[1] permet de récupérer les déplacements pouvant protéger un roi * * @author Axel Floquet-Trillot * */ private List <Coordinates>[] FindPiecesCoordinatesAndMovesToProtectMyKing() { Coordinates MyKing; List <Coordinates> MateThreat = new List <Coordinates>(); List <Coordinates> PiecesCoordinatesToProtectMyKing = new List <Coordinates>(); List <Coordinates> MatePossibleMoves = new List <Coordinates>(); if (PlayingNow == Piece.Color.White) { MyKing = King.locateKing(GameBoard, Piece.Color.White); MateThreat = WhiteMateThreats; } else { MyKing = King.locateKing(GameBoard, Piece.Color.Black); MateThreat = BlackMateThreats; } //Exception levée si un des rois n'est pas trouvé if (MyKing == null) { throw (new Exception("Un des rois n'a pas pu être trouvé")); } //Recherche des pièces pouvant protéger le roi if (MateThreat.Count() > 0 && PlayingNow == GameBoard[MyKing.X, MyKing.Y].PieceColor) { foreach (Coordinates Threat in MateThreat) { for (int x = 0; x < GameBoard.GetLength(0); x++) { for (int y = 0; y < GameBoard.GetLength(1); y++) { if (GameBoard[x, y] != null && GameBoard[x, y].PieceColor == PlayingNow) { foreach (Coordinates Coord in GameBoard[x, y].GetPossibleMoves(GameBoard, new Coordinates(x, y))) { if (!GameBoard[x, y].Equals(GameBoard[MyKing.X, MyKing.Y])) { //Si la menace peut être mangée if (Coord.X == Threat.X && Coord.Y == Threat.Y) { PiecesCoordinatesToProtectMyKing.Add(new Coordinates(x, y)); MatePossibleMoves.Add(new Coordinates(Coord.X, Coord.Y)); } //Si une pièce peut s'interposer entre le roi et la menace sur la même ligne if (Threat.X == MyKing.X && Threat.X == Coord.X && ((Coord.Y > MyKing.Y && Coord.Y < Threat.Y) || (Coord.Y < MyKing.Y && Coord.Y > Threat.Y))) { PiecesCoordinatesToProtectMyKing.Add(new Coordinates(x, y)); MatePossibleMoves.Add(new Coordinates(Coord.X, Coord.Y)); } //Si une pièce peut s'interposer entre le roi et la menace sur la même colonne if (Threat.Y == MyKing.Y && Threat.Y == Coord.Y && ((Coord.X > MyKing.X && Coord.X < Threat.X) || (Coord.X < MyKing.X && Coord.X > Threat.X))) { PiecesCoordinatesToProtectMyKing.Add(new Coordinates(x, y)); MatePossibleMoves.Add(new Coordinates(Coord.X, Coord.Y)); } //Si une pièce peut s'interposer entre le roi et la menace en diagonale gauche->droite (\) if (MyKing.X - Threat.X == MyKing.Y - Threat.Y && MyKing.X - Coord.X == MyKing.Y - Coord.Y && ((MyKing.X - Coord.X < MyKing.X - Threat.X && MyKing.Y - Coord.Y < MyKing.Y - Threat.Y) || (MyKing.X - Coord.X > MyKing.X - Threat.X && MyKing.Y - Coord.Y > MyKing.Y - Threat.Y))) { PiecesCoordinatesToProtectMyKing.Add(new Coordinates(x, y)); MatePossibleMoves.Add(new Coordinates(Coord.X, Coord.Y)); } //Si une pièce peut s'interposer entre le roi et la menace en diagonale droite->gauche (/) if (MyKing.X - Threat.X == Threat.Y - MyKing.Y && MyKing.X - Coord.X == Coord.Y - MyKing.Y && ((MyKing.X - Coord.X < MyKing.X - Threat.X && MyKing.Y - Coord.Y > MyKing.Y - Threat.Y) || (MyKing.X - Coord.X > MyKing.X - Threat.X && MyKing.Y - Coord.Y < MyKing.Y - Threat.Y))) { PiecesCoordinatesToProtectMyKing.Add(new Coordinates(x, y)); MatePossibleMoves.Add(new Coordinates(Coord.X, Coord.Y)); } } //Si le roi peut bouger et sortir de l'échec if ((x == MyKing.X && y == MyKing.Y) && !VirtualMoveAndMateTest(new Coordinates(MyKing.X, MyKing.Y), new Coordinates(Coord.X, Coord.Y))) { PiecesCoordinatesToProtectMyKing.Add(new Coordinates(x, y)); MatePossibleMoves.Add(new Coordinates(Coord.X, Coord.Y)); } } } } } } } return(new List <Coordinates>[] { PiecesCoordinatesToProtectMyKing, MatePossibleMoves }); }