Example #1
0
        private static Position CalculateTo(ChessPlayer owner, CastlingType castlingType)
        {
            switch (owner)
            {
            case ChessPlayer.White:
                switch (castlingType)
                {
                case CastlingType.Long: return(Positions.C1);

                case CastlingType.Short: return(Positions.G1);

                default: throw new ArgumentOutOfRangeException(nameof(castlingType), owner, null);
                }

            case ChessPlayer.Black:
                switch (castlingType)
                {
                case CastlingType.Long: return(Positions.C8);

                case CastlingType.Short: return(Positions.G8);

                default: throw new ArgumentOutOfRangeException(nameof(castlingType), owner, null);
                }

            default: throw new ArgumentOutOfRangeException(nameof(owner), owner, null);
            }
        }
Example #2
0
        private static void PopulateKingCastlingMoves(
            ICollection <GameMoveData2> resultMoves,
            Square sourceSquare,
            Bitboard target,
            CastlingOptions allowedCastlingOptions,
            Bitboard nonEmptySquares,
            CastlingType castlingType)
        {
            var option = castlingType.ToOption();

            if ((allowedCastlingOptions & option) == 0)
            {
                return;
            }

            var info = KingCastlingInfos[GetCastlingTypeArrayIndexInternal(castlingType)];

            if (info.KingMove.From != sourceSquare || (info.ExpectedEmptySquares & nonEmptySquares).IsAny ||
                (info.KingMove.To.Bitboard & target).IsNone)
            {
                return;
            }

            var moveData = new GameMoveData2(info.KingMove, GameMoveFlags.IsKingCastling);

            resultMoves.Add(moveData);
        }
Example #3
0
 public DetailedMove(Position originalPosition, Position newPosition, Player player, char?promotion, Piece piece, bool isCapture, CastlingType castling) :
     base(originalPosition, newPosition, player, promotion)
 {
     Piece     = piece;
     IsCapture = isCapture;
     Castling  = castling;
 }
Example #4
0
 public DetailedMove(Position originalPosition, Position newPosition, Player player, char? promotion, Piece piece, bool isCapture, CastlingType castling) : 
     base(originalPosition, newPosition, player, promotion)
 {
     Piece = piece;
     IsCapture = isCapture;
     Castling = castling;
 }
Example #5
0
        public static long GetCastlingHash(CastlingType castlingType)
        {
            var castlingIndex = CastlingMap[castlingType];
            var result        = (long)Randoms[RandomsCastlingOffset + castlingIndex];

            return(result);
        }
        internal CastlingInfo2(
            CastlingType castlingType,
            GameMove2 kingMove,
            GameMove2 rookMove,
            [NotNull] params Square[] emptySquares)
        {
            castlingType.EnsureDefined();

            if (emptySquares is null)
            {
                throw new ArgumentNullException(nameof(emptySquares));
            }

            if (kingMove.From.Rank != kingMove.To.Rank ||
                Math.Abs(kingMove.From.SquareIndex - kingMove.To.SquareIndex) != 2)
            {
                throw new ArgumentException(
                          $@"Invalid castling move '{kingMove.ToUciNotation()}'.",
                          nameof(kingMove));
            }

            CastlingType = castlingType;
            CastlingSide = castlingType.GetSide();
            Option       = castlingType.ToOption();
            KingMove     = kingMove;
            RookMove     = rookMove;
            EmptySquares = emptySquares.AsReadOnly();
            PassedSquare = new Square((kingMove.From.SquareIndex + kingMove.To.SquareIndex) / 2);
            GameSide     = Option.IsAnySet(CastlingOptions.WhiteMask) ? GameSide.White : GameSide.Black;
        }
        /// <summary>
        /// Removes castling possibility Zobrist hash.
        /// </summary>
        /// <param name="color">The piece color.</param>
        /// <param name="castlingType">The castling type.</param>
        /// <param name="bitboard">The bitboard.</param>
        public static void RemoveCastlingPossibility(Color color, CastlingType castlingType, Bitboard bitboard)
        {
            var castlingIndex = FastArray.GetCastlingIndex(color, castlingType);

            if (bitboard.CastlingPossibility[castlingIndex])
            {
                bitboard.Hash ^= ZobristContainer.Castling[castlingIndex];
            }
        }
        public static string CastlingTypeToNotation(CastlingType castlingType)
        {
            switch (castlingType)
            {
                case CastlingType.KingSide:
                    return "O-O";
                case CastlingType.QueenSide:
                    return "O-O-O";
            }

            return "";
        }
