private bool youCanMove(PositionBoard position) { Piece piece = Board.Piece(position); // The piece will only be able to move if the chosen position is free or with a piece of the opposite color. return(piece == null || piece.Color != Color); }
// Check on all pieces of the same color as the king if there is one that moves the check from the king. // If we run out of possibilities and it is not possible to move any, we conclude that the king is in checkmate. // And the game is over. public bool TestCheckmate(Color color) { // If the king of that color is not in check, then there is no need to check if he is in checkmate if (!KingIsInCheck(color)) { return(false); } foreach (Piece item in PiecesStillInPlay(color)) { bool[,] possibleMovesMatrix = item.PossibleMoviments(); for (int i = 0; i < Board.Rows; i++) { for (int j = 0; j < Board.Columns; j++) { if (possibleMovesMatrix[i, j]) { PositionBoard originalPosition = item.PositionBoard; PositionBoard destination = new PositionBoard(i, j); Piece capturedPiece = PerformMovement(originalPosition, destination); bool checkTest = KingIsInCheck(color); UndoMoves(originalPosition, destination, capturedPiece); if (!checkTest) { return(false); } } } } } return(true); }
public void ValidateDestinationPosition(PositionBoard originalPosition, PositionBoard destinationPosition) { Board.ValidatePositionException(destinationPosition); if (!Board.Piece(originalPosition).CanMoveTo(destinationPosition)) { throw new BoardException("Invalid target position"); } }
public override bool[,] PossibleMoviments() { // It will save all possible moves for the root. bool[,] possibleMovimentsMatrix = new bool[Board.Rows, Board.Columns]; PositionBoard position = new PositionBoard(0, 0); // Above position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column); while (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; if (Board.Piece(position) != null && Board.Piece(position).Color != Color) { break; } position.Row = position.Row - 1; } // Below position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column); while (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; if (Board.Piece(position) != null && Board.Piece(position).Color != Color) { break; } position.Row = position.Row + 1; } // Right position.SetPositionValues(PositionBoard.Row, PositionBoard.Column + 1); while (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; if (Board.Piece(position) != null && Board.Piece(position).Color != Color) { break; } position.Column = position.Column + 1; } // Left position.SetPositionValues(PositionBoard.Row, PositionBoard.Column - 1); while (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; if (Board.Piece(position) != null && Board.Piece(position).Color != Color) { break; } position.Column = position.Column - 1; } return(possibleMovimentsMatrix); }
public void UndoMoves(PositionBoard originalPosition, PositionBoard destinationPosition, Piece capturedPiece) { Piece piece = Board.RemovePiece(destinationPosition); piece.DecreaseMovementCount(); // There was a piece that was captured if (capturedPiece != null) { // I go to the board and place the captured piece back at the destination Board.PlacePieceOnBoard(capturedPiece, destinationPosition); // I go to the set of captured pieces and remove that captured piece setCapturedPieces.Remove(capturedPiece); } // Put the piece back in the original position. Board.PlacePieceOnBoard(piece, originalPosition); //SPECIAL MOVE : small castling if (piece is King && destinationPosition.Column == originalPosition.Column + 2) { PositionBoard originalPositionRook = new PositionBoard(originalPosition.Row, originalPosition.Column + 3); PositionBoard destinationPositionRook = new PositionBoard(originalPosition.Row, originalPosition.Column + 1); Piece rook = Board.RemovePiece(destinationPositionRook); rook.DecreaseMovementCount(); Board.PlacePieceOnBoard(rook, originalPositionRook); } //SPECIAL MOVE : Big castling if (piece is King && destinationPosition.Column == originalPosition.Column - 2) { PositionBoard originalPositionRook = new PositionBoard(originalPosition.Row, originalPosition.Column - 4); PositionBoard destinationPositionRook = new PositionBoard(originalPosition.Row, originalPosition.Column - 1); Piece rook = Board.RemovePiece(destinationPositionRook); rook.DecreaseMovementCount(); Board.PlacePieceOnBoard(rook, originalPositionRook); } //SPECIAL MOVE : En Passant if (piece is Pawn) { if (originalPosition.Column != destinationPosition.Column && capturedPiece == VulnerablePieceEnPassant) { Piece pawn = Board.RemovePiece(destinationPosition); PositionBoard pawnPosition; if (piece.Color == Color.White) { pawnPosition = new PositionBoard(3, destinationPosition.Column); } else { pawnPosition = new PositionBoard(4, destinationPosition.Column); } Board.PlacePieceOnBoard(pawn, pawnPosition); } } }
public void ValidateOriginalPosition(PositionBoard position) { Board.ValidatePositionException(position); if (Board.Piece(position) == null) { throw new BoardException("There is no piece in the chosen original position!"); } if (CurrentPlayer != Board.Piece(position).Color) { throw new BoardException("The piece chosen is not yours!"); } if (!Board.Piece(position).ThereArePossibleMovements()) { throw new BoardException("There are no possible movements for the chosen piece!"); } }
static void Main(string[] args) { try { ChessMatch match = new ChessMatch(); while (!match.MatchIsOver) { try { Console.Clear(); Screen.PrintMatch(match); Console.WriteLine(); Console.Write("Original: "); // It is always necessary to transform the position provided by the user (chess position) into a matrix position PositionBoard originalPosition = Screen.ReadChessPosition().ChessPositionToMatrixPosition(); match.ValidateOriginalPosition(originalPosition); // pick up the required piece in the original position, check which movements are possible and store it in the matrix bool[,] PossiblePositions = match.Board.Piece(originalPosition).PossibleMoviments(); Console.Clear(); Screen.PrintBoard(match.Board, PossiblePositions); Console.WriteLine(); Console.Write("Destination: "); PositionBoard destinationPosition = Screen.ReadChessPosition().ChessPositionToMatrixPosition(); match.ValidateDestinationPosition(originalPosition, destinationPosition); match.MakeAMove(originalPosition, destinationPosition); } catch (BoardException e) { Console.WriteLine(e.Message); Console.ReadLine(); } } Console.Clear(); Screen.PrintMatch(match); } catch (BoardException e) { Console.WriteLine(e.Message); } }
public Piece PerformMovement(PositionBoard originalPosition, PositionBoard destinationPosition) { // Removes the piece from the defined position (origin position), Piece piece = Board.RemovePiece(originalPosition); // Increase a play. piece.IncreaseMovementCount(); // If there is a piece in the destination position, it will be removed. // It will capture a piece. Piece capturedPiece = Board.RemovePiece(destinationPosition); // Place the piece that was removed from the original position into the destination position Board.PlacePieceOnBoard(piece, destinationPosition); //If had a piece in the target position if (capturedPiece != null) { // Will add this piece to the list of captured pieces setCapturedPieces.Add(capturedPiece); } //SPECIAL MOVE : small castling if (piece is King && destinationPosition.Column == originalPosition.Column + 2) { PositionBoard originalPositionRook = new PositionBoard(originalPosition.Row, originalPosition.Column + 3); PositionBoard destinationPositionRook = new PositionBoard(originalPosition.Row, originalPosition.Column + 1); Piece rook = Board.RemovePiece(originalPositionRook); rook.IncreaseMovementCount(); Board.PlacePieceOnBoard(rook, destinationPositionRook); } //SPECIAL MOVE : big castling if (piece is King && destinationPosition.Column == originalPosition.Column - 2) { PositionBoard originalPositionRook = new PositionBoard(originalPosition.Row, originalPosition.Column - 4); PositionBoard destinationPositionRook = new PositionBoard(originalPosition.Row, originalPosition.Column - 1); Piece rook = Board.RemovePiece(originalPositionRook); rook.IncreaseMovementCount(); Board.PlacePieceOnBoard(rook, destinationPositionRook); } //SPECIAL MOVE : En Passant if (piece is Pawn) { // Diagonally moved and did not capture any pieces if (originalPosition.Column != destinationPosition.Column && capturedPiece == null) { PositionBoard pawnPosition; if (piece.Color == Color.White) { // The black piece (piece to be captured) will be one square below the white pawnPosition = new PositionBoard(destinationPosition.Row + 1, destinationPosition.Column); } else { // If it's a black pawn, it's the same thing, but now from the bottom up pawnPosition = new PositionBoard(destinationPosition.Row - 1, destinationPosition.Column); } capturedPiece = Board.RemovePiece(pawnPosition); setCapturedPieces.Add(capturedPiece); } } return(capturedPiece); }
// The piece will perform a movement from the origin position to the destination position. public void MakeAMove(PositionBoard originalPosition, PositionBoard destinationPosition) { Piece capturedPiece = PerformMovement(originalPosition, destinationPosition); // The opponent can be in check with my move, but I can't. if (KingIsInCheck(CurrentPlayer)) { UndoMoves(originalPosition, destinationPosition, capturedPiece); throw new BoardException("You can't put yourself in check!"); } Piece piece = Board.Piece(destinationPosition); // SPECIAL MOVE : Promotion if (piece is Pawn) { // If the piece is a white pawn and has reached line 0 or if it is a black pawn and has reached line 7 if ((piece.Color == Color.White && destinationPosition.Row == 0) || (piece.Color == Color.Black && destinationPosition.Row == 7)) { // That pawn piece will be transformed into a queen piece = Board.RemovePiece(destinationPosition); setPieces.Remove(piece); Piece queen = new Queen(piece.Color, Board); Board.PlacePieceOnBoard(queen, destinationPosition); } } if (KingIsInCheck(colorOpponent(CurrentPlayer))) { MatchInCheck = true; } else { MatchInCheck = false; } // If the method in which the checkmate is being tested returns true then the game is ended if (TestCheckmate(colorOpponent(CurrentPlayer))) { MatchIsOver = true; } else // Else continues with the next player's move { // change the turn TurnToPlay++; changesPlayersTurn(); } // #SPECIAL MOVES : En Passant // Se a peça é um peão e se andou duas linhas a mais ou a menos, // se for verdade a peça está vulnerável a en passant if (piece is Pawn && (destinationPosition.Row == originalPosition.Row - 2 || destinationPosition.Row == originalPosition.Row + 2)) { VulnerablePieceEnPassant = piece; } else { VulnerablePieceEnPassant = null; } }
public override bool[,] PossibleMoviments() { // It will save all possible moves for the king. // It can move all around him. bool[,] possibleMovimentsMatrix = new bool[Board.Rows, Board.Columns]; PositionBoard position = new PositionBoard(0, 0); // Above position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // NorthEast position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column + 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Right position.SetPositionValues(PositionBoard.Row, PositionBoard.Column + 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Southeast position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column + 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Below position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // South-west position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column - 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Left position.SetPositionValues(PositionBoard.Row, PositionBoard.Column - 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Northwest position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column - 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // #SPECIAL MOVE : Castling if (MovementCount == 0 && !match.MatchInCheck) { // Small castling // The king’s position must be three columns to the right relative to the rook PositionBoard rookPositionSmall = new PositionBoard(PositionBoard.Row, PositionBoard.Column + 3); if (testRookForCastling(rookPositionSmall)) { // The two houses between the king and the rook must be free PositionBoard nextPosition = new PositionBoard(PositionBoard.Row, PositionBoard.Column + 1); PositionBoard nextPosition2 = new PositionBoard(PositionBoard.Row, PositionBoard.Column + 2); // The king can move to the second free house (next to the rook) if (Board.Piece(nextPosition) == null && Board.Piece(nextPosition2) == null) { possibleMovimentsMatrix[PositionBoard.Row, PositionBoard.Column + 2] = true; } } // Big castling PositionBoard rookPositionBig = new PositionBoard(PositionBoard.Row, PositionBoard.Column - 4); if (testRookForCastling(rookPositionBig)) { // The three houses between the king and the rook must be free PositionBoard nextPosition = new PositionBoard(PositionBoard.Row, PositionBoard.Column - 1); PositionBoard nextPosition2 = new PositionBoard(PositionBoard.Row, PositionBoard.Column - 2); PositionBoard nextPosition3 = new PositionBoard(PositionBoard.Row, PositionBoard.Column - 2); // The king can move to the second free house if (Board.Piece(nextPosition) == null && Board.Piece(nextPosition2) == null && Board.Piece(nextPosition3) == null) { possibleMovimentsMatrix[PositionBoard.Row, PositionBoard.Column - 2] = true; } } } return(possibleMovimentsMatrix); }
// Checks whether the tower in that position is eligible for castling private bool testRookForCastling(PositionBoard position) { Piece piece = Board.Piece(position); return(piece != null && piece is Rook && piece.Color == Color && piece.MovementCount == 0); }
public override bool[,] PossibleMoviments() { // It will save all possible moves for the knight. bool[,] possibleMovimentsMatrix = new bool[Board.Rows, Board.Columns]; PositionBoard position = new PositionBoard(0, 0); // Above position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column - 2); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // NorthEast position.SetPositionValues(PositionBoard.Row - 2, PositionBoard.Column - 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Right position.SetPositionValues(PositionBoard.Row - 2, PositionBoard.Column + 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // South-west position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column + 2); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Below position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column + 2); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // South-west position.SetPositionValues(PositionBoard.Row + 2, PositionBoard.Column + 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Left position.SetPositionValues(PositionBoard.Row + 2, PositionBoard.Column - 1); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Northwest position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column - 2); if (Board.PositionIsValid(position) && youCanMove(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } return(possibleMovimentsMatrix); }
public override bool[,] PossibleMoviments() { // It will save all possible moves for the king. // It can move all around him. bool[,] possibleMovimentsMatrix = new bool[Board.Rows, Board.Columns]; PositionBoard position = new PositionBoard(0, 0); if (Color == Color.White) { // Can move up one house if the house is free. position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column); if (Board.PositionIsValid(position) && free(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Can move two houses up if the house is free and if it is the first move of the pawn. position.SetPositionValues(PositionBoard.Row - 2, PositionBoard.Column); if (Board.PositionIsValid(position) && free(position) && MovementCount == 0) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Can walk on diagonals if there is an enemy. position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column - 1); if (Board.PositionIsValid(position) && thereIsEnemy(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } position.SetPositionValues(PositionBoard.Row - 1, PositionBoard.Column + 1); if (Board.PositionIsValid(position) && thereIsEnemy(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // #SPECIAL MOVES : En Passant // It only happens on this line for the white pieces if (PositionBoard.Row == 3) { // left pawn position PositionBoard leftPosition = new PositionBoard(PositionBoard.Row, PositionBoard.Column - 1); if (Board.PositionIsValid(leftPosition) && thereIsEnemy(leftPosition) && Board.Piece(leftPosition) == match.VulnerablePieceEnPassant) { possibleMovimentsMatrix[leftPosition.Row - 1, leftPosition.Column] = true; } // Right pawn position PositionBoard rightPosition = new PositionBoard(PositionBoard.Row, PositionBoard.Column + 1); if (Board.PositionIsValid(rightPosition) && thereIsEnemy(rightPosition) && Board.Piece(rightPosition) == match.VulnerablePieceEnPassant) { possibleMovimentsMatrix[rightPosition.Row - 1, rightPosition.Column] = true; } } } else { // Can move down one house if the house is free. position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column); if (Board.PositionIsValid(position) && free(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Can move two houses down if the house is free and if it is the first move of the pawn. position.SetPositionValues(PositionBoard.Row + 2, PositionBoard.Column); //PositionBoard secondPosition = new PositionBoard(position.Row + 1, position.Column); if (Board.PositionIsValid(position) && free(position) && MovementCount == 0) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // Can walk on diagonals if there is an enemy. position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column - 1); if (Board.PositionIsValid(position) && thereIsEnemy(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } position.SetPositionValues(PositionBoard.Row + 1, PositionBoard.Column + 1); if (Board.PositionIsValid(position) && thereIsEnemy(position)) { possibleMovimentsMatrix[position.Row, position.Column] = true; } // #SPECIAL MOVES : En Passant // It only happens on this line for the black pieces if (PositionBoard.Row == 4) { // left pawn position PositionBoard leftPosition = new PositionBoard(PositionBoard.Row, PositionBoard.Column - 1); if (Board.PositionIsValid(leftPosition) && thereIsEnemy(leftPosition) && Board.Piece(leftPosition) == match.VulnerablePieceEnPassant) { possibleMovimentsMatrix[leftPosition.Row + 1, leftPosition.Column] = true; } // Right pawn position PositionBoard rightPosition = new PositionBoard(PositionBoard.Row, PositionBoard.Column + 1); if (Board.PositionIsValid(rightPosition) && thereIsEnemy(rightPosition) && Board.Piece(rightPosition) == match.VulnerablePieceEnPassant) { possibleMovimentsMatrix[rightPosition.Row + 1, rightPosition.Column] = true; } } } return(possibleMovimentsMatrix); }
private bool free(PositionBoard position) { return(Board.Piece(position) == null); }
private bool thereIsEnemy(PositionBoard position) { Piece piece = Board.Piece(position); return(piece != null && piece.Color != Color); }