예제 #1
0
파일: King.cs 프로젝트: crybot/Napoleon-old
 internal static BitBoard GetKingAttacks(BitBoard king)
 {
     BitBoard attacks = CompassRose.OneStepEast(king) | CompassRose.OneStepWest(king);
     king |= attacks;
     attacks |= CompassRose.OneStepNorth(king) | CompassRose.OneStepSouth(king);
     return attacks;
 }
예제 #2
0
        internal static void Display(BitBoard bitBoard)
        {
            for (int r = 7; r >= 0; r--)
            {
                Console.WriteLine("   ------------------------");

                Console.Write(" {0} ", r + 1);

                for (int c = 0; c <= 7; c++)
                {
                    Console.Write('[');
                    if (IsBitSet(bitBoard, Square.GetSquareIndex(c, r)))
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.Write('1');
                    }
                    else
                    {
                        Console.ForegroundColor = ConsoleColor.DarkRed;
                        Console.Write('0');
                    }

                    Console.ResetColor();
                    Console.Write(']');
                }
                Console.WriteLine();
            }
            Console.WriteLine("\n    A  B  C  D  E  F  G  H");
        }
예제 #3
0
파일: Pawn.cs 프로젝트: crybot/Napoleon-old
        private static BitBoard GetDoublePushTargets(byte color, BitBoard pawns, BitBoard empty)
        {
            BitBoard singlePush = GetSinglePushTargets(color, pawns, empty);

            return color == PieceColor.White
                ? CompassRose.OneStepNorth(singlePush) & empty & Constants.Ranks.Four
                : CompassRose.OneStepSouth(singlePush) & empty & Constants.Ranks.Five;
        }
예제 #4
0
        internal static int BitScanForwardReset(ref BitBoard bitBoard)
        {
            Debug.Assert(bitBoard.value != 0);

            UInt64 bb = bitBoard.value;
            bitBoard.value &= (bitBoard.value - 1);

            return Constants.DeBrujinTable[((ulong)((long)bb & -(long)bb) * Constants.DeBrujinValue) >> 58];
        }
예제 #5
0
파일: Pawn.cs 프로젝트: crybot/Napoleon-old
 private static BitBoard GetPawnsAbleToSinglePush(byte color, BitBoard pawns, BitBoard empty)
 {
     switch (color)
     {
         case PieceColor.White:
             return CompassRose.OneStepSouth(empty) & pawns;
         case PieceColor.Black:
             return CompassRose.OneStepNorth(empty) & pawns;
         default:
             throw new NotImplementedException();
     }
 }
예제 #6
0
파일: Rook.cs 프로젝트: crybot/Napoleon-old
        internal static BitBoard GetAllTargets(byte pieceColor, BitBoard rooks, Board board)
        {
            BitBoard occupiedSquares = board.OccupiedSquares;
            BitBoard targets = Constants.Empty;
            int square;

            square = BitBoard.BitScanForward(rooks);

            targets |= MovePackHelper.GetRankAttacks(occupiedSquares, square);
            targets |= MovePackHelper.GetFileAttacks(occupiedSquares, square);

            return targets & ~board.GetPlayerPieces();
        }
예제 #7
0
        internal static BitBoard GetAllTargets(byte pieceColor, BitBoard bishops, Board board)
        {
            BitBoard occupiedSquares = board.OccupiedSquares;
            BitBoard targets = Constants.Empty;
            int square;

            square = BitBoard.BitScanForward(bishops);

            targets |= MovePackHelper.GetA1H8DiagonalAttacks(occupiedSquares, square);
            targets |= MovePackHelper.GetH1A8DiagonalAttacks(occupiedSquares, square);

            return targets & ~board.GetPlayerPieces();
        }
예제 #8
0
        internal static BitBoard GetKnightAttacks(BitBoard knights)
        {
            BitBoard west, east, attacks;
            east = CompassRose.OneStepEast(knights);
            west = CompassRose.OneStepWest(knights);
            attacks = (east | west) << 16;
            attacks |= (east | west) >> 16;
            east = CompassRose.OneStepEast(east);
            west = CompassRose.OneStepWest(west);
            attacks |= (east | west) << 8;
            attacks |= (east | west) >> 8;

            return attacks;
        }
예제 #9
0
        internal static void GetKingMoves(byte color, BitBoard king, Board board, Move[] moveList, ref int pos)
        {
            BitBoard targets;
            byte fromIndex;
            byte toIndex;

            while (king != 0)
            {
                fromIndex = (byte)BitBoard.BitScanForwardReset(ref king); // search for LS1B and then reset it
                targets = King.GetAllTargets(color, Constants.SquareMask[fromIndex], board);

                while (targets != 0)
                {
                    toIndex = (byte)BitBoard.BitScanForwardReset(ref targets); // search for LS1B and then reset it
                    moveList[pos++] = new Move(fromIndex, toIndex, PieceType.King, board.pieceSet[toIndex].Type, PieceType.None);
                }
            }
        }