Example #9
0
        public KingCastlingMove(ChessPlayer owner, CastlingType castlingType)
            : base(owner, CalculateFrom(owner), CalculateTo(owner, castlingType))
        {
            CastlingType = castlingType;
            switch (owner)
            {
            case ChessPlayer.White:
                switch (castlingType)
                {
                case CastlingType.Long:
                    RookFrom = Positions.A1;
                    RookTo   = Positions.D1;
                    break;

                case CastlingType.Short:
                    RookFrom = Positions.H1;
                    RookTo   = Positions.F1;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(castlingType), owner, null);
                }
                break;

            case ChessPlayer.Black:
                switch (castlingType)
                {
                case CastlingType.Long:
                    RookFrom = Positions.A8;
                    RookTo   = Positions.D8;
                    break;

                case CastlingType.Short:
                    RookFrom = Positions.H8;
                    RookTo   = Positions.F8;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(castlingType), owner, null);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(owner), owner, null);
            }
        }
        protected override MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured, out CastlingType castlingType)
        {
            MoveType type = base.ApplyMove(move, alreadyValidated, out captured, out castlingType);

            if (!type.HasFlag(MoveType.Capture))
            {
                return(type);
            }
            var surroundingSquares = new int[][] { new int[] { 1, 0 }, new int[] { 1, 1 }, new int[] { 0, 1 }, new int[] { -1, -1 },
                                                   new int[] { -1, 0 }, new int[] { 0, -1 }, new int[] { -1, 1 }, new int[] { 1, -1 } };

            SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, null);
            foreach (int[] surroundingSquaresDistance in surroundingSquares)
            {
                File f = move.NewPosition.File + surroundingSquaresDistance[0];
                int  r = move.NewPosition.Rank + surroundingSquaresDistance[1];
                if (f < 0 || (int)f >= BoardWidth || r < 1 || r > BoardHeight)
                {
                    continue;
                }
                if (!(GetPieceAt(f, r) is Pawn))
                {
                    SetPieceAt(f, r, null);
                }
            }

            if (CanBlackCastleKingSide && GetPieceAt(InitialBlackRookFileKingsideCastling, 8) == null)
            {
                CanBlackCastleKingSide = false;
            }
            if (CanBlackCastleQueenSide && GetPieceAt(InitialBlackRookFileQueensideCastling, 8) == null)
            {
                CanBlackCastleQueenSide = false;
            }
            if (CanWhiteCastleKingSide && GetPieceAt(InitialWhiteRookFileKingsideCastling, 1) == null)
            {
                CanWhiteCastleKingSide = false;
            }
            if (CanWhiteCastleQueenSide && GetPieceAt(InitialWhiteRookFileQueensideCastling, 1) == null)
            {
                CanWhiteCastleQueenSide = false;
            }

            return(type);
        }
Example #11
0
 public DetailedMove(Position originalPosition, Position newPosition, Player player, char?promotion, Piece piece, bool isCapture, CastlingType castling, string san, Piece captured, int?lastHalfMoveClock, bool enPassant)
     : this(originalPosition, newPosition, player, promotion, piece, isCapture, castling, san)
 {
     CapturedPiece     = captured;
     LastHalfMoveClock = lastHalfMoveClock;
     EnPassant         = enPassant;
 }
Example #12
0
 public DetailedMove(Move move, Piece piece, Piece capturedPiece, CastlingType castling, string san, int halfMoveClock, bool enPassant)
     : this(move.OriginalPosition, move.NewPosition, move.Player, move.Promotion, piece, capturedPiece != null, castling, san, capturedPiece, halfMoveClock, enPassant)
 {
 }
Example #13
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 #14
0
 /// <summary>
 /// 构造函数。
 /// </summary>
 /// <param name="originalPosition"></param>
 /// <param name="newPosition"></param>
 /// <param name="player"></param>
 /// <param name="promotion"></param>
 /// <param name="piece"></param>
 /// <param name="isCapture"></param>
 /// <param name="castling"></param>
 /// <param name="capturedPiece"></param>
 /// <param name="isEnpassant"></param>
 /// <param name="isChecking"></param>
 /// <param name="isCheckmate"></param>
 public MoreDetailedMove(Position originalPosition, Position newPosition, Player player, char? promotion, Piece piece, bool isCapture, CastlingType castling, Piece capturedPiece, bool isEnpassant, bool isChecking, bool isCheckmate) : base(originalPosition, newPosition, player, promotion, piece, isCapture, castling)
 {
     CapturedPiece = capturedPiece;
     IsEnpassant = isEnpassant;
     IsChecking = isChecking;
     IsCheckmate = isCheckmate;
 }
        protected override MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured, out CastlingType castlingType)
        {
            MoveType ret = base.ApplyMove(move, alreadyValidated, out captured, out castlingType);

            if (ret == MoveType.Invalid)
            {
                return(ret);
            }

            if (WhoseTurn == Player.White && IsInCheck(Player.White))
            {
                ChecksByBlack++;
            }
            if (WhoseTurn == Player.Black && IsInCheck(Player.Black))
            {
                ChecksByWhite++;
            }

            return(ret);
        }
