// try to do a movement of piece
        public MovementResult MovePiece(char column, int row, char targetColumn, int targetRow)
        {
            MovementResult result = new MovementResult();

            var selectPiece = GetPiece(column, row);

            // check if there is a piece at start position
            if (selectPiece == null)
            {
                result.IsSuccess   = false;
                result.Description = String.Format("No piece is present at position {0}{1}", column, row.ToString());

                return(result);
            }

            var targetPiece = GetPiece(targetColumn, targetRow);

            // check it is a valid movement for piece (rules piece validator)
            if (!selectPiece.IsValidMovement(
                    (targetPiece != null && !selectPiece.ChessColor.Equals(targetPiece.ChessColor)),
                    row - 1, Columns[column], targetRow - 1, Columns[targetColumn]))
            {
                result.IsSuccess   = false;
                result.Description =
                    String.Format("The {0} {1} at position {2}{3} cannot move to {4}{5}",
                                  selectPiece.ChessColor.ToString(), selectPiece.GetType().Name,
                                  column, row.ToString(), targetColumn, targetRow.ToString());

                return(result);
            }

            // check if the path is free if piece is not a knight
            if (!(selectPiece is Knight) && !checkIfPathIsFree(column, row, targetColumn, targetRow))
            {
                result.IsSuccess   = false;
                result.Description =
                    String.Format("The path from {0}{1} to {2}{3} for {4}{5} is not free.",
                                  column, row.ToString(), targetColumn, targetRow.ToString(),
                                  selectPiece.ChessColor.ToString(), selectPiece.GetType().Name);

                return(result);
            }

            // check if target position there is already present a piece with same color
            if (targetPiece != null && selectPiece.ChessColor.Equals(targetPiece.ChessColor))
            {
                result.IsSuccess   = false;
                result.Description =
                    String.Format("There is already present a {0} piece at position {1}{2}",
                                  selectPiece.ChessColor.ToString(), targetColumn, targetRow);

                return(result);
            }

            // set result information after capture
            result.Capture = (targetPiece != null && !selectPiece.ChessColor.Equals(targetPiece.ChessColor));
            if (result.Capture)
            {
                result.CapturedPiece = targetPiece;
            }

            // change position of piece
            putPiece(selectPiece, targetColumn, targetRow);
            clearBoardPosition(column, row);

            return(result);
        }
