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; } } } }
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)); } }
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); }