private static Bitboard[] InitializeConnections()
        {
            var result = new Bitboard[ChessConstants.SquareCount * ChessConstants.SquareCount];

            result.Initialize(i => Bitboard.Everything);

            for (var squareIndex = 0; squareIndex < ChessConstants.SquareCount; squareIndex++)
            {
                var source = Bitboard.FromSquareIndex(squareIndex);

                foreach (var direction in AllDirections)
                {
                    var current    = source;
                    var connection = Bitboard.None;
                    while ((current = current.Shift(direction)).IsAny)
                    {
                        var anotherSquareIndex = current.FindFirstSquareIndex();
                        var index        = GetConnectionIndex(squareIndex, anotherSquareIndex);
                        var reverseIndex = GetConnectionIndex(anotherSquareIndex, squareIndex);
                        result[index] = result[reverseIndex] = connection;

                        connection |= current;
                    }
                }
            }

            return(result);
        }
        private static Bitboard[] InitializeDiagonallySlidingAttacks()
        {
            var result = new Bitboard[ChessConstants.SquareCount];

            var directions = new[]
            {
                ShiftDirection.NorthEast,
                ShiftDirection.SouthEast,
                ShiftDirection.SouthWest,
                ShiftDirection.NorthWest
            };

            for (var squareIndex = 0; squareIndex < ChessConstants.SquareCount; squareIndex++)
            {
                var bitboard = Bitboard.FromSquareIndex(squareIndex);

                var attackBitboard = Bitboard.None;
                foreach (var direction in directions)
                {
                    var current = bitboard;
                    while ((current = current.Shift(direction)).IsAny)
                    {
                        attackBitboard |= current;
                    }
                }

                result[squareIndex] = attackBitboard;
            }

            return(result);
        }
        private static void PopulatePinLimitations(
            Bitboard[] pinLimitations,
            Bitboard enemyPieces,
            int squareIndex,
            Bitboard ownPieces,
            Bitboard[] slidingAttacks,
            Bitboard slidingPieces)
        {
            var slidingAttack    = slidingAttacks[squareIndex];
            var potentialPinners = slidingPieces & slidingAttack;

            var current = potentialPinners;

            while (current.IsAny)
            {
                var attackerSquareIndex = Bitboard.PopFirstSquareIndex(ref current);
                var connection          = GetConnection(squareIndex, attackerSquareIndex);

                var pinned = ownPieces & connection;
                var enemiesOnConnection = enemyPieces & connection;
                if (enemiesOnConnection.IsAny || !pinned.IsExactlyOneSquare())
                {
                    continue;
                }

                var pinnedSquareIndex = pinned.FindFirstSquareIndex();
                pinLimitations[pinnedSquareIndex] = connection | Bitboard.FromSquareIndex(attackerSquareIndex);
            }
        }
        private void GenerateSlidingPieceMoves(
            [NotNull] ICollection <GameMoveData> resultMoves,
            GameSide side,
            GeneratedMoveTypes moveTypes,
            PieceType pieceType,
            ShiftDirection[] directions)
        {
            var piece  = pieceType.ToPiece(side);
            var pieces = PiecePosition[piece];

            var emptySquares = PiecePosition[Piece.None];
            var enemies      = PiecePosition[side.Invert()];

            var shouldGenerateQuiets   = moveTypes.IsAnySet(GeneratedMoveTypes.Quiet);
            var shouldGenerateCaptures = moveTypes.IsAnySet(GeneratedMoveTypes.Capture);

            while (pieces.IsAny)
            {
                var sourceSquareIndex = Bitboard.PopFirstSquareIndex(ref pieces);
                var sourceBitboard    = Bitboard.FromSquareIndex(sourceSquareIndex);
                var sourceSquare      = new Square(sourceSquareIndex);

                foreach (var direction in directions)
                {
                    var current = sourceBitboard;

                    while ((current = current.Shift(direction)).IsAny)
                    {
                        if ((current & emptySquares).IsAny)
                        {
                            if (shouldGenerateQuiets)
                            {
                                var move = new GameMove(sourceSquare, current.GetFirstSquare());
                                resultMoves.Add(new GameMoveData(move, GameMoveFlags.None));
                            }

                            continue;
                        }

                        if ((current & enemies).IsAny)
                        {
                            if (shouldGenerateCaptures)
                            {
                                var move = new GameMove(sourceSquare, current.GetFirstSquare());
                                resultMoves.Add(
                                    new GameMoveData(move, GameMoveFlags.IsRegularCapture));
                            }
                        }

                        break;
                    }
                }
            }
        }
Beispiel #5
0
        public void TestFromSquareIndexAndFromSquareIndexInternal()
        {
            for (var squareIndex = 0; squareIndex < ChessConstants.SquareCount; squareIndex++)
            {
                var expectedValue = 1UL << squareIndex;

                var bitboard = Bitboard.FromSquareIndex(squareIndex);
                Assert.That(bitboard.InternalValue, Is.EqualTo(expectedValue));

                var internalValue = Bitboard.FromSquareIndexInternal(squareIndex);
                Assert.That(internalValue, Is.EqualTo(expectedValue));
            }
        }
Beispiel #6
0
        public void TestFromSquareIndexAndFromSquareIndexInternalNegativeCases(int squareIndex)
        {
            const string ParameterName = "squareIndex";

            Assert.That(
                () => Bitboard.FromSquareIndex(squareIndex),
                Throws.TypeOf <ArgumentOutOfRangeException>()
                .With
                .Property(nameof(ArgumentOutOfRangeException.ParamName))
                .EqualTo(ParameterName));

            Assert.That(
                () => Bitboard.FromSquareIndexInternal(squareIndex),
                Throws.TypeOf <ArgumentOutOfRangeException>()
                .With
                .Property(nameof(ArgumentOutOfRangeException.ParamName))
                .EqualTo(ParameterName));
        }
        private static Bitboard[] InitializeKingAttacksOrMoves()
        {
            var result = new Bitboard[ChessConstants.SquareCount * ChessConstants.SquareCount];

            var directions = EnumFactotum.GetAllValues <ShiftDirection>();

            for (var squareIndex = 0; squareIndex < ChessConstants.SquareCount; squareIndex++)
            {
                var sourceBitboard = Bitboard.FromSquareIndex(squareIndex);

                var movesBitboard = directions
                                    .Select(sourceBitboard.Shift)
                                    .Aggregate(Bitboard.None, (current, bitboard) => current | bitboard);

                result[squareIndex] = movesBitboard;
            }

            return(result);
        }