Exemplo n.º 2
0
        private MovementResult MovePiece(char column, int row, char targetColumn, int targetRow, bool forTest)
        {
            MovementResult result = new MovementResult();

            var selectPiece = GetPiece(column, row);

            // check if there is a piece at start position
            if (selectPiece == null)
            {
                result.IsSuccess   = false;
                result.Description = String.Format("No piece is present at position {0}{1}", column, row.ToString());

                return(result);
            }

            Piece targetPiece = null;
            var   isEnPassant = EnPassant != null && selectPiece is Pawn && targetColumn == EnPassant.Item1 && targetRow == EnPassant.Item2;

            if (!isEnPassant)
            {
                targetPiece = GetPiece(targetColumn, targetRow);
            }
            else
            {
                targetPiece = GetPiece(targetColumn, row);
            }



            // check it is a valid movement for piece (rules piece validator)
            if (!selectPiece.IsValidMovement(
                    (targetPiece != null && !selectPiece.ChessColor.Equals(targetPiece.ChessColor)),
                    row - 1, Columns[column], targetRow - 1, Columns[targetColumn]))
            {
                result.IsSuccess   = false;
                result.Description =
                    String.Format("The {0} {1} at position {2}{3} cannot move to {4}{5}",
                                  selectPiece.ChessColor.ToString(), selectPiece.GetType().Name,
                                  column, row.ToString(), targetColumn, targetRow.ToString());

                return(result);
            }

            // check if the path is free if piece is not a knight
            if (!(selectPiece is Knight) && !checkIfPathIsFree(column, row, targetColumn, targetRow))
            {
                result.IsSuccess   = false;
                result.Description =
                    String.Format("The path from {0}{1} to {2}{3} for {4}{5} is not free.",
                                  column, row.ToString(), targetColumn, targetRow.ToString(),
                                  selectPiece.ChessColor.ToString(), selectPiece.GetType().Name);

                return(result);
            }

            // check if target position there is already present a piece with same color
            if (targetPiece != null && selectPiece.ChessColor.Equals(targetPiece.ChessColor))
            {
                result.IsSuccess   = false;
                result.Description =
                    String.Format("There is already present a {0} piece at position {1}{2}",
                                  selectPiece.ChessColor.ToString(), targetColumn, targetRow);

                return(result);
            }

            //En passant done
            if (isEnPassant && !forTest)
            {
                clearBoardPosition(targetColumn, row);
            }

            // set result information after ate
            result.Ate = (targetPiece != null && !selectPiece.ChessColor.Equals(targetPiece.ChessColor));
            if (result.Ate)
            {
                result.AtePiece = targetPiece;
            }


            // set EnPassant Information
            EnPassant = null;
            if ((selectPiece is Pawn) && (Math.Abs(row - targetRow) == 2))
            {
                //En passant possibilities
                var pieceLeft  = TryGetPiece(Columns[targetColumn], targetRow);
                var pieceRigth = TryGetPiece(Columns[targetColumn] + 2, targetRow);
                if ((pieceLeft != null && pieceLeft.ChessColor != selectPiece.ChessColor && pieceLeft is Pawn)
                    ||
                    (pieceRigth != null && pieceRigth.ChessColor != selectPiece.ChessColor && pieceRigth is Pawn))
                {
                    EnPassant = new Tuple <char, int>(targetColumn, (targetRow + row) / 2);
                }
            }

            //Castling rules
            bool isCastling = false;

            if ((selectPiece is King) && Math.Abs(Columns[column] - Columns[targetColumn]) == 2)
            {
                //1-The king should not have moved yet
                var king = (King)selectPiece;
                if (king.HasAlreadyMoved || !(column == 'E' && (row == 1 || row == 8)))
                {
                    result.IsSuccess   = false;
                    result.Description =
                        String.Format("You cannot do the Castling because your king has already moved.");
                    return(result);
                }
                //2-The Rook should not have moved yet either
                var rookColumn = (targetColumn == 'G') ? 'H' : 'A';
                var pieceFound = GetPiece(rookColumn, targetRow);
                if (pieceFound == null || pieceFound.ChessColor != king.ChessColor || !(pieceFound is Rook))
                {
                    result.IsSuccess   = false;
                    result.Description =
                        String.Format("You cannot do the Castling because there is no Rook at position {0}{1}.", rookColumn, targetRow);
                    return(result);
                }

                var goodRook = (Rook)pieceFound;

                if (goodRook.HasAlreadyMoved)
                {
                    result.IsSuccess   = false;
                    result.Description =
                        String.Format("You cannot do the Castling as your rook has already moved at position {0}{1}.", rookColumn, targetRow);
                    return(result);
                }
                //3-The King should not be chess or passing on a echec position
                var canMoveOnTheKing = CheckKingEchec(king.ChessColor);
                if (canMoveOnTheKing != null)
                {
                    result.IsSuccess   = false;
                    result.Description =
                        String.Format("You cannot do the Castling because you are echec {0}{1}.", canMoveOnTheKing.Item1, canMoveOnTheKing.Item2);
                    return(result);
                }

                //4-Can do one step :
                var oneStepColumn = (targetColumn == 'G') ? 'F' : 'D';
                var canDoOne      = this.MovePiece(column, row, oneStepColumn, targetRow);
                if (!canDoOne.IsSuccess)
                {
                    result.IsSuccess   = false;
                    result.Description =
                        String.Format("You cannot do the Castling because you would be echec at the position {0}{1}.", oneStepColumn, targetRow);
                    return(result);
                }
                else
                {
                    //One step is posible, so rollback, and test two step :
                    PutPiece(king, column, row);
                    clearBoardPosition(oneStepColumn, row);
                    king.HasAlreadyMoved = false;
                    isCastling           = true;
                }
            }

            // change position of piece
            if (!forTest)
            {
                PutPiece(selectPiece, targetColumn, targetRow);
                clearBoardPosition(column, row);

                //Pawn reach the opposite side, can be promoted
                if (selectPiece is Pawn && (targetRow == 1 || targetRow == 8))
                {
                    PawnPromoted      = true;
                    PawnPromotedColor = selectPiece.ChessColor;
                }

                // check if the move does not make our king in chess
                Tuple <char, int> pieceWitchMakeChess = CheckKingEchec(selectPiece.ChessColor);
                if (pieceWitchMakeChess != null)
                {
                    //RollBack
                    PutPiece(selectPiece, column, row);
                    clearBoardPosition(targetColumn, targetRow);
                    PawnPromoted = false;
                    if (result.Ate == true)
                    {
                        var pieceEaten = result.AtePiece;
                        this.PutPiece(pieceEaten, targetColumn, targetRow);
                        result.AtePiece = null;
                        result.Ate      = false;
                    }

                    result.IsSuccess   = false;
                    result.Description =
                        String.Format("Your king is in echec from the piece {0} ({1}{2}).",
                                      selectPiece.GetType().Name, pieceWitchMakeChess.Item1, pieceWitchMakeChess.Item2);

                    return(result);
                }

                if (selectPiece is IHasAlreadyMoved)
                {
                    ((IHasAlreadyMoved)selectPiece).HasAlreadyMoved = true;
                    //TODO : Move the rook in case of castling
                    if (isCastling)
                    {
                        var rookColumnOrigin = (targetColumn == 'G') ? 'H' : 'A';
                        var rookColumnTarget = (targetColumn == 'G') ? 'F' : 'D';
                        var pieceFound       = GetPiece(rookColumnOrigin, row);
                        PutPiece(pieceFound, rookColumnTarget, row);
                        clearBoardPosition(rookColumnOrigin, row);
                    }
                }
            }
            return(result);
        }