Example #1
0
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }
            PositionDistance distance2 = (PositionDistance)obj;

            return(DistanceX == distance2.DistanceX && DistanceY == distance2.DistanceY);
        }
Example #2
0
        protected virtual bool IsValidMoveKnight(Move move)
        {
            Utilities.ThrowIfNull(move, "move");
            PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);

            if ((posDelta.DistanceX != 2 || posDelta.DistanceY != 1) && (posDelta.DistanceX != 1 || posDelta.DistanceY != 2))
            {
                return(false);
            }
            return(true);
        }
Example #3
0
        protected virtual bool IsValidMoveKing(Move move)
        {
            Utilities.ThrowIfNull(move, "move");
            PositionDistance distance = new PositionDistance(move.OriginalPosition, move.NewPosition);

            if ((distance.DistanceX != 1 || distance.DistanceY != 1) &&
                (distance.DistanceX != 0 || distance.DistanceY != 1) &&
                (distance.DistanceX != 1 || distance.DistanceY != 0) &&
                (distance.DistanceX != 2 || distance.DistanceY != 0))
            {
                return(false);
            }
            if (distance.DistanceX != 2)
            {
                return(true);
            }
            return(CanCastle(move));
        }
Example #4
0
        protected virtual bool IsValidMoveRook(Move move)
        {
            Utilities.ThrowIfNull(move, "move");
            PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);

            if (posDelta.DistanceX != 0 && posDelta.DistanceY != 0)
            {
                return(false);
            }
            bool increasingRank = (int)move.NewPosition.Rank > (int)move.OriginalPosition.Rank;
            bool increasingFile = (int)move.NewPosition.File > (int)move.OriginalPosition.File;

            if (posDelta.DistanceX == 0)
            {
                int f = (int)move.OriginalPosition.File;
                for (int r = (int)move.OriginalPosition.Rank + (increasingRank ? 1 : -1);
                     increasingRank?r <(int)move.NewPosition.Rank : r> (int) move.NewPosition.Rank;
                     r += increasingRank ? 1 : -1)
                {
                    if (Board[r][f].Player != Player.None)
                    {
                        return(false);
                    }
                }
            }
            else // (posDelta.DeltaY == 0)
            {
                int r = (int)move.OriginalPosition.Rank;
                for (int f = (int)move.OriginalPosition.File + (increasingFile ? 1 : -1);
                     increasingFile?f <(int)move.NewPosition.File : f> (int) move.NewPosition.File;
                     f += increasingFile ? 1 : -1)
                {
                    if (Board[r][f].Player != Player.None)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Example #5
0
        public virtual MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured)
        {
            ChessUtilities.ThrowIfNull(move, "move");
            captured = null;
            if (!alreadyValidated && !IsValidMove(move))
            {
                return(MoveType.Invalid);
            }
            MoveType type          = MoveType.Move;
            Piece    movingPiece   = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            Piece    capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank);

            captured = capturedPiece;
            Piece        newPiece  = movingPiece;
            bool         isCapture = capturedPiece != null;
            CastlingType castle    = CastlingType.None;

            if (movingPiece is Pawn)
            {
                i_halfMoveClock = 0;
                PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition);
                if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition) == null)
                { // en passant
                    isCapture = true;
                    captured  = GetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank);
                    SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null);
                }
                if (move.NewPosition.Rank == (move.Player == Player.White ? 8 : 1))
                {
                    newPiece = MapPgnCharToPiece(move.Promotion.Value, move.Player).AsPromotion();
                    type    |= MoveType.Promotion;
                }
            }
            else if (movingPiece is King)
            {
                if (movingPiece.Owner == Player.White)
                {
                    CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false;
                }
                else
                {
                    CanBlackCastleKingSide = CanBlackCastleQueenSide = false;
                }

                if (CastlingCanBeLegal &&
                    ((GetPieceAt(move.NewPosition) is Rook && GetPieceAt(move.NewPosition).Owner == move.Player) ||
                     ((move.NewPosition.File == File.C || move.NewPosition.File == File.G) &&
                      (move.Player == Player.White ? InitialWhiteKingFile : InitialBlackKingFile) == File.E &&
                      move.OriginalPosition.File == File.E)))
                {
                    castle    = ApplyCastle(move);
                    type     |= MoveType.Castling;
                    isCapture = false;
                }
            }
            else if (movingPiece is Rook)
            {
                if (move.Player == Player.White)
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 1)
                    {
                        CanWhiteCastleQueenSide = false;
                    }
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 1)
                    {
                        CanWhiteCastleKingSide = false;
                    }
                }
                else
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 8)
                    {
                        CanBlackCastleQueenSide = false;
                    }
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 8)
                    {
                        CanBlackCastleKingSide = false;
                    }
                }
            }
            if (isCapture)
            {
                type           |= MoveType.Capture;
                i_halfMoveClock = 0;
                if (move.NewPosition.File == File.A && move.NewPosition.Rank == 1)
                {
                    CanWhiteCastleQueenSide = false;
                }
                else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 1)
                {
                    CanWhiteCastleKingSide = false;
                }
                else if (move.NewPosition.File == File.A && move.NewPosition.Rank == 8)
                {
                    CanBlackCastleQueenSide = false;
                }
                else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 8)
                {
                    CanBlackCastleKingSide = false;
                }
            }
            if (!isCapture && !(movingPiece is Pawn))
            {
                i_halfMoveClock++;
                if (i_halfMoveClock >= 100)
                {
                    fiftyMoves = true;
                }
                else
                {
                    fiftyMoves = false;
                }
            }
            if (move.Player == Player.Black)
            {
                i_fullMoveNumber++;
            }
            if (castle == CastlingType.None)
            {
                SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
                SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null);
            }
            WhoseTurn = ChessUtilities.GetOpponentOf(move.Player);
            AddDetailedMove(new DetailedMove(move, movingPiece, isCapture, castle));
            return(type);
        }
