示例#1
0
        private MoveViewer TryCastles(Board board, Colour colour, SquareFlag fromSquare, SquareFlag toSquare, IEnumerable <MoveViewer> availableMoves)
        {
            if (colour == Colour.White && fromSquare == SquareFlagConstants.WhiteKingStartSquare)
            {
                if (toSquare == SquareFlagConstants.WhiteKingSideRookStartSquare && board.WhiteCanCastleKingSide)
                {
                    return(availableMoves.SingleOrDefault(x => x.MoveType == MoveType.CastleKing)
                           ?? new MoveViewer(0));
                }
                else if (toSquare == SquareFlagConstants.WhiteQueenSideRookStartSquare && board.WhiteCanCastleQueenSide)
                {
                    return(availableMoves.SingleOrDefault(x => x.MoveType == MoveType.CastleQueen)
                           ?? new MoveViewer(0));
                }
            }

            if (colour == Colour.Black && fromSquare == SquareFlagConstants.BlackKingStartSquare)
            {
                if (toSquare == SquareFlagConstants.BlackKingSideRookStartSquare && board.BlackCanCastleKingSide)
                {
                    return(availableMoves.SingleOrDefault(x => x.MoveType == MoveType.CastleKing)
                           ?? new MoveViewer(0));
                }
                else if (toSquare == SquareFlagConstants.BlackQueenSideRookStartSquare && board.BlackCanCastleQueenSide)
                {
                    return(availableMoves.SingleOrDefault(x => x.MoveType == MoveType.CastleQueen)
                           ?? new MoveViewer(0));
                }
            }

            return(new MoveViewer(0));
        }
        public static IEnumerable <SquareFlag> ToList(this SquareFlag squares)
        {
            var ulsquares = (ulong)squares;

            var a = (uint)(ulsquares & 0b00000000_00000000_00000000_00000000_11111111_11111111_11111111_11111111);
            var b = (uint)((ulsquares & 0b11111111_11111111_11111111_11111111_00000000_00000000_00000000_00000000) >> 32);

            var x = 0;

            while (a > 0)
            {
                if ((a & 1) > 0)
                {
                    yield return((SquareFlag)((ulong)1 << x));
                }

                a >>= 1;
                ++x;
            }

            x = 0;

            while (b > 0)
            {
                if ((b & 1) > 0)
                {
                    yield return((SquareFlag)((ulong)1 << (32 + x)));
                }

                b >>= 1;
                ++x;
            }
        }
示例#3
0
 public void Set(
     Colour colour,
     SquareFlag myPawns,
     SquareFlag myRooks,
     SquareFlag myKnights,
     SquareFlag myBishops,
     SquareFlag myQueens,
     SquareFlag myKing,
     SquareFlag opponentPawns,
     SquareFlag opponentRooks,
     SquareFlag opponentKnights,
     SquareFlag opponentBishops,
     SquareFlag opponentQueens,
     SquareFlag opponentKing,
     StateFlag boardState,
     SquareFlag enPassantSquare)
 {
     Colour          = colour;
     OpponentColour  = colour.Opposite();
     MyPawns         = myPawns;
     MyRooks         = myRooks;
     MyKnights       = myKnights;
     MyBishops       = myBishops;
     MyQueens        = myQueens;
     MyKing          = myKing;
     OpponentPawns   = opponentPawns;
     OpponentRooks   = opponentRooks;
     OpponentKnights = opponentKnights;
     OpponentBishops = opponentBishops;
     OpponentQueens  = opponentQueens;
     OpponentKing    = opponentKing;
     _boardState     = boardState;
     EnPassant       = enPassantSquare;
 }
示例#4
0
        public Board(
            SquareFlag whitePawns,
            SquareFlag whiteRooks,
            SquareFlag whiteKnights,
            SquareFlag whiteBishops,
            SquareFlag whiteQueens,
            SquareFlag whiteKing,
            SquareFlag blackPawns,
            SquareFlag blackRooks,
            SquareFlag blackKnights,
            SquareFlag blackBishops,
            SquareFlag blackQueens,
            SquareFlag blackKing,
            StateFlag state,
            SquareFlag enPassant)
        {
            WhitePawns   = whitePawns;
            WhiteRooks   = whiteRooks;
            WhiteKnights = whiteKnights;
            WhiteBishops = whiteBishops;
            WhiteQueens  = whiteQueens;
            WhiteKing    = whiteKing;
            BlackPawns   = blackPawns;
            BlackRooks   = blackRooks;
            BlackKnights = blackKnights;
            BlackBishops = blackBishops;
            BlackQueens  = blackQueens;
            BlackKing    = blackKing;

            keyGen.Init();

            Key = keyGen.Hash(this, Colour.White);

            history.Push(new BoardStateInfo(Key, 0, state, enPassant));
        }