Example #16
0
 public static CastlingOptions ToOption(this CastlingType castlingType)
 {
     return(unchecked ((CastlingOptions)(1 << (int)castlingType)));
 }
 private static int GetCastlingTypeArrayIndexInternal(CastlingType castlingType)
 {
     return((int)castlingType);
 }
Example #18
0
 public CastlingMove(CastlingType castlingType, Piece movingPiece, Space newSpace) : base(movingPiece, newSpace)
 {
     this.castlingType = castlingType;
 }
Example #19
0
 private static int GetCastlingTypeArrayIndexInternal(CastlingType castlingType) => (int)castlingType;
Example #20
0
 public DetailedMove(Move move, Piece piece, bool isCapture, CastlingType castling)
     : this(move.OriginalPosition, move.NewPosition, move.Player, move.Promotion, piece, isCapture, castling)
 {
 }
Example #21
0
 private static bool Castling(Player currentPlayer, CastlingType castlingType, Figures[,] board)
 {
     return(true);
 }
Example #22
0
 public DetailedMove(Move move, Piece piece, bool isCapture, CastlingType castling)
     : this(move.OriginalPosition, move.NewPosition, move.Player, move.Promotion, piece, isCapture, castling)
 {
 }
Example #23
0
 /// <summary>
 /// Checks if castling with the specified type is possible.
 /// </summary>
 /// <param name="type">The castling type.</param>
 /// <param name="opt">The generator parameters.</param>
 /// <returns>True if castling is possible, otherwise false.</returns>
 private static bool IsCastlingPossible(CastlingType type, GeneratorParameters opt)
 {
     return(opt.Bitboard.CastlingPossibility[FastArray.GetCastlingIndex(opt.FriendlyColor, type)]);
 }
 public static bool Castling(Player currentPlayer, CastlingType castlingType, Cell[,] board)
 {
     // TODO: implement later
     return(true);
 }
        protected override MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured, out CastlingType castlingType)
        {
            MoveType ret = base.ApplyMove(move, alreadyValidated, out captured, out castlingType);

            if (ret.HasFlag(MoveType.Capture))
            {
                (move.Player == Player.White ? whitePocket : blackPocket).Add(!captured.IsPromotionResult ? captured.GetWithInvertedOwner() : new Pawn(ChessUtilities.GetOpponentOf(captured.Owner)));
            }
            return(ret);
        }
Example #26
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 #27
0
 public MoreDetailedMove(Move move, Piece piece, bool isCapture, CastlingType castling, Piece capturedPiece, bool isEnpassant, bool isChecking, bool isCheckmate) : this(move.OriginalPosition, move.NewPosition, move.Player, move.Promotion, piece, isCapture, castling, capturedPiece, isEnpassant, isChecking, isCheckmate)
 { }
Example #28
0
 public static CastlingSide GetSide(this CastlingType castlingType)
 {
     //// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
     //// ReSharper disable once RedundantOverflowCheckingContext
     return((CastlingSide) unchecked ((int)castlingType & 1));
 }
Example #29
0
 public static int GetCastlingIndex(Color color, CastlingType castlingType)
 {
     return(((int)color << 1) + (int)castlingType);
 }
Example #30
0
 public CastlingTemplate(CastlingType type)
     : base(null, false, true)
 {
     CType = type;
 }