Example #6
0
        protected virtual bool ApplyMove(Move move, bool alreadyValidated, bool validateHasAnyValidMoves)
        {
            Utilities.ThrowIfNull(move, "move");
            if (!alreadyValidated && !IsValidMove(move))
                return false;
            ChessPiece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            ChessPiece newPiece = movingPiece;
            if (movingPiece.Piece == Piece.Pawn)
            {
                PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition);
                if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition).Piece == Piece.None)
                { // en passant
                    SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, ChessPiece.None);
                }
                if (move.NewPosition.Rank == (move.Player == Player.White ? Rank.Eight : Rank.One))
                {
                    newPiece = new ChessPiece(move.Promotion, move.Player);
                }
            }
            else if (movingPiece.Piece == Piece.King)
            {
                if (movingPiece.Player == Player.White)
                    _whiteKingMoved = true;
                else
                    _blackKingMoved = true;

                if (new PositionDistance(move.OriginalPosition, move.NewPosition).DistanceX == 2)
                {
                    Rank rank = move.Player == Player.White ? Rank.One : Rank.Eight;
                    File rookFile = move.NewPosition.File == File.C ? File.A : File.H;
                    File newRookFile = move.NewPosition.File == File.C ? File.D : File.F;
                    SetPieceAt(newRookFile, rank, new ChessPiece(Piece.Rook, move.Player));
                    SetPieceAt(rookFile, rank, ChessPiece.None);
                }
            }
            else if (movingPiece.Piece == Piece.Rook)
            {
                if (move.Player == Player.White)
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == Rank.One)
                        _whiteRookAMoved = true;
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == Rank.One)
                        _whiteRookHMoved = true;
                }
                else
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == Rank.Eight)
                        _blackRookAMoved = true;
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == Rank.Eight)
                        _blackRookHMoved = true;
                }
            }
            SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
            SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, ChessPiece.None);
            WhoseTurn = Utilities.GetOpponentOf(move.Player);
            _moves.Add(move);
            return true;
        }
Example #7
0
 protected virtual bool IsValidMoveKnight(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);
     if ((posDelta.DistanceX != 2 || posDelta.DistanceY != 1) && (posDelta.DistanceX != 1 || posDelta.DistanceY != 2))
         return false;
     return true;
 }