示例#5
0
        // https://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/
        // The function will recursively generate all combinations of length 'combinationLength'. For example,
        // if there are 10 elements to sort then a combinationLenght of 5 will find all the combinations that
        // use exactly 5 elements. Therefore, it must be called once 'end' times to find all combinations of
        // any length
        private void CombinationUtil(
            IReadOnlyList <SquareFlag> squares,
            int rootSquare,
            SquareFlag[] combination,
            int start,
            int end,
            int index,
            int combinationLength,
            Action <SortedDictionary <int, SquareFlag>, int, SquareFlag> addToList,
            SortedDictionary <int, SquareFlag> dictionary)
        {
            if (index == combinationLength)
            {
                SquareFlag currentOccupancy = 0;

                foreach (var square in combination)
                {
                    currentOccupancy |= square;
                }

                addToList(dictionary, rootSquare, currentOccupancy);

                return;
            }

            // Replace index with all possible elements. The condition  "end-i+1 >= r-index" makes sure
            // that including one element at index will make a combination with remaining elements
            // at remaining positions
            for (int i = start; i <= end && end - i + 1 >= combinationLength - index; i++)
            {
                combination[index] = squares.ElementAt(i);

                CombinationUtil(squares, rootSquare, combination, i + 1, end, index + 1, combinationLength, addToList, dictionary);
            }
        }
示例#6
0
        public static GameState Parse(string fen)
        {
            var parts = fen.Split(' ');

            var board  = parts[0];
            var colour = parts[1] == "w" ? Colour.White : Colour.Black;

            StateFlag castlingRights = ParseCastlingRights(parts[2]);

            SquareFlag enPassantSquare = 0;

            if (parts[3] != "-")
            {
                Enum.TryParse(parts[3].ToUpper(), out enPassantSquare);
            }

            var halfTurnCounter = 0;
            var fullMoveNumber  = 0;

            if (parts.Length > 4)
            {
                halfTurnCounter = int.Parse(parts[4]);
            }

            if (parts.Length > 5)
            {
                fullMoveNumber = int.Parse(parts[5]);
            }

            return(CreateGameState(board, colour, castlingRights, enPassantSquare, halfTurnCounter, fullMoveNumber));
        }
示例#7
0
 public RelativeBoard(
     Colour colour,
     SquareFlag myPawns,
     SquareFlag myRooks,
     SquareFlag myKnights,
     SquareFlag myBishops,
     SquareFlag myQueens,
     SquareFlag myKing,
     SquareFlag opponentPawns,
     SquareFlag opponentRooks,
     SquareFlag opponentKnights,
     SquareFlag opponentBishops,
     SquareFlag opponentQueens,
     SquareFlag opponentKing,
     StateFlag boardState)
 {
     Colour          = colour;
     OpponentColour  = colour.Opposite();
     MyPawns         = myPawns;
     MyRooks         = myRooks;
     MyKnights       = myKnights;
     MyBishops       = myBishops;
     MyQueens        = myQueens;
     MyKing          = myKing;
     OpponentPawns   = opponentPawns;
     OpponentRooks   = opponentRooks;
     OpponentKnights = opponentKnights;
     OpponentBishops = opponentBishops;
     OpponentQueens  = opponentQueens;
     OpponentKing    = opponentKing;
     _boardState     = boardState;
 }
示例#8
0
        public byte GetInstanceNumber(Piece piece, SquareFlag square)
        {
            if (piece.Colour == Colour.White)
            {
                if (piece.Type == PieceType.Pawn)
                {
                    return(WhitePawns.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.Rook)
                {
                    return(WhiteRooks.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.Knight)
                {
                    return(WhiteKnights.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.Bishop)
                {
                    return(WhiteBishops.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.Queen)
                {
                    return(WhiteQueens.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.King)
                {
                    return(WhiteKing.GetInstanceNumber(square));
                }
            }
            else
            {
                if (piece.Type == PieceType.Pawn)
                {
                    return(BlackPawns.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.Rook)
                {
                    return(BlackRooks.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.Knight)
                {
                    return(BlackKnights.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.Bishop)
                {
                    return(BlackBishops.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.Queen)
                {
                    return(BlackQueens.GetInstanceNumber(square));
                }
                if (piece.Type == PieceType.King)
                {
                    return(BlackKing.GetInstanceNumber(square));
                }
            }

            return(0);
        }
        public static Square ToSquare(this SquareFlag squareFlag)
        {
            Square square;

            square.Flag  = squareFlag;
            square.Index = squareFlag.ToSquareIndex();
            return(square);
        }
        public void ToList_1_Correct()
        {
            SquareFlag square = SquareFlag.H1;

            var asList = square.ToList();

            Assert.Collection(asList, item => Assert.Equal(SquareFlag.H1, item));
        }
示例#11
0
        public static SquareFlag GeneratePotentialRookAttacks(int squareIndex, SquareFlag occupancy)
        {
            ulong attackableSquares = 0;

            var bit = 1ul << squareIndex;

            var occupancyAsLong = (ulong)occupancy;

            var rankBits = AllBitsOnForRank(squareIndex);

            do
            {
                bit <<= 8;
                attackableSquares |= bit;
            }while (bit != 0 && ((bit & occupancyAsLong) == 0));

            bit = 1ul << squareIndex;

            do
            {
                bit >>= 8;
                attackableSquares |= bit;
            }while (bit != 0 && ((bit & occupancyAsLong) == 0));

            bit = 1ul << squareIndex;

            do
            {
                bit <<= 1;

                if ((bit & rankBits) != 0)
                {
                    attackableSquares |= bit;
                }
                else
                {
                    break;
                }
            }while ((bit & occupancyAsLong) == 0);

            bit = 1ul << squareIndex;

            do
            {
                bit >>= 1;

                if ((bit & rankBits) != 0)
                {
                    attackableSquares |= bit;
                }
                else
                {
                    break;
                }
            }while ((bit & occupancyAsLong) == 0);

            return((SquareFlag)attackableSquares);
        }
示例#12
0
        private SquareFlag AddPinnedMovesInternal(
            MoveGenerationWorkspace workspace,
            Square kingSquare,
            SquareFlag potentialPins,
            SquareFlag pinners,
            bool diagonal,
            SquareFlag pushMask,
            SquareFlag captureMask)
        {
            var pinnedSquares = (SquareFlag)0;
            var pinnersAsList = pinners.ToList();

            foreach (var pinner in pinnersAsList)
            {
                var path = AttackBitmaps.Paths[kingSquare.Index][pinner.ToSquareIndex()];

                var squarePinnedByThisPiece = path & potentialPins;

                if (squarePinnedByThisPiece == 0)
                {
                    continue;
                }

                pinnedSquares |= squarePinnedByThisPiece;

                var pushPath    = path & pushMask;
                var capturePath = path & captureMask;

                var pieceType = workspace.RelativeBitBoard.GetPieceType(squarePinnedByThisPiece);

                switch (pieceType)
                {
                case PieceType.Pawn when !diagonal:
                    AddIndividualPawnPushes(workspace, squarePinnedByThisPiece.ToSquare(), pushPath);
                    break;

                case PieceType.Pawn when diagonal:
                    AddIndividualPawnCaptures(workspace, squarePinnedByThisPiece.ToSquare(), pushPath, capturePath);
                    break;

                case PieceType.Rook:
                    AddIndividualRayMoves(workspace, squarePinnedByThisPiece.ToSquare(), PieceType.Rook, PieceType.Rook, pushPath | capturePath);
                    break;

                case PieceType.Bishop:
                    AddIndividualRayMoves(workspace, squarePinnedByThisPiece.ToSquare(), PieceType.Bishop, PieceType.Bishop, pushPath | capturePath);
                    break;

                case PieceType.Queen:
                    AddIndividualQueenMoves(workspace, squarePinnedByThisPiece.ToSquare(), pushPath | capturePath);
                    break;
                }
            }

            return(pinnedSquares);
        }
示例#13
0
        public static int GetMagicIndex(PieceType pieceType, int squareIndex, SquareFlag occupancy)
        {
            if (occupancy == 0)
            {
                return(0);
            }

            return(pieceType == PieceType.Rook
                    ? GetRookMagicIndex(squareIndex, occupancy)
                    : GetBishopMagicIndex(squareIndex, occupancy));
        }
示例#14
0
        private void InitPaths()
        {
            var paths = new SquareFlag[64][];

            for (var squareIndex = 0; squareIndex < 64; ++squareIndex)
            {
                paths[squareIndex] = AttackGenerator.GeneratePaths(squareIndex);
            }

            Paths = paths;
        }
        public static SquareFlag ToSquareFlag(this IList <SquareFlag> squaresAsList)
        {
            SquareFlag squares = 0;

            foreach (var square in squaresAsList)
            {
                squares |= square;
            }

            return(squares);
        }
示例#16
0
        private void InitKingAttacks()
        {
            var kingAttacks = new SquareFlag[64];

            for (var squareIndex = 0; squareIndex < 64; ++squareIndex)
            {
                kingAttacks[squareIndex] = AttackGenerator.GeneratePotentialKingAttacks(squareIndex);
            }

            KingAttacks = kingAttacks;
        }
        public static IEnumerable <SquareFlag> ToListFaster(this SquareFlag squares)
        {
            var ulsquares = (ulong)squares;

            for (var i = 1ul; i > 0; i = i << 1)
            {
                if ((ulsquares & i) > 0)
                {
                    yield return((SquareFlag)i);
                }
            }
        }
        public static byte Count(this SquareFlag squares)
        {
            // Solution from: https://stackoverflow.com/questions/12171584/what-is-the-fastest-way-to-count-set-bits-in-uint32
            byte count = 0;

            while (squares != 0)
            {
                count++;
                squares &= squares - 1;
            }

            return(count);
        }
        public void ToList_4_Correct()
        {
            SquareFlag square = SquareFlag.H1 | SquareFlag.A5 | SquareFlag.E6 | SquareFlag.H8;

            var asList = square.ToList();

            Assert.Collection(
                asList,
                item => Assert.Equal(SquareFlag.H1, item),
                item => Assert.Equal(SquareFlag.A5, item),
                item => Assert.Equal(SquareFlag.E6, item),
                item => Assert.Equal(SquareFlag.H8, item));
        }
示例#20
0
        public void Make_EnPassantOnlySetIfCapturePossible(string partialFen, SquareFlag enPassant)
        {
            var board = Create($"rnbqkbnr/pppp1ppp/8/{partialFen}/1P6/2PPPPPP/RNBQKBNR b KQkq -");

            var fromSquare = SquareFlag.D2;
            var toSquare   = SquareFlag.D4;

            var move = MoveBuilder.Create(Colour.White, PieceType.Pawn, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.None, MoveType.Ordinary);

            board.MakeMove(move);

            Assert.Equal(enPassant, board.EnPassant);
        }
示例#21
0
        public Colour GetPieceColour(SquareFlag square)
        {
            if (MySquares.HasFlag(square))
            {
                return(Colour);
            }

            if (OpponentSquares.HasFlag(square))
            {
                return(Colour.Opposite());
            }

            return(Colour.None);
        }
示例#22
0
        private static Colour GetPieceColour(IPieceMap board, SquareFlag square)
        {
            if (board.White.HasFlag(square))
            {
                return(Colour.White);
            }

            if (board.Black.HasFlag(square))
            {
                return(Colour.Black);
            }

            return(Colour.None);
        }
        public static IReadOnlyList <SquareFlag> ToListOrig(this SquareFlag squares)
        {
            IList <SquareFlag> squaresAsList = new List <SquareFlag>();

            for (var i = 1ul; i > 0; i = i << 1)
            {
                if (squares.HasFlag((SquareFlag)i))
                {
                    squaresAsList.Add((SquareFlag)i);
                }
            }

            return((IReadOnlyList <SquareFlag>)squaresAsList);
        }
示例#24
0
        private void InitPawnCaptures()
        {
            var pawnCapturesWhite = new SquareFlag[64];
            var pawnCapturesBlack = new SquareFlag[64];

            // You could potentially use a smaller range EXCEPT that Kings use this from ranks 1 and 8
            for (var squareIndex = 0; squareIndex < 64; ++squareIndex)
            {
                pawnCapturesWhite[squareIndex] = AttackGenerator.GeneratePotentialWhitePawnCaptures(squareIndex);
                pawnCapturesBlack[squareIndex] = AttackGenerator.GeneratePotentialBlackPawnCaptures(squareIndex);
            }

            PawnCapturesWhite = pawnCapturesWhite;
            PawnCapturesBlack = pawnCapturesBlack;
        }
示例#25
0
        public static SquareFlag[] GeneratePaths(int squareIndex)
        {
            SquareFlag[] paths = new SquareFlag[64];

            GenerateNorthPath(squareIndex, paths);
            GenerateNorthEastPath(squareIndex, paths);
            GenerateEastPath(squareIndex, paths);
            GenerateSouthEastPath(squareIndex, paths);
            GenerateSouthPath(squareIndex, paths);
            GenerateSouthWestPath(squareIndex, paths);
            GenerateWestPath(squareIndex, paths);
            GenerateNorthWestPath(squareIndex, paths);

            return(paths);
        }
示例#26
0
        public void MidBoardOnlyOnePush(string fenString, SquareFlag toSquare)
        {
            var gameState = FenHelpers.Parse(fenString);

            var board = CreateBoard(gameState);

            var moves = new List <uint>(10);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var pawnMoveViews = GetPawnMoveViews(moves);

            var pawnMoves = pawnMoveViews.Select(x => x.Value);

            Assert.Collection(pawnMoves, x => Assert.Equal(toSquare, x.GetTo()));
        }
示例#27
0
        public void DiscoverCheck(string fenString, SquareFlag fromSquare, SquareFlag toSquare)
        {
            var gameState = FenHelpers.Parse(fenString);

            var board = CreateBoard(gameState);

            var moves = new List <uint>(20);

            MoveGenerator.Generate(board, gameState.ToPlay, moves);

            var moveCount = moves.Count;

            var illegalMove = MoveBuilder.Create(Colour.White, PieceType.Pawn, fromSquare.ToSquare(), toSquare.ToSquare(), PieceType.None, MoveType.Ordinary);

            Assert.DoesNotContain(illegalMove, moves);
        }
示例#28
0
 public GameState(
     int ply,
     Colour toPlay,
     int halfMoveClock,
     int fullTurn,
     bool whiteCanCastleKingSide,
     bool whiteCanCastleQueenSide,
     bool blackCanCastleKingSide,
     bool blackCanCastleQueenSide,
     SquareFlag whitePawns,
     SquareFlag whiteRooks,
     SquareFlag whiteKnights,
     SquareFlag whiteBishops,
     SquareFlag whiteQueens,
     SquareFlag whiteKing,
     SquareFlag blackPawns,
     SquareFlag blackRooks,
     SquareFlag blackKnights,
     SquareFlag blackBishops,
     SquareFlag blackQueens,
     SquareFlag blackKing,
     SquareFlag enPassant)
 {
     Ply                     = ply;
     ToPlay                  = toPlay;
     HalfMoveClock           = halfMoveClock;
     FullTurn                = fullTurn;
     WhiteCanCastleKingSide  = whiteCanCastleKingSide;
     WhiteCanCastleQueenSide = whiteCanCastleQueenSide;
     BlackCanCastleKingSide  = blackCanCastleKingSide;
     BlackCanCastleQueenSide = blackCanCastleQueenSide;
     WhitePawns              = whitePawns;
     WhiteRooks              = whiteRooks;
     WhiteKnights            = whiteKnights;
     WhiteBishops            = whiteBishops;
     WhiteQueens             = whiteQueens;
     WhiteKing               = whiteKing;
     BlackPawns              = blackPawns;
     BlackRooks              = blackRooks;
     BlackKnights            = blackKnights;
     BlackBishops            = blackBishops;
     BlackQueens             = blackQueens;
     BlackKing               = blackKing;
     EnPassant               = enPassant;
     White                   = WhitePawns | WhiteRooks | WhiteKnights | WhiteBishops | WhiteQueens | WhiteKing;
     Black                   = BlackPawns | BlackRooks | BlackKnights | BlackBishops | BlackQueens | BlackKing;
 }
示例#29
0
        private void GenerateAllOccupancyCombinations(int square, SquareFlag occupancyMask, Action <SortedDictionary <int, SquareFlag>, int, SquareFlag> addToList, SortedDictionary <int, SquareFlag> dictionary)
        {
            var squares = new List <SquareFlag>();

            foreach (var occupancyMaskSquare in occupancyMask.ToList())
            {
                squares.Add(occupancyMaskSquare);
            }

            var numSquares = squares.Count();

            // Generate each 'length' combination
            for (var combinationLength = 0; combinationLength <= numSquares; ++combinationLength)
            {
                CombinationUtil(squares, square, new SquareFlag[numSquares], 0, numSquares - 1, 0, combinationLength, addToList, dictionary);
            }
        }
示例#30
0
        public BoardStateInfo(ulong key, uint move, StateFlag state, SquareFlag enPassant) : this()
        {
            Key        = key;
            Move       = move;
            StateFlags = state;
            EnPassant  = enPassant;

            var movePieceType = move.GetPieceType();
            var moveType      = move.GetMoveType();

            if (movePieceType == PieceType.Pawn ||
                moveType == MoveType.CastleKing ||
                moveType == MoveType.CastleQueen)
            {
                IsIrreversible = true;
            }
        }