示例#1
0
        public static BitBoard XrayRookAttacks(this Square square, BitBoard occupied, BitBoard blockers)
        {
            var attacks = square.RookAttacks(occupied);

            blockers &= attacks;
            return(attacks ^ square.RookAttacks(occupied ^ blockers));
        }
示例#2
0
 public static BitBoard NorthFill(this BitBoard bb)
 {
     bb |= bb << 8;
     bb |= bb << 16;
     bb |= bb << 32;
     return(bb);
 }
示例#3
0
 public static BitBoard SouthFill(this BitBoard bb)
 {
     bb |= bb >> 8;
     bb |= bb >> 16;
     bb |= bb >> 32;
     return(bb);
 }
示例#4
0
        private static EMoveAmbiguity Ambiguity(this Move move, BitBoard similarTypeAttacks, IPosition position)
        {
            var ambiguity = EMoveAmbiguity.None;

            foreach (var square in similarTypeAttacks)
            {
                var pinned = position.GetPinnedPieces(square, move.GetMovingSide());

                if (similarTypeAttacks & pinned)
                {
                    continue;
                }

                if (move.GetMovingPieceType() != position.GetPieceType(square))
                {
                    continue;
                }

                if (position.OccupiedBySide[move.GetMovingSide().Side] & square)
                {
                    if (square.File() == move.GetFromSquare().File())
                    {
                        ambiguity |= EMoveAmbiguity.File;
                    }
                    else if (square.Rank() == move.GetFromSquare().Rank())
                    {
                        ambiguity |= EMoveAmbiguity.Rank;
                    }

                    ambiguity |= EMoveAmbiguity.Move;
                }
            }

            return(ambiguity);
        }
示例#5
0
        public static Square Lsb(this BitBoard bb)
        {
            // @ C author Matt Taylor (2003)
            bb ^= bb - 1;
            var folded = (uint)(bb ^ (bb >> 32));

            return(Lsb64Table[folded * 0x78291ACF >> 26]);
        }
示例#6
0
        public static BitBoard Shift(this BitBoard bb, Direction direction)
        {
            if (ShiftFuncs.TryGetValue(direction.Value, out var func))
            {
                return(func(bb));
            }

            throw new ArgumentException("Invalid shift argument.", nameof(direction));
        }