Example #8
0
 protected virtual bool IsValidMoveBishop(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);
     if (posDelta.DistanceX != posDelta.DistanceY)
         return false;
     bool increasingRank = (int)move.NewPosition.Rank > (int)move.OriginalPosition.Rank;
     bool increasingFile = (int)move.NewPosition.File > (int)move.OriginalPosition.File;
     for (int f = (int)move.OriginalPosition.File + (increasingFile ? 1 : -1), r = (int)move.OriginalPosition.Rank + (increasingRank ? 1 : -1);
          increasingFile ? f < (int)move.NewPosition.File : f > (int)move.NewPosition.File;
          f += increasingFile ? 1 : -1, r += increasingRank ? 1 : -1)
     {
         if (Board[r][f].Player != Player.None)
         {
             return false;
         }
     }
     return true;
 }
Example #9
0
 protected virtual bool IsValidMovePawn(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);
     if ((posDelta.DistanceX != 0 || posDelta.DistanceY != 1) && (posDelta.DistanceX != 1 || posDelta.DistanceY != 1)
                 && (posDelta.DistanceX != 0 || posDelta.DistanceY != 2))
         return false;
     if (move.Player == Player.White)
     {
         if ((int)move.OriginalPosition.Rank < (int)move.NewPosition.Rank)
             return false;
         if (move.NewPosition.Rank == Rank.Eight && move.Promotion == Piece.None)
             return false;
     }
     if (move.Player == Player.Black)
     {
         if ((int)move.OriginalPosition.Rank > (int)move.NewPosition.Rank)
             return false;
         if (move.NewPosition.Rank == Rank.One && move.Promotion == Piece.None)
             return false;
     }
     bool checkEnPassant = false;
     if (posDelta.DistanceY == 2)
     {
         if ((move.OriginalPosition.Rank != Rank.Two && move.Player == Player.White)
             || (move.OriginalPosition.Rank != Rank.Seven && move.Player == Player.Black))
             return false;
         if (move.OriginalPosition.Rank == Rank.Two && GetPieceAt(move.OriginalPosition.File, Rank.Three).Piece != Piece.None)
             return false;
         if (move.OriginalPosition.Rank == Rank.Seven && GetPieceAt(move.OriginalPosition.File, Rank.Six).Piece != Piece.None)
             return false;
     }
     if (posDelta.DistanceX == 0 && (posDelta.DistanceY == 1 || posDelta.DistanceY == 2))
     {
         if (GetPieceAt(move.NewPosition).Player != Player.None)
             return false;
     }
     else
     {
         if (GetPieceAt(move.NewPosition).Player != Utilities.GetOpponentOf(move.Player))
             checkEnPassant = true;
         if (GetPieceAt(move.NewPosition).Player == move.Player)
             return false;
     }
     if (checkEnPassant)
     {
         if (_moves.Count == 0)
         {
             return false;
         }
         if ((move.OriginalPosition.Rank != Rank.Five && move.Player == Player.White)
             || (move.OriginalPosition.Rank != Rank.Four && move.Player == Player.Black))
             return false;
         Move latestMove = _moves[_moves.Count - 1];
         if (latestMove.Player != Utilities.GetOpponentOf(move.Player))
             return false;
         if (move.Player == Player.White)
         {
             if (latestMove.OriginalPosition.Rank != Rank.Seven || latestMove.NewPosition.Rank != Rank.Five)
                 return false;
         }
         else // (m.Player == Players.Black)
         {
             if (latestMove.OriginalPosition.Rank != Rank.Two || latestMove.NewPosition.Rank != Rank.Four)
                 return false;
         }
         if (move.NewPosition.File != latestMove.NewPosition.File)
             return false;
     }
     return true;
 }
Example #10
0
 protected virtual bool IsValidMoveKing(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     PositionDistance distance = new PositionDistance(move.OriginalPosition, move.NewPosition);
     if ((distance.DistanceX != 1 || distance.DistanceY != 1)
                 && (distance.DistanceX != 0 || distance.DistanceY != 1)
                 && (distance.DistanceX != 1 || distance.DistanceY != 0)
                 && (distance.DistanceX != 2 || distance.DistanceY != 0))
         return false;
     if (distance.DistanceX != 2)
         return true;
     return CanCastle(move);
 }
