/// <summary> /// Retrieves a list of positions that are between the castling Rook and King. /// </summary> /// <param name="king"></param> /// <param name="rook"></param> /// <returns></returns> public List <ChessPosition> GetPositionsBetweenCastle(IKing king, IRook rook) { var locationsInBetween = new List <ChessPosition>(); // add all locations to check based on where the king and rook are located switch (king.Location) { case ChessPosition.E1 when rook.Location == ChessPosition.A1: locationsInBetween.Add(ChessPosition.D1); locationsInBetween.Add(ChessPosition.C1); locationsInBetween.Add(ChessPosition.B1); break; case ChessPosition.E1 when rook.Location == ChessPosition.H1: locationsInBetween.Add(ChessPosition.F1); locationsInBetween.Add(ChessPosition.G1); break; case ChessPosition.E8 when rook.Location == ChessPosition.A8: locationsInBetween.Add(ChessPosition.D8); locationsInBetween.Add(ChessPosition.C8); locationsInBetween.Add(ChessPosition.B8); break; case ChessPosition.E8 when rook.Location == ChessPosition.H8: locationsInBetween.Add(ChessPosition.F8); locationsInBetween.Add(ChessPosition.G8); break; } return(locationsInBetween); }
/// <summary> /// Updates board for Castle. Does not check legality. /// </summary> /// <param name="king"></param> /// <param name="move"></param> /// <param name="rook"></param> private void UpdateBoardForCastle(IKing king, IMove move, IRook rook) { ChessPosition newRookLocation = ModelLocator.CastlingHelper.GetEndingPositionForCastlingRook(king, rook); GameBoard.Remove(king.Location); // remove King from board king.MoveTo(move.EndingPosition); // move King, update location GameBoard.Add(move.EndingPosition); // place King on board at update location GameBoard.Remove(rook.Location); // remove Rook from board rook.MoveTo(newRookLocation); // move Rook, update location GameBoard.Add(rook.Location); // place Rook on board at updated location MoveHistory.Add(king, move); }
/// <summary> /// Determines the position where a castling Rook will end at. /// </summary> /// <param name="king"></param> /// <param name="rook"></param> /// <returns></returns> public ChessPosition GetEndingPositionForCastlingRook(IKing king, IRook rook) { switch (king.Location) { case ChessPosition.E1 when rook.Location == ChessPosition.A1: return(ChessPosition.D1); case ChessPosition.E1 when rook.Location == ChessPosition.H1: return(ChessPosition.F1); case ChessPosition.E8 when rook.Location == ChessPosition.A8: return(ChessPosition.D8); case ChessPosition.E8 when rook.Location == ChessPosition.H8: return(ChessPosition.F8); default: return(rook.Location); } }
/// <summary> /// Checks if the castle is legal by a process of six standard steps. /// </summary> /// <param name="piece"></param> /// <param name="move"></param> /// <param name="board"></param> /// <returns></returns> private bool IsCastleLegal(IPiece piece, IMove move, IBoard board) { // 1.) has the King moved already? if (!(piece is IKing king) || piece.HasMoved) { return(false); } IRook rook = GetCastlingRook(move, king.Color); // 2.) has the Rook moved already? if (rook == null || rook.HasMoved) { return(false); } List <ChessPosition> piecesBetweenRookAndKing = ModelLocator.CastlingHelper.GetPositionsBetweenCastle(king, rook); // 3.) are there pieces standing between the King and Rook? foreach (ChessPosition location in piecesBetweenRookAndKing) { if (board.IsPositionOccupied(location)) { return(false); } } // 4.) is the King currently in check? if (IsPositionThreatened(king.Location, board, InactivePlayerBoardState)) { return(false); } // 5.) are any positions between King and Rook threatened? foreach (ChessPosition position in piecesBetweenRookAndKing) { if (IsPositionThreatened(position, board, InactivePlayerBoardState)) { return(false); } } // 6.) will the King be in check after castling? return(!IsPositionThreatened(move.EndingPosition, board, InactivePlayerBoardState)); }
public Rook(IRook other) : base(other) { }
public Rook(IRook other) : base(other) { SpriteImageFilePath = DefaultSpriteImageFiles[this.Color]; }
/// <summary> /// Updates a board for the given move. Does not check legality. /// </summary> /// <param name="piece"></param> /// <param name="move"></param> /// <returns></returns> private void ExecuteCastle(IKing piece, IMove move) { IRook rook = GetCastlingRook(move, piece.Color); UpdateBoardForCastle(piece, move, rook); }