예제 #1
0
        public void UnMake()
        {
            if (!MoveHistory.Any())
            {
                throw new Exception("No move to unmake");
            }
            int MoveToUnmake  = MoveHistory.Pop();
            int ColorMadeMove = 1 - ColorToMove;

            int fromSquare = Move.FromSquare(MoveToUnmake);
            int toSquare   = Move.ToSquare(MoveToUnmake);
            int fromPiece  = Move.FromPiece(MoveToUnmake);
            int toPiece    = Move.ToPiece(MoveToUnmake);

            MovesFiftyHistory.Pop();


            //Moving Back And Cancelling Capturing
            SquarePiece[toSquare]   = toPiece;
            SquarePiece[fromSquare] = fromPiece;

            PieceBitboard[fromPiece] ^= 1UL << fromSquare;              //no changes
            PieceBitboard[fromPiece] ^= 1UL << toSquare;                //no changes

            PieceBitboard[fromPiece & Color.Mask] ^= 1UL << fromSquare; //no changes
            PieceBitboard[fromPiece & Color.Mask] ^= 1UL << toSquare;   //no changes

            OccupiedBB ^= 1UL << fromSquare;                            //no changes
            if (toPiece != 0)
            {
                PieceBitboard[toPiece] ^= 1UL << toSquare;
                PieceBitboard[toPiece & Color.Mask] ^= 1UL << toSquare;

                int EnemyLeftRookIndex = 56 * ColorMadeMove;
                if (toSquare == EnemyLeftRookIndex && toPiece == Piece.Rook && CastleShortIndex[1 - ColorMadeMove] <= 0)
                {
                    CastleShortIndex[1 - ColorMadeMove]++;
                }
                else if (toSquare == EnemyLeftRookIndex + 7 && toPiece == Piece.Rook && CastleLongIndex[1 - ColorMadeMove] <= 0)
                {
                    CastleShortIndex[1 - ColorMadeMove]++;
                }
            }
            else
            {
                OccupiedBB ^= 1UL << toSquare;
            }

            if (CastleShortIndex[ColorMadeMove] <= 0)
            {
                CastleShortIndex[ColorMadeMove]++;
            }
            if (CastleLongIndex[ColorMadeMove] <= 0)
            {
                CastleLongIndex[ColorMadeMove]++;
            }
            if (CastleShortIndex[1 - ColorMadeMove] <= 0)
            {
                CastleShortIndex[1 - ColorMadeMove]++;
            }
            if (CastleLongIndex[1 - ColorMadeMove] <= 0)
            {
                CastleLongIndex[1 - ColorMadeMove]++;
            }

            //Castling Back
            if (Move.Castling(MoveToUnmake))
            {
                int sidePreIndex = 56 * ColorMadeMove;

                int rookSquare, rookToSquare;
                //Short castling (getting rook position)
                if (File(toSquare) == 6)
                {
                    rookSquare   = sidePreIndex + 7;
                    rookToSquare = fromSquare + 1;
                }
                //Long castling (getting rook position)
                else
                {
                    rookSquare   = sidePreIndex;
                    rookToSquare = fromSquare - 1;
                }

                //Moving the rook back
                SquarePiece[rookSquare]   = SquarePiece[rookToSquare];
                SquarePiece[rookToSquare] = 0;

                OccupiedBB ^= 1UL << rookSquare;
                OccupiedBB ^= 1UL << rookToSquare;

                PieceBitboard[Piece.Rook | ColorMadeMove] ^= 1UL << rookSquare;
                PieceBitboard[Piece.Rook | ColorMadeMove] ^= 1UL << rookToSquare;

                PieceBitboard[ColorMadeMove] ^= 1UL << rookSquare;
                PieceBitboard[ColorMadeMove] ^= 1UL << rookToSquare;
            }

            //Promotion
            if (Move.Promotion(MoveToUnmake))
            {
                int PromotedTo = Move.PromotionPiece(MoveToUnmake); //Either queen, knight, bishop or rook
                //SquarePiece[toSquare] = PromotedTo;

                //If we are here, we've just set the PieceBitboard[fromPiece] to 1 at the toSquare thinking of doing the opposite, so we need to cancel that
                PieceBitboard[fromPiece]  ^= 1UL << toSquare;
                PieceBitboard[PromotedTo] ^= 1UL << toSquare;

                //Color maps do not change, as well as occupied (we're just replacing the piece)
            }

            //Enpassant
            if (Move.EnPassant(MoveToUnmake))
            {
                //Restoring the pawn
                int    EnPassantVictimSquare   = toSquare + 16 * ColorMadeMove - 8;
                UInt64 enPassantVictimBitboard = 1UL << EnPassantVictimSquare;

                OccupiedBB ^= enPassantVictimBitboard;
                PieceBitboard[Piece.Pawn | ColorToMove] ^= enPassantVictimBitboard;
                PieceBitboard[ColorToMove]        ^= enPassantVictimBitboard;
                SquarePiece[EnPassantVictimSquare] = Piece.Pawn | ColorToMove;
            }

            ColorToMove = ColorMadeMove;
            EnPassantHistory.Pop();
        }