Example #11
0
        public virtual MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured)
        {
            ChessUtilities.ThrowIfNull(move, "move");
            captured = null;
            if (!alreadyValidated && !IsValidMove(move))
            {
                return(MoveType.Invalid);
            }
            MoveType type          = MoveType.Move;
            Piece    movingPiece   = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            Piece    capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank);

            captured = capturedPiece;
            Piece newPiece = movingPiece;

            enp = "-1";
            bool         isCapture = capturedPiece != null;
            CastlingType castle    = CastlingType.None;

            if (movingPiece is Pawn)
            {
                i_halfMoveClock = 0;
                PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition);
                if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition) == null)
                { // en passant
                    isCapture = true;
                    captured  = GetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank);
                    enp       = move.NewPosition.File.ToString().ToLower() + move.OriginalPosition.Rank.ToString();
                    SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null);
                }
                if (move.NewPosition.Rank == (move.Player == Player.White ? 8 : 1))
                {
                    //get promotion type
                    char PromoteTo;

                    if (move.Promotion == null)
                    {
                        string promote;
                        Console.Write("enter promotion type:");
                        promote = Console.ReadLine();
                        switch (promote)
                        {
                        case "queen":
                            PromoteTo = 'Q';
                            break;

                        case "bishop":
                            PromoteTo = 'B';
                            break;

                        case "knight":
                            PromoteTo = 'N';
                            break;

                        case "rook":
                            PromoteTo = 'R';
                            break;

                        default:
                            PromoteTo = 'Q';
                            break;
                        }
                    }
                    else
                    {
                        PromoteTo = 'Q';
                    }
                    newPiece = MapPgnCharToPiece(PromoteTo, move.Player).AsPromotion();
                    type    |= MoveType.Promotion;
                }
            }
            else if (movingPiece is King)
            {
                if (movingPiece.Owner == Player.White)
                {
                    CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false;
                }
                else
                {
                    CanBlackCastleKingSide = CanBlackCastleQueenSide = false;
                }

                if (CastlingCanBeLegal &&
                    ((GetPieceAt(move.NewPosition) is Rook && GetPieceAt(move.NewPosition).Owner == move.Player) ||
                     ((move.NewPosition.File == File.C || move.NewPosition.File == File.G) &&
                      (move.Player == Player.White ? InitialWhiteKingFile : InitialBlackKingFile) == File.E &&
                      move.OriginalPosition.File == File.E)))
                {
                    castle    = ApplyCastle(move);
                    type     |= MoveType.Castling;
                    isCapture = false;
                }
            }
            else if (movingPiece is Rook)
            {
                if (move.Player == Player.White)
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 1)
                    {
                        CanWhiteCastleQueenSide = false;
                    }
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 1)
                    {
                        CanWhiteCastleKingSide = false;
                    }
                }
                else
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 8)
                    {
                        CanBlackCastleQueenSide = false;
                    }
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 8)
                    {
                        CanBlackCastleKingSide = false;
                    }
                }
            }
            if (isCapture)
            {
                type           |= MoveType.Capture;
                i_halfMoveClock = 0;
                if (move.NewPosition.File == File.A && move.NewPosition.Rank == 1)
                {
                    CanWhiteCastleQueenSide = false;
                }
                else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 1)
                {
                    CanWhiteCastleKingSide = false;
                }
                else if (move.NewPosition.File == File.A && move.NewPosition.Rank == 8)
                {
                    CanBlackCastleQueenSide = false;
                }
                else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 8)
                {
                    CanBlackCastleKingSide = false;
                }
            }
            if (!isCapture && !(movingPiece is Pawn))
            {
                i_halfMoveClock++;
                if (i_halfMoveClock >= 100)
                {
                    fiftyMoves = true;
                }
                else
                {
                    fiftyMoves = false;
                }
            }
            if (move.Player == Player.Black)
            {
                i_fullMoveNumber++;
            }
            if (castle == CastlingType.None)
            {
                SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
                SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null);
            }
            WhoseTurn = ChessUtilities.GetOpponentOf(move.Player);
            AddDetailedMove(new DetailedMove(move, movingPiece, isCapture, castle));
            return(type);
        }