示例#7
0
        static BitBoards()
        {
            PseudoAttacksBB = new BitBoard[PieceTypes.PieceTypeNb.AsInt()][];
            for (var i = 0; i < PseudoAttacksBB.Length; i++)
            {
                PseudoAttacksBB[i] = new BitBoard[64];
            }

            PawnAttackSpanBB    = new BitBoard[2][];
            PawnAttackSpanBB[0] = new BitBoard[64];
            PawnAttackSpanBB[1] = new BitBoard[64];

            PassedPawnMaskBB    = new BitBoard[2][];
            PassedPawnMaskBB[0] = new BitBoard[64];
            PassedPawnMaskBB[1] = new BitBoard[64];

            ForwardRanksBB    = new BitBoard[2][];
            ForwardRanksBB[0] = new BitBoard[64];
            ForwardRanksBB[1] = new BitBoard[64];

            ForwardFileBB    = new BitBoard[2][];
            ForwardFileBB[0] = new BitBoard[64];
            ForwardFileBB[1] = new BitBoard[64];

            KingRingBB    = new BitBoard[2][];
            KingRingBB[0] = new BitBoard[64];
            KingRingBB[1] = new BitBoard[64];

            BetweenBB = new BitBoard[64][];
            for (var i = 0; i < BetweenBB.Length; i++)
            {
                BetweenBB[i] = new BitBoard[64];
            }

            LineBB = new BitBoard[64][];
            for (var i = 0; i < LineBB.Length; i++)
            {
                LineBB[i] = new BitBoard[64];
            }

            SquareDistance = new int[64][];
            for (var i = 0; i < SquareDistance.Length; i++)
            {
                SquareDistance[i] = new int[64];
            }

            DistanceRingBB = new BitBoard[64][];
            for (var i = 0; i < SquareDistance.Length; i++)
            {
                DistanceRingBB[i] = new BitBoard[8];
            }

            CornerA1 = MakeBitboard(Squares.a1, Squares.b1, Squares.a2, Squares.b2);
            CornerA8 = MakeBitboard(Squares.a8, Squares.b8, Squares.a7, Squares.b7);
            CornerH1 = MakeBitboard(Squares.h1, Squares.g1, Squares.h2, Squares.g2);
            CornerH8 = MakeBitboard(Squares.h8, Squares.g8, Squares.h7, Squares.g7);
示例#8
0
 public static void ToString(this BitBoard bb, TextWriter outputWriter)
 {
     try
     {
         outputWriter.WriteLine(bb);
     }
     catch (IOException ioException)
     {
         throw new IOException("Writer is not available.", ioException);
     }
 }
示例#9
0
        public static int PopCount(BitBoard bb)
        {
            var y = 0;

            while (bb)
            {
                y++;
                ResetLsb(ref bb);
            }

            return(y);
        }
示例#10
0
        public static Square Msb(this BitBoard bb)
        {
            const ulong debruijn64 = 0x03f79d71b4cb0a89UL;

            bb |= bb >> 1;
            bb |= bb >> 2;
            bb |= bb >> 4;
            bb |= bb >> 8;
            bb |= bb >> 16;
            bb |= bb >> 32;
            return(Msb64Table[(bb.Value * debruijn64) >> 58]);
        }
示例#11
0
 public static BitBoard GetAttacks(this Square square, EPieceType pieceType, BitBoard occupied = new BitBoard())
 {
     return(pieceType == EPieceType.Knight || pieceType == EPieceType.King
         ? PseudoAttacksBB[pieceType.AsInt(), square.AsInt()]
         : pieceType == EPieceType.Bishop
             ? square.BishopAttacks(occupied)
             : pieceType == EPieceType.Rook
                 ? square.RookAttacks(occupied)
                 : pieceType == EPieceType.Queen
                     ? square.QueenAttacks(occupied)
                     : Zero);
 }
示例#12
0
        public static BitBoard MakeBitboard(params Square[] squares)
        {
            BitBoard b = ZeroBb;

            // ReSharper disable once ForCanBeConvertedToForeach
            // ReSharper disable once LoopCanBeConvertedToQuery
            for (var i = 0; i < squares.Length; ++i)
            {
                b |= squares[i];
            }
            return(b);
        }
示例#13
0
        public static BitBoard XrayAttacks(this Square square, EPieceType pieceType, BitBoard occupied, BitBoard blockers)
        {
            switch (pieceType)
            {
            case EPieceType.Bishop:
                return(square.XrayBishopAttacks(occupied, blockers));

            case EPieceType.Rook:
                return(square.XrayRookAttacks(occupied, blockers));

            case EPieceType.Queen:
                return(XrayBishopAttacks(square, occupied, blockers) | XrayRookAttacks(square, occupied, blockers));

            default:
                return(EmptyBitBoard);
            }
        }
示例#14
0
        public static BitBoard GetAttacks(this Square square, EPieceType pieceType, BitBoard occupied = new BitBoard())
        {
            switch (pieceType)
            {
            case EPieceType.Knight:
            case EPieceType.King:
                return(PseudoAttacksBB[pieceType.AsInt(), square.AsInt()]);

            case EPieceType.Bishop:
                return(square.BishopAttacks(occupied));

            case EPieceType.Rook:
                return(square.RookAttacks(occupied));

            case EPieceType.Queen:
                return(square.QueenAttacks(occupied));

            default:
                return(EmptyBitBoard);
            }
        }
示例#15
0
        public static string PrintBitBoard(BitBoard b, string title = "")
        {
            var s = new StringBuilder("+---+---+---+---+---+---+---+---+---+\n", 1024);

            if (!string.IsNullOrWhiteSpace(title))
            {
                s.AppendLine($"| {title}");
            }
            for (var r = ERank.Rank8; r >= ERank.Rank1; --r)
            {
                s.AppendFormat("| {0} ", (int)r + 1);
                for (var f = EFile.FileA; f <= EFile.FileH; ++f)
                {
                    s.AppendFormat("| {0} ", (b & new Square(r, f)).Empty() ? ' ' : 'X');
                }
                s.AppendLine("|\n+---+---+---+---+---+---+---+---+---+");
            }

            s.AppendLine("|   | A | B | C | D | E | F | G | H |");
            s.AppendLine("+---+---+---+---+---+---+---+---+---+");
            return(s.ToString());
        }
示例#16
0
 public static BitBoard NorthWestOne(this BitBoard bb) => (bb & ~FILEA) << 7;
示例#17
0
 public static BitBoard SouthWestOne(this BitBoard bb) => (bb & ~FILEA) >> 9;
示例#18
0
 public static BitBoard SouthEastOne(this BitBoard bb) => (bb & ~FILEH) >> 7;
示例#19
0
 public static bool IsSet(this BitBoard bb, int pos) => (bb.Value & (One << pos)) != 0;
示例#20
0
 public static Square Last(this BitBoard bb) => bb.Msb();
示例#21
0
 public static Square First(this BitBoard bb) => bb.Lsb();
示例#22
0
 public static BitBoard NorthEastOne(this BitBoard bb) => (bb & ~FILEH) << 9;
示例#23
0
        static BitBoards()
        {
            QueenSide   = new BitBoard(FILEA | FILEB | FILEC | FILED);
            CenterFiles = new BitBoard(FILEC | FILED | FILEE | FILEF);
            KingSide    = new BitBoard(FILEE | FILEF | FILEG | FILEH);
            Center      = new BitBoard((FILED | FILEE) & (RANK4 | RANK5));

            ShiftFuncs       = MakeShiftFuncs();
            BetweenBB        = new BitBoard[64, 64];
            PseudoAttacksBB  = new BitBoard[EPieceType.PieceTypeNb.AsInt(), 64];
            EmptyBitBoard    = new BitBoard(ZeroBb);
            AllSquares       = ~EmptyBitBoard;
            PawnAttackSpanBB = new BitBoard[2, 64];
            PassedPawnMaskBB = new BitBoard[2, 64];
            ForwardRanksBB   = new BitBoard[2, 64];
            ForwardFileBB    = new BitBoard[2, 64];
            LineBB           = new BitBoard[64, 64];
            KingRingBB       = new BitBoard[2, 64];
            SquareDistance   = new byte[64, 64];
            DistanceRingBB   = new BitBoard[64, 8];

            // local helper functions to calculate distance
            int distance(int x, int y)
            {
                return(Math.Abs(x - y));
            }

            int distanceFile(Square x, Square y)
            {
                return(distance(x.File().AsInt(), y.File().AsInt()));
            }

            int distanceRank(Square x, Square y)
            {
                return(distance(x.Rank().AsInt(), y.Rank().AsInt()));
            }

            var validMagicPieces = new[] { EPieceType.Bishop, EPieceType.Rook };

            // ForwardRanksBB population loop idea from sf
            for (var r = ERank.Rank1; r < ERank.RankNb; ++r)
            {
                var rank = (int)r;
                ForwardRanksBB[0, rank] = ~(ForwardRanksBB[1, rank + 1] = ForwardRanksBB[1, rank] | RankBB[rank]);
            }

            for (var side = EPlayer.White; side < EPlayer.PlayerNb; ++side)
            {
                var c = (int)side;
                foreach (var square in AllSquares)
                {
                    var s = square.AsInt();
                    ForwardFileBB[c, s]    = ForwardRanksBB[c, square.Rank().AsInt()] & FileBB[square.File().AsInt()];
                    PawnAttackSpanBB[c, s] = ForwardRanksBB[c, square.Rank().AsInt()] & AdjacentFilesBB[square.File().AsInt()];
                    PassedPawnMaskBB[c, s] = ForwardFileBB[c, s] | PawnAttackSpanBB[c, s];
                }
            }

            // mini local helpers
            BitBoard ComputeKnightAttack(BitBoard b)
            {
                BitBoard res = (b & ~(FILEA | FILEB)) << 6;

                res |= (b & ~FILEA) << 15;
                res |= (b & ~FILEH) << 17;
                res |= (b & ~(FILEG | FILEH)) << 10;
                res |= (b & ~(FILEG | FILEH)) >> 6;
                res |= (b & ~FILEH) >> 15;
                res |= (b & ~FILEA) >> 17;
                res |= (b & ~(FILEA | FILEB)) >> 10;
                return(res);
            }

            // Pseudo attacks for all pieces
            foreach (var s1 in AllSquares)
            {
                var sq = s1.AsInt();
                var b  = s1.BitBoardSquare();

                var file = s1.File();

                // distance computation
                foreach (var s2 in AllSquares)
                {
                    SquareDistance[sq, s2.AsInt()] = (byte)distanceFile(s1, s2).Max(distanceRank(s1, s2));
                    DistanceRingBB[sq, SquareDistance[sq, s2.AsInt()]] |= s2;
                }

                PseudoAttacksBB[0, sq] = b.NorthEastOne() | b.NorthWestOne();
                PseudoAttacksBB[1, sq] = b.SouthWestOne() | b.SouthEastOne();

                var pt = EPieceType.Knight.AsInt();
                PseudoAttacksBB[pt, sq] = ComputeKnightAttack(b);

                var bishopAttacks = s1.BishopAttacks(EmptyBitBoard);
                var rookAttacks   = s1.RookAttacks(EmptyBitBoard);

                pt = EPieceType.Bishop.AsInt();
                PseudoAttacksBB[pt, sq] = bishopAttacks;

                pt = EPieceType.Rook.AsInt();
                PseudoAttacksBB[pt, sq] = rookAttacks;

                pt = EPieceType.Queen.AsInt();
                PseudoAttacksBB[pt, sq] = bishopAttacks | rookAttacks;

                pt = EPieceType.King.AsInt();
                PseudoAttacksBB[pt, sq] = b.NorthOne() | b.SouthOne() | b.EastOne() | b.WestOne()
                                          | b.NorthEastOne() | b.NorthWestOne() | b.SouthEastOne() | b.SouthWestOne();

                // Compute lines and betweens
                foreach (var validMagicPiece in validMagicPieces)
                {
                    pt = validMagicPiece.AsInt();
                    foreach (var s2 in AllSquares)
                    {
                        if ((PseudoAttacksBB[pt, sq] & s2).Empty())
                        {
                            continue;
                        }

                        LineBB[sq, s2.AsInt()]    = GetAttacks(s1, validMagicPiece, EmptyBitBoard) & GetAttacks(s2, validMagicPiece, EmptyBitBoard) | s1 | s2;
                        BetweenBB[sq, s2.AsInt()] = GetAttacks(s1, validMagicPiece, BbSquares[s2.AsInt()]) & GetAttacks(s2, validMagicPiece, BbSquares[sq]);
                    }
                }

                // Compute KingRings
                pt = EPieceType.King.AsInt();
                for (var side = EPlayer.White; side < EPlayer.PlayerNb; ++side)
                {
                    var c = (int)side;
                    KingRingBB[c, sq] = PseudoAttacksBB[pt, sq];
                    if (s1.RelativeRank(side) == ERank.Rank1)
                    {
                        KingRingBB[c, sq] |= KingRingBB[c, sq].Shift(side == EPlayer.White ? EDirection.North : EDirection.South);
                    }

                    if (file == EFile.FileH)
                    {
                        KingRingBB[c, sq] |= KingRingBB[c, sq].WestOne();
                    }
                    else if (file == EFile.FileA)
                    {
                        KingRingBB[c, sq] |= KingRingBB[c, sq].EastOne();
                    }

                    Debug.Assert(!KingRingBB[c, sq].Empty());
                }
            }

            CornerA1 = MakeBitboard(ESquare.a1, ESquare.b1, ESquare.a2, ESquare.b2);
            CornerA8 = MakeBitboard(ESquare.a8, ESquare.b8, ESquare.a7, ESquare.b7);
            CornerH1 = MakeBitboard(ESquare.h1, ESquare.g1, ESquare.h2, ESquare.g2);
            CornerH8 = MakeBitboard(ESquare.h8, ESquare.g8, ESquare.h7, ESquare.g7);
        }
示例#24
0
 public static BitBoard SouthOne(this BitBoard bb) => bb >> 8;
示例#25
0
 public static BitBoard Fill(this BitBoard bb, Player side) => side == EPlayer.White ? bb.NorthFill() : bb.SouthFill();
示例#26
0
 public static BitBoard EastOne(this BitBoard bb) => (bb & ~FILEH) << 1;
示例#27
0
 public static void ResetLsb(ref BitBoard bb) => bb &= bb - 1;
示例#28
0
 public static BitBoard WestOne(this BitBoard bb) => (bb & ~FILEA) >> 1;
示例#29
0
 public static BitBoard NorthOne(this BitBoard bb) => bb << 8;
示例#30
0
 public static Square Get(this BitBoard bb, int pos) => (int)(bb.Value >> pos) & 0x1;