Example #31
0
        protected virtual string GetSanForMove(Move move, Piece movingPiece, bool isCapture, CastlingType castle, List <Position> ambiguities)
        {
            if (castle == CastlingType.KingSide)
            {
                return("O-O");
            }
            if (castle == CastlingType.QueenSide)
            {
                return("O-O-O");
            }

            bool needsUnambigFile = false;
            bool needsUnambigRank = false;

            if (ambiguities.Count > 0)
            {
                foreach (Position amb in ambiguities)
                {
                    if (amb.Rank == move.OriginalPosition.Rank)
                    {
                        needsUnambigFile = true;
                    }
                    if (amb.File == move.OriginalPosition.File)
                    {
                        needsUnambigRank = true;
                    }
                }
                if (!needsUnambigFile && !needsUnambigRank)
                {
                    needsUnambigFile = true;
                }
            }

            StringBuilder sanBuilder = new StringBuilder();

            if (!(movingPiece is Pawn))
            {
                sanBuilder.Append(char.ToUpperInvariant(movingPiece.GetFenCharacter()));
            }
            else if (isCapture)
            {
                sanBuilder.Append(move.OriginalPosition.File.ToString().ToLowerInvariant());
                needsUnambigFile = false;
                needsUnambigRank = false;
            }
            if (needsUnambigFile)
            {
                sanBuilder.Append(move.OriginalPosition.File.ToString().ToLowerInvariant());
            }
            if (needsUnambigRank)
            {
                sanBuilder.Append(move.OriginalPosition.Rank.ToString());
            }
            if (isCapture)
            {
                sanBuilder.Append("x");
            }
            sanBuilder.Append(move.NewPosition.ToString().ToLowerInvariant());
            if (move.Promotion.HasValue)
            {
                sanBuilder.Append("=");
                sanBuilder.Append(move.Promotion.Value);
            }
            if (IsWinner(ChessUtilities.GetOpponentOf(WhoseTurn)))
            {
                sanBuilder.Append("#");
            }
            else if (IsInCheck(WhoseTurn))
            {
                sanBuilder.Append("+");
            }
            return(sanBuilder.ToString());
        }
Example #32
0
        public virtual MoveType ApplyMove(Move move, bool alreadyValidated)
        {
            ChessUtility.ThrowIfNull(move, "move");
            if (!alreadyValidated && !IsValidMove(move))
            {
                return(MoveType.Invalid);
            }
            MoveType     type          = MoveType.Move;
            ChessPiece   movingPiece   = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            ChessPiece   capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank);
            ChessPiece   newPiece      = movingPiece;
            bool         isCapture     = capturedPiece != null;
            CastlingType castle        = CastlingType.None;

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

                if (new BoardDistance(move.OriginalPosition, move.NewPosition).X == 2 && CastlingCanBeLegal)
                {
                    castle = ApplyCastle(move);
                    type  |= MoveType.Castling;
                }
            }
            else if (movingPiece is Rook)
            {
                if (move.Player == ChessPlayer.White)
                {
                    if (move.OriginalPosition.File == ChessFile.A && move.OriginalPosition.Rank == 1)
                    {
                        CanWhiteCastleQueenSide = false;
                    }
                    else if (move.OriginalPosition.File == ChessFile.H && move.OriginalPosition.Rank == 1)
                    {
                        CanWhiteCastleKingSide = false;
                    }
                }
                else
                {
                    if (move.OriginalPosition.File == ChessFile.A && move.OriginalPosition.Rank == 8)
                    {
                        CanBlackCastleQueenSide = false;
                    }
                    else if (move.OriginalPosition.File == ChessFile.H && move.OriginalPosition.Rank == 8)
                    {
                        CanBlackCastleKingSide = false;
                    }
                }
            }
            if (isCapture)
            {
                type          |= MoveType.Capture;
                _halfMoveClock = 0;
                if (move.NewPosition.File == ChessFile.A && move.NewPosition.Rank == 1)
                {
                    CanWhiteCastleQueenSide = false;
                }
                else if (move.NewPosition.File == ChessFile.H && move.NewPosition.Rank == 1)
                {
                    CanWhiteCastleKingSide = false;
                }
                else if (move.NewPosition.File == ChessFile.A && move.NewPosition.Rank == 8)
                {
                    CanBlackCastleQueenSide = false;
                }
                else if (move.NewPosition.File == ChessFile.H && move.NewPosition.Rank == 8)
                {
                    CanBlackCastleKingSide = false;
                }
            }
            if (!isCapture && !(movingPiece is Pawn))
            {
                _halfMoveClock++;
                if (_halfMoveClock >= 100)
                {
                    fiftyMoves = true;
                }
                else
                {
                    fiftyMoves = false;
                }
            }
            if (move.Player == ChessPlayer.Black)
            {
                _fullMoveNumber++;
            }
            SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
            SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null);
            WhoseTurn = ChessUtility.GetOpponentOf(move.Player);
            _moves.Add(new DetailedMove(move, movingPiece, isCapture, castle));
            _positions.Add(GetPosition());
            return(type);
        }
Example #33
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CastlingMove"/> class.
 /// </summary>
 /// <param name="from">The source piece position.</param>
 /// <param name="to">The destination piece position.</param>
 /// <param name="piece">The piece type.</param>
 /// <param name="color">The piece color.</param>
 /// <param name="castlingType">The castling type.</param>
 public CastlingMove(Position from, Position to, PieceType piece, Color color, CastlingType castlingType)
     : base(from, to, piece, color)
 {
     CastlingType = castlingType;
 }