예제 #1
0
        public void CanGenerateBitboardFromNullableSquare(Square?square, ulong expectedBitboard)
        {
            // Act
            var bb = Bitboard.FromSquare(square);

            // Assert
            Assert.Equal <Bitboard>(expectedBitboard, bb);
        }
예제 #2
0
        private static void AddMovesFromAttacks(Bitboard attacks, Square from, Side sideToMove, Board board, List <Move> allMoves)
        {
            Bitboard validAttacks = attacks & ~board.FriendlyPieces(sideToMove);

            int[] targetSquares = validAttacks.Serialize();
            for (int t = 0; t < targetSquares.Length; t++)
            {
                Square to        = (Square)targetSquares[t];
                bool   isCapture = (Bitboard.FromSquare(to) & board.OpposingPieces(sideToMove)) != 0;

                if (isCapture)
                {
                    (_, Piece targetPiece) = board.GetPieceOnSquare(to);
                    allMoves.Add(new Move(from, to, MoveFlags.Capture, targetPiece));
                }
                else
                {
                    allMoves.Add(new Move(from, to, MoveFlags.QuietMove));
                }
            }
        }
예제 #3
0
파일: Mover.cs 프로젝트: DM-Francis/ChessDF
        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;
예제 #4
0
        internal static void AddAllPawnMoves(Position position, List <Move> allMoves)
        {
            Board    board           = position.Board;
            Side     sideToMove      = position.SideToMove;
            Bitboard enPassantTarget = Bitboard.FromSquare(position.EnPassantSquare);
            Bitboard pawns           = board[sideToMove, Piece.Pawn];

            // Single pushes
            Bitboard singlePawnPushTargets = PawnMoves.PawnSinglePushTargets(pawns, board.EmptySquares, sideToMove);
            Bitboard singlePawnPushSources = sideToMove == Side.White ? singlePawnPushTargets.SoutOne() : singlePawnPushTargets.NortOne();

            AddPawnPushes(singlePawnPushTargets, singlePawnPushSources, allMoves, false);

            // Double pushes
            Bitboard doublePawnPushTargets = PawnMoves.PawnDoublePushTargets(pawns, board.EmptySquares, sideToMove);
            Bitboard doublePawnPushSources = sideToMove == Side.White ? doublePawnPushTargets.SoutOne().SoutOne() : doublePawnPushTargets.NortOne().NortOne();

            AddPawnPushes(doublePawnPushTargets, doublePawnPushSources, allMoves, true);

            // Pawn captures
            int[] pawnSquares = pawns.Serialize();
            for (int p = 0; p < pawnSquares.Length; p++)
            {
                Square   from = (Square)pawnSquares[p];
                Bitboard validAttacks;
                if (sideToMove == Side.White)
                {
                    validAttacks = PawnMoves.WhitePawnAttacks(from) & (board.BlackPieces | enPassantTarget);
                }
                else if (sideToMove == Side.Black)
                {
                    validAttacks = PawnMoves.BlackPawnAttacks(from) & (board.WhitePieces | enPassantTarget);
                }
                else
                {
                    throw new IndexOutOfRangeException(nameof(sideToMove));
                }

                int[] targetSquares = validAttacks.Serialize();
                for (int t = 0; t < targetSquares.Length; t++)
                {
                    Square to = (Square)targetSquares[t];

                    if (to == position.EnPassantSquare)
                    {
                        allMoves.Add(new Move(from, to, MoveFlags.EnPassantCapture, Piece.Pawn));
                        continue;
                    }

                    (_, Piece targetPiece) = board.GetPieceOnSquare(to);
                    if (IsFinalRank(to))
                    {
                        var promotions = new[]
                        {
                            new Move(from, to, MoveFlags.Capture | MoveFlags.KnightPromotion, targetPiece),
                            new Move(from, to, MoveFlags.Capture | MoveFlags.BishopPromotion, targetPiece),
                            new Move(from, to, MoveFlags.Capture | MoveFlags.RookPromotion, targetPiece),
                            new Move(from, to, MoveFlags.Capture | MoveFlags.QueenPromotion, targetPiece),
                        };
                        allMoves.AddRange(promotions);
                    }
                    else
                    {
                        var flags = to == position.EnPassantSquare ? MoveFlags.EnPassantCapture : MoveFlags.Capture;
                        allMoves.Add(new Move(from, to, flags, targetPiece));
                    }
                }
            }
        }