Example #12
0
        protected virtual bool ApplyMove(Move move, bool alreadyValidated, bool validateHasAnyValidMoves)
        {
            Utilities.ThrowIfNull(move, "move");
            if (!alreadyValidated && !IsValidMove(move))
            {
                return(false);
            }
            ChessPiece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            ChessPiece newPiece    = movingPiece;

            if (movingPiece.Piece == Piece.Pawn)
            {
                PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition);
                if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition).Piece == Piece.None)
                { // en passant
                    SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, ChessPiece.None);
                }
                if (move.NewPosition.Rank == (move.Player == Player.White ? Rank.Eight : Rank.One))
                {
                    newPiece = new ChessPiece(move.Promotion, move.Player);
                }
            }
            else if (movingPiece.Piece == Piece.King)
            {
                if (movingPiece.Player == Player.White)
                {
                    _whiteKingMoved = true;
                }
                else
                {
                    _blackKingMoved = true;
                }

                if (new PositionDistance(move.OriginalPosition, move.NewPosition).DistanceX == 2)
                {
                    Rank rank        = move.Player == Player.White ? Rank.One : Rank.Eight;
                    File rookFile    = move.NewPosition.File == File.C ? File.A : File.H;
                    File newRookFile = move.NewPosition.File == File.C ? File.D : File.F;
                    SetPieceAt(newRookFile, rank, new ChessPiece(Piece.Rook, move.Player));
                    SetPieceAt(rookFile, rank, ChessPiece.None);
                }
            }
            else if (movingPiece.Piece == Piece.Rook)
            {
                if (move.Player == Player.White)
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == Rank.One)
                    {
                        _whiteRookAMoved = true;
                    }
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == Rank.One)
                    {
                        _whiteRookHMoved = true;
                    }
                }
                else
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == Rank.Eight)
                    {
                        _blackRookAMoved = true;
                    }
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == Rank.Eight)
                    {
                        _blackRookHMoved = true;
                    }
                }
            }
            SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
            SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, ChessPiece.None);
            WhoseTurn = Utilities.GetOpponentOf(move.Player);
            _moves.Add(move);
            return(true);
        }
Example #13
0
        protected virtual bool IsValidMovePawn(Move move)
        {
            Utilities.ThrowIfNull(move, "move");
            PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);

            if ((posDelta.DistanceX != 0 || posDelta.DistanceY != 1) && (posDelta.DistanceX != 1 || posDelta.DistanceY != 1) &&
                (posDelta.DistanceX != 0 || posDelta.DistanceY != 2))
            {
                return(false);
            }
            if (move.Player == Player.White)
            {
                if ((int)move.OriginalPosition.Rank < (int)move.NewPosition.Rank)
                {
                    return(false);
                }
                if (move.NewPosition.Rank == Rank.Eight && move.Promotion == Piece.None)
                {
                    return(false);
                }
            }
            if (move.Player == Player.Black)
            {
                if ((int)move.OriginalPosition.Rank > (int)move.NewPosition.Rank)
                {
                    return(false);
                }
                if (move.NewPosition.Rank == Rank.One && move.Promotion == Piece.None)
                {
                    return(false);
                }
            }
            bool checkEnPassant = false;

            if (posDelta.DistanceY == 2)
            {
                if ((move.OriginalPosition.Rank != Rank.Two && move.Player == Player.White) ||
                    (move.OriginalPosition.Rank != Rank.Seven && move.Player == Player.Black))
                {
                    return(false);
                }
                if (move.OriginalPosition.Rank == Rank.Two && GetPieceAt(move.OriginalPosition.File, Rank.Three).Piece != Piece.None)
                {
                    return(false);
                }
                if (move.OriginalPosition.Rank == Rank.Seven && GetPieceAt(move.OriginalPosition.File, Rank.Six).Piece != Piece.None)
                {
                    return(false);
                }
            }
            if (posDelta.DistanceX == 0 && (posDelta.DistanceY == 1 || posDelta.DistanceY == 2))
            {
                if (GetPieceAt(move.NewPosition).Player != Player.None)
                {
                    return(false);
                }
            }
            else
            {
                if (GetPieceAt(move.NewPosition).Player != Utilities.GetOpponentOf(move.Player))
                {
                    checkEnPassant = true;
                }
                if (GetPieceAt(move.NewPosition).Player == move.Player)
                {
                    return(false);
                }
            }
            if (checkEnPassant)
            {
                if (_moves.Count == 0)
                {
                    return(false);
                }
                if ((move.OriginalPosition.Rank != Rank.Five && move.Player == Player.White) ||
                    (move.OriginalPosition.Rank != Rank.Four && move.Player == Player.Black))
                {
                    return(false);
                }
                Move latestMove = _moves[_moves.Count - 1];
                if (latestMove.Player != Utilities.GetOpponentOf(move.Player))
                {
                    return(false);
                }
                if (move.Player == Player.White)
                {
                    if (latestMove.OriginalPosition.Rank != Rank.Seven || latestMove.NewPosition.Rank != Rank.Five)
                    {
                        return(false);
                    }
                }
                else // (m.Player == Players.Black)
                {
                    if (latestMove.OriginalPosition.Rank != Rank.Two || latestMove.NewPosition.Rank != Rank.Four)
                    {
                        return(false);
                    }
                }
                if (move.NewPosition.File != latestMove.NewPosition.File)
                {
                    return(false);
                }
            }
            return(true);
        }
