Пример #1
0
        private static CastlingRights UpdateCastlingRightsForSide(CastlingRights castlingRights, Board newBoard, Side side)
        {
            if ((Castling.KingSideRookFrom(side) & newBoard[side, Piece.Rook]) == 0)
            {
                castlingRights = castlingRights.RemoveKingSide(side);
            }

            if ((Castling.QueenSideRookFrom(side) & newBoard[side, Piece.Rook]) == 0)
            {
                castlingRights = castlingRights.RemoveQueenSide(side);
            }

            return(castlingRights);
        }
Пример #2
0
        internal static void AddCastlingMoves(Position position, List <Move> allMoves)
        {
            Side  side  = position.SideToMove;
            Board board = position.Board;

            if (board[side, Piece.King] == 0)
            {
                return;
            }

            if (Castling.CanCastleKingside(position.CastlingRights, side))
            {
                var  kingsideBetween = Castling.KingSideBetween(side);
                bool spaceAvailable  = BitUtils.IsASubsetOfB(kingsideBetween, board.EmptySquares);

                var      kingsideChecks = Castling.KingSideChecks(side);
                Bitboard enemyAttacks   = board.AttacksBy(position.OpposingSide);
                bool     avoidsChecks   = (kingsideChecks & enemyAttacks) == 0;

                if (spaceAvailable && avoidsChecks)
                {
                    Bitboard king         = board[side, Piece.King];
                    Bitboard castleTarget = king.EastOne().EastOne();
                    Square   from         = (Square)king.Serialize()[0];
                    Square   to           = (Square)castleTarget.Serialize()[0];

                    allMoves.Add(new Move(from, to, MoveFlags.KingCastle));
                }
            }

            if (Castling.CanCastleQueenside(position.CastlingRights, side))
            {
                var  queensideBetween = Castling.QueenSideBetween(side);
                bool spaceAvailable   = BitUtils.IsASubsetOfB(queensideBetween, board.EmptySquares);

                var      queensideChecks = Castling.QueenSideChecks(side);
                Bitboard enemyAttacks    = board.AttacksBy(position.OpposingSide);
                bool     avoidsChecks    = (queensideChecks & enemyAttacks) == 0;

                if (spaceAvailable && avoidsChecks)
                {
                    Bitboard king         = board[side, Piece.King];
                    Bitboard castleTarget = king.WestOne().WestOne();
                    Square   from         = (Square)king.Serialize()[0];
                    Square   to           = (Square)castleTarget.Serialize()[0];

                    allMoves.Add(new Move(from, to, MoveFlags.QueenCastle));
                }
            }
        }
Пример #3
0
        public static void ApplyMoveToBoard(Board board, Move move, out Piece fromPiece)
        {
            (Side fromSide, Piece fromPiece_) = board.GetPieceOnSquare(move.From);
            fromPiece = fromPiece_;
            Bitboard from   = Bitboard.FromSquare(move.From);
            Bitboard to     = Bitboard.FromSquare(move.To);
            Bitboard fromTo = from | to;

            if (move.Flags == MoveFlags.EnPassantCapture)
            {
                Bitboard capturedPawn = fromSide switch
                {
                    Side.White => to.SoutOne(),
                    Side.Black => to.NortOne(),
                    _ => throw new IndexOutOfRangeException(nameof(fromSide))
                };

                board[fromSide.OpposingSide(), Piece.Pawn] ^= capturedPawn;
            }
            else if (move.IsCapture)
            {
                (Side toSide, Piece toPiece) = board.GetPieceOnSquare(move.To);
                board[toSide, toPiece]      ^= to;
            }
            else if (move.Flags == MoveFlags.KingCastle)
            {
                board[fromSide, Piece.Rook] ^= Castling.KingSideRookToFrom(fromSide);
            }
            else if (move.Flags == MoveFlags.QueenCastle)
            {
                board[fromSide, Piece.Rook] ^= Castling.QueenSideRookToFrom(fromSide);
            }

            board[fromSide, fromPiece] ^= fromTo;

            if (move.IsPromotion)
            {
                board[fromSide, fromPiece] ^= to;
                board[fromSide, move.PromotionPiece !.Value] ^= to;