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);
        }
Beispiel #2
0
 // 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);
 }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        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);
                }
            }
        }
Beispiel #6
0
        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!");
            }
        }
Beispiel #7
0
        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);
            }
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        // 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);
        }