Example #14
0
        public virtual MoveType ApplyMove(Move move, bool alreadyValidated)
        {
            ChessUtilities.ThrowIfNull(move, "move");
            if (!alreadyValidated && !IsValidMove(move))
                return MoveType.Invalid;
            MoveType type = MoveType.Move;
            Piece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            Piece capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank);
            Piece newPiece = movingPiece;
            bool isCapture = capturedPiece != null;
            CastlingType castle = CastlingType.None;
            if (movingPiece is Pawn)
            {
                _halfMoveClock = 0;
                PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition);
                if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition) == null)
                { // en passant
                    isCapture = true;
                    SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null);
                }
                if (move.NewPosition.Rank == (move.Player == Player.White ? 8 : 1))
                {
                    newPiece = MapPgnCharToPiece(move.Promotion.Value, move.Player);
                    type |= MoveType.Promotion;
                }
            }
            else if (movingPiece is King)
            {
                if (movingPiece.Owner == Player.White)
                    CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false;
                else
                    CanBlackCastleKingSide = CanBlackCastleQueenSide = false;

                if (new PositionDistance(move.OriginalPosition, move.NewPosition).DistanceX == 2 && CastlingCanBeLegal)
                {
                    castle = ApplyCastle(move);
                    type |= MoveType.Castling;
                }
            }
            else if (movingPiece is Rook)
            {
                if (move.Player == Player.White)
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 1)
                        CanWhiteCastleQueenSide = false;
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 1)
                        CanWhiteCastleKingSide = false;
                }
                else
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 8)
                        CanBlackCastleQueenSide = false;
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 8)
                        CanBlackCastleKingSide = false;
                }
            }
            if (isCapture)
            {
                type |= MoveType.Capture;
                _halfMoveClock = 0;
                if (move.NewPosition.File == File.A && move.NewPosition.Rank == 1)
                    CanWhiteCastleQueenSide = false;
                else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 1)
                    CanWhiteCastleKingSide = false;
                else if (move.NewPosition.File == File.A && move.NewPosition.Rank == 8)
                    CanBlackCastleQueenSide = false;
                else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 8)
                    CanBlackCastleKingSide = false;
            }
            if (!isCapture && !(movingPiece is Pawn))
            {
                _halfMoveClock++;
                if (_halfMoveClock >= 100)
                {
                    fiftyMoves = true;
                }
                else
                {
                    fiftyMoves = false;
                }
            }
            if (move.Player == Player.Black)
            {
                _fullMoveNumber++;
            }
            SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
            SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null);
            WhoseTurn = ChessUtilities.GetOpponentOf(move.Player);
            _moves.Add(new DetailedMove(move, movingPiece, isCapture, castle));
            return type;
        }