예제 #10
0
파일: Pawn.cs 프로젝트: crybot/Napoleon-old
 private static BitBoard GetPawnsAbleToDoublePush(byte color, BitBoard pawns, BitBoard empty)
 {
     switch (color)
     {
         case PieceColor.White:
             {
                 BitBoard emptyRank3 = CompassRose.OneStepSouth(empty & Constants.Ranks.Four) & empty;
                 return GetPawnsAbleToSinglePush(color, pawns, emptyRank3);
             }
         case PieceColor.Black:
             {
                 BitBoard emptyRank6 = CompassRose.OneStepNorth(empty & Constants.Ranks.Six) & empty;
                 return GetPawnsAbleToSinglePush(color, pawns, emptyRank6);
             }
         default:
             throw new NotImplementedException();
     }
 }
예제 #11
0
        internal static int BitScanForward(BitBoard bitBoard)
        {
            Debug.Assert(bitBoard.value != 0);

            return Constants.DeBrujinTable[((ulong)((long)bitBoard.value & -(long)bitBoard.value) * Constants.DeBrujinValue) >> 58];
        }
예제 #12
0
 internal static int ToInt32(BitBoard bitBoard)
 {
     return (int)bitBoard.value;
 }
예제 #13
0
 internal static UInt64 GetRankAttacks(BitBoard occupiedSquares, int square)
 {
     int rank = Square.GetRankIndex(square);
     int occupancy = BitBoard.ToInt32((occupiedSquares & Constants.SixBitRankMask[rank]) >> (8 * rank));
     return RankAttacks[square][(occupancy >> 1) & 63];
 }
예제 #14
0
 internal static UInt64 GetH1A8DiagonalAttacks(BitBoard occupiedSquares, int square)
 {
     int diag = Square.GetH1A8AntiDiagonalIndex(square);
     int occupancy = BitBoard.ToInt32((occupiedSquares & Constants.H1A8DiagonalMask[diag]) * Constants.H1A8DiagonalMagic[diag] >> 56);
     return H1A8DiagonalAttacks[square][(occupancy >> 1) & 63];
 }
예제 #15
0
파일: Pawn.cs 프로젝트: crybot/Napoleon-old
        internal static BitBoard GetAllTargets(byte color, BitBoard pawns, Board board)
        {
            BitBoard empty = board.EmptySquares;

            return GetQuietTargets(color, pawns, empty) | GetAnyAttack(color, pawns, board);
        }
예제 #16
0
파일: King.cs 프로젝트: crybot/Napoleon-old
 internal static BitBoard GetAllTargets(byte pieceColor, BitBoard king, Board board)
 {
     BitBoard kingMoves = MovePackHelper.KingAttacks[(BitBoard.BitScanForward(king))];
     return kingMoves & ~board.GetPlayerPieces();
 }
예제 #17
0
        internal static BitBoard GetAllTargets(byte pieceColor, BitBoard knights, Board board)
        {
            BitBoard targets = MovePackHelper.KnightAttacks[(BitBoard.BitScanForward(knights))];

            return targets & ~board.GetPlayerPieces();
        }
예제 #18
0
 internal static bool IsBitSet(BitBoard bitBoard, int posBit)
 {
     return (bitBoard & ((UInt64)1 << (posBit))) != 0;
 }
예제 #19
0
파일: Pawn.cs 프로젝트: crybot/Napoleon-old
 private static BitBoard GetWestAttacks(byte color, BitBoard pawns)
 {
     return color == PieceColor.White ? CompassRose.OneStepNorthWest(pawns) : CompassRose.OneStepSouthWest(pawns);
 }
예제 #20
0
파일: Pawn.cs 프로젝트: crybot/Napoleon-old
 private static BitBoard GetSinglePushTargets(byte color, BitBoard pawns, BitBoard empty)
 {
     return color == PieceColor.White ? CompassRose.OneStepNorth(pawns) & empty : CompassRose.OneStepSouth(pawns) & empty;
 }
예제 #21
0
파일: Pawn.cs 프로젝트: crybot/Napoleon-old
 private static BitBoard GetQuietTargets(byte color, BitBoard pawns, BitBoard empty)
 {
     return GetSinglePushTargets(color, pawns, empty) | GetDoublePushTargets(color, pawns, empty);
 }
예제 #22
0
파일: Pawn.cs 프로젝트: crybot/Napoleon-old
 internal static BitBoard GetAnyAttack(byte color, BitBoard pawns, Board board)
 {
     return (GetEastAttacks(color, pawns) | GetWestAttacks(color, pawns)) & board.GetEnemyPieces();
 }
예제 #23
0
 internal static int PopCount(BitBoard bitBoard)
 {
     bitBoard.value -= ((bitBoard.value >> 1) & 0x5555555555555555UL);
     bitBoard.value = ((bitBoard.value >> 2) & 0x3333333333333333UL) + (bitBoard.value & 0x3333333333333333UL);
     bitBoard.value = ((bitBoard.value >> 4) + bitBoard.value) & 0x0F0F0F0F0F0F0F0FUL;
     return (int)((bitBoard.value * 0x0101010101010101UL) >> 56);
 }
예제 #24
0
 internal static UInt64 GetFileAttacks(BitBoard occupiedSquares, int square)
 {
     int file = Square.GetFileIndex(square);
     int occupancy = BitBoard.ToInt32((occupiedSquares & Constants.SixBitFileMask[file]) * Constants.FileMagic[file] >> 56);
     return FileAttacks[square][(occupancy >> 1) & 63];
 }
예제 #25
0
        private void UpdateGenericBitBoards()
        {
            this.WhitePieces =
                  this.bitBoardSet[PieceColor.White][PieceType.Pawn] | this.bitBoardSet[PieceColor.White][PieceType.Knight]
                | this.bitBoardSet[PieceColor.White][PieceType.Bishop] | this.bitBoardSet[PieceColor.White][PieceType.Rook]
                | this.bitBoardSet[PieceColor.White][PieceType.Queen] | this.bitBoardSet[PieceColor.White][PieceType.King];

            this.BlackPieces =
                  this.bitBoardSet[PieceColor.Black][PieceType.Pawn] | this.bitBoardSet[PieceColor.Black][PieceType.Knight]
                | this.bitBoardSet[PieceColor.Black][PieceType.Bishop] | this.bitBoardSet[PieceColor.Black][PieceType.Rook]
                | this.bitBoardSet[PieceColor.Black][PieceType.Queen] | this.bitBoardSet[PieceColor.Black][PieceType.King];

            this.OccupiedSquares = WhitePieces | BlackPieces;
            this.EmptySquares = ~OccupiedSquares;
        }
예제 #26
0
 internal static BitBoard GetAllTargets(byte pieceColor, BitBoard queens, Board board)
 {
     return Rook.GetAllTargets(pieceColor, queens, board) | Bishop.GetAllTargets(pieceColor, queens, board);
 }
예제 #27
0
        internal void UndoMove(Move move)
        {
            //ARRAY
            this.pieceSet[move.FromSquare] = this.pieceSet[move.ToSquare]; // muove il pezzo
            this.pieceSet[move.ToSquare] = move.IsCapture() ? new Piece(SideToMove, move.PieceCaptured) : new Piece(PieceColor.None, PieceType.None); // svuota o riempie la casella di partenza

            //BITBOARDS
            BitBoard From = Constants.SquareMask[move.FromSquare];
            BitBoard To = Constants.SquareMask[move.ToSquare];
            BitBoard FromTo = From | To;

            this.SideToMove = this.SideToMove.GetOpposite();

            // aggiorna la bitboard
            this.bitBoardSet[this.SideToMove][move.PieceMoved] ^= FromTo;
            if (this.SideToMove == PieceColor.White)
                this.WhitePieces ^= FromTo;
            else
                this.BlackPieces ^= FromTo;

            if (move.PieceMoved == PieceType.King)
                this.kingSquare[this.SideToMove] = move.FromSquare;

            if (move.IsCapture())
            {
                this.bitBoardSet[this.SideToMove.GetOpposite()][move.PieceCaptured] ^= To;

                //aggiorna i pezzi dell'avversario
                if (this.SideToMove == PieceColor.White)
                    this.BlackPieces ^= To;
                else
                    this.WhitePieces ^= To;

                this.OccupiedSquares ^= From;
                this.EmptySquares ^= From;
            }
            else
            {
                this.OccupiedSquares ^= FromTo;
                this.EmptySquares ^= FromTo;
            }
        }
예제 #28
0
        internal bool IsAttacked(BitBoard target, byte side)
        {
            BitBoard slidingAttackers;
            BitBoard pawnAttacks;
            BitBoard allPieces = this.OccupiedSquares;
            byte enemyColor = side.GetOpposite();
            int to;

            while (target != 0)
            {
                to = BitBoard.BitScanForwardReset(ref target);
                pawnAttacks = side == PieceColor.White ? MovePackHelper.WhitePawnAttacks[to] : MovePackHelper.BlackPawnAttacks[to];

                if ((this.GetPieceSet(enemyColor, PieceType.Pawn) & pawnAttacks) != 0) return true;
                if ((this.GetPieceSet(enemyColor, PieceType.Knight) & MovePackHelper.KnightAttacks[to]) != 0) return true;
                if ((this.GetPieceSet(enemyColor, PieceType.King) & MovePackHelper.KingAttacks[to]) != 0) return true;

                // file / rank attacks
                slidingAttackers = this.GetPieceSet(enemyColor, PieceType.Queen) | this.GetPieceSet(enemyColor, PieceType.Rook);

                if (slidingAttackers != 0)
                {
                    if ((MovePackHelper.GetRankAttacks(allPieces, to) & slidingAttackers) != 0) return true;
                    if ((MovePackHelper.GetFileAttacks(allPieces, to) & slidingAttackers) != 0) return true;
                }

                // diagonals
                slidingAttackers = this.GetPieceSet(enemyColor, PieceType.Queen) | this.GetPieceSet(enemyColor, PieceType.Bishop);

                if (slidingAttackers != 0)
                {
                    if ((MovePackHelper.GetH1A8DiagonalAttacks(allPieces, to) & slidingAttackers) != 0) return true;
                    if ((MovePackHelper.GetA1H8DiagonalAttacks(allPieces, to) & slidingAttackers) != 0) return true;
                }
            }
            return false;
        }
예제 #29
0
        internal bool IsMoveLegal(Move move, BitBoard pinned)
        {
            if (move.PieceMoved == PieceType.King)
                return !this.IsAttacked(Constants.SquareMask[move.ToSquare], this.SideToMove);

            if (this.IsAttacked(this.bitBoardSet[SideToMove][PieceType.King], this.SideToMove))
            {
                bool islegal = true;
                this.MakeMove(move);
                islegal = !this.IsAttacked(this.bitBoardSet[SideToMove.GetOpposite()][PieceType.King], this.SideToMove.GetOpposite());
                this.UndoMove(move);

                return islegal;
            }

            return (pinned == 0) || ((pinned & Constants.SquareMask[move.FromSquare]) == 0)
                || MovePackHelper.AreSquareAligned(move.FromSquare, move.ToSquare, this.kingSquare[this.SideToMove]);
        }
예제 #30
-1
        internal static void GetPawnMoves(byte color, BitBoard pawns, Board board, Move[] moveList, ref int pos)
        {
            BitBoard targets;
            BitBoard epTargets;
            byte fromIndex;
            byte toIndex;

            while (pawns != 0)
            {
                fromIndex = (byte)BitBoard.BitScanForwardReset(ref pawns); // search for LS1B and then reset it
                targets = Pawn.GetAllTargets(color, Constants.SquareMask[fromIndex], board);

                while (targets != 0)
                {
                    toIndex = (byte)BitBoard.BitScanForwardReset(ref targets); // search for LS1B and then reset it

                    // en passant
                    if (board.EnPassantSquare != Square.Invalid)
                    {
                        epTargets = color == PieceColor.White ? MovePackHelper.WhitePawnAttacks[fromIndex] : MovePackHelper.BlackPawnAttacks[fromIndex];

                        if ((epTargets & Constants.SquareMask[board.EnPassantSquare]) != 0)
                            moveList[pos++] = new Move(fromIndex, toIndex, PieceType.Pawn, PieceType.Pawn, PieceType.Pawn);
                    }

                    // promotions
                    if (Square.GetRankIndex(toIndex) == 7 && color == PieceColor.White || Square.GetRankIndex(toIndex) == 0 && color == PieceColor.Black)
                    {
                        moveList[pos++] = new Move(fromIndex, toIndex, PieceType.Pawn, board.pieceSet[toIndex].Type, PieceType.Queen);
                        moveList[pos++] = new Move(fromIndex, toIndex, PieceType.Pawn, board.pieceSet[toIndex].Type, PieceType.Rook);
                        moveList[pos++] = new Move(fromIndex, toIndex, PieceType.Pawn, board.pieceSet[toIndex].Type, PieceType.Bishop);
                        moveList[pos++] = new Move(fromIndex, toIndex, PieceType.Pawn, board.pieceSet[toIndex].Type, PieceType.Knight);
                    }
                    else
                        moveList[pos++] = new Move(fromIndex, toIndex, PieceType.Pawn, board.pieceSet[toIndex].Type, PieceType.None); // no promotions
                }
            }
        }