protected void GeneratePotentialKingMoves( [NotNull] ICollection <GameMoveData2> resultMoves, GameSide side, GeneratedMoveTypes moveTypes, Bitboard target, CastlingOptions allowedCastlingOptions) { if (resultMoves is null) { throw new ArgumentNullException(nameof(resultMoves)); } var kingPiece = side.ToPiece(PieceType.King); var kings = PiecePosition[kingPiece]; while (kings.IsAny) { var kingSquareIndex = Bitboard.PopFirstSquareIndex(ref kings); var sourceSquare = new Square(kingSquareIndex); var moves = KingAttacksOrMoves[kingSquareIndex]; var movesOnTarget = moves & target; if (moveTypes.IsAnySet(GeneratedMoveTypes.Capture)) { var enemies = PiecePosition[side.Invert()]; var captures = movesOnTarget & enemies; PopulateSimpleMoves(resultMoves, sourceSquare, captures, GameMoveFlags.IsRegularCapture); } //// ReSharper disable once InvertIf if (moveTypes.IsAnySet(GeneratedMoveTypes.Quiet)) { var emptySquares = PiecePosition[Piece.None]; var nonCaptures = movesOnTarget & emptySquares; PopulateSimpleMoves(resultMoves, sourceSquare, nonCaptures, GameMoveFlags.None); var nonEmptySquares = ~emptySquares; PopulateKingCastlingMoves( resultMoves, sourceSquare, target, allowedCastlingOptions, nonEmptySquares, CastlingSide.KingSide.ToCastlingType(side)); PopulateKingCastlingMoves( resultMoves, sourceSquare, target, allowedCastlingOptions, nonEmptySquares, CastlingSide.QueenSide.ToCastlingType(side)); } } }
private void GenerateSlidingPieceMoves( [NotNull] ICollection <GameMoveData2> resultMoves, GameSide side, GeneratedMoveTypes moveTypes, PieceType pieceType, [NotNull] 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); //// TODO [HarinezumiSama] NEW-DESIGN: IDEA: Generate for all pieces rather for one by one 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 GameMove2(sourceSquare, current.GetFirstSquare()); resultMoves.Add(new GameMoveData2(move, GameMoveFlags.None)); } continue; } if ((current & enemies).IsAny) { if (shouldGenerateCaptures) { var move = new GameMove2(sourceSquare, current.GetFirstSquare()); resultMoves.Add( new GameMoveData2(move, GameMoveFlags.IsRegularCapture)); } } break; } } } }
protected void GeneratePotentialBishopMoves( [NotNull] List <GameMoveData2> resultMoves, GameSide side, GeneratedMoveTypes moveTypes) { if (resultMoves is null) { throw new ArgumentNullException(nameof(resultMoves)); } GenerateSlidingPieceMoves(resultMoves, side, moveTypes, PieceType.Bishop, BishopDirections); }
public void GenerateRookMoves( [NotNull] List <GameMoveData> resultMoves, GameSide side, GeneratedMoveTypes moveTypes) { if (resultMoves is null) { throw new ArgumentNullException(nameof(resultMoves)); } GenerateSlidingPieceMoves(resultMoves, side, moveTypes, PieceType.Rook, RookDirections); }
public static bool IsAnySet(this GeneratedMoveTypes value, GeneratedMoveTypes flags) { return((value & flags) != 0); }
protected void GeneratePotentialPawnMoves( [NotNull] ICollection <GameMoveData2> resultMoves, GameSide side, GeneratedMoveTypes moveTypes, Bitboard target, Bitboard enPassantCaptureTarget) { if (resultMoves is null) { throw new ArgumentNullException(nameof(resultMoves)); } var pawnPiece = side.ToPiece(PieceType.Pawn); var pawns = PiecePosition[pawnPiece]; if (pawns.IsNone) { return; } var rank8 = side == GameSide.White ? Bitboards.Rank8 : Bitboards.Rank1; if (moveTypes.IsAnySet(GeneratedMoveTypes.Quiet)) { var forwardDirection = side == GameSide.White ? ShiftDirection.North : ShiftDirection.South; var emptySquares = PiecePosition[Piece.None]; var pushes = pawns.Shift(forwardDirection) & emptySquares; var targetPushes = pushes & target; if (targetPushes.IsAny) { var nonPromotionPushes = targetPushes & ~rank8; PopulatePawnMoves(resultMoves, nonPromotionPushes, (int)forwardDirection, GameMoveFlags.None); var promotionPushes = targetPushes & rank8; PopulatePawnMoves( resultMoves, promotionPushes, (int)forwardDirection, GameMoveFlags.IsPawnPromotion); } if (pushes.IsAny) { var rank3 = side == GameSide.White ? Bitboards.Rank3 : Bitboards.Rank6; var doublePushes = (pushes & rank3).Shift(forwardDirection) & emptySquares & target; PopulatePawnMoves( resultMoves, doublePushes, (int)forwardDirection << 1, GameMoveFlags.None); } } //// ReSharper disable once InvertIf if (moveTypes.IsAnySet(GeneratedMoveTypes.Capture)) { var enemies = PiecePosition[side.Invert()]; var enemyTargets = enemies & target; var leftCaptureOffset = side == GameSide.White ? ShiftDirection.NorthWest : ShiftDirection.SouthEast; PopulatePawnCaptures(resultMoves, pawns, enemyTargets, leftCaptureOffset, rank8, enPassantCaptureTarget); var rightCaptureOffset = side == GameSide.White ? ShiftDirection.NorthEast : ShiftDirection.SouthWest; PopulatePawnCaptures(resultMoves, pawns, enemyTargets, rightCaptureOffset, rank8, enPassantCaptureTarget); } }
protected void GeneratePotentialKnightMoves( [NotNull] ICollection <GameMoveData2> resultMoves, GameSide side, GeneratedMoveTypes moveTypes, Bitboard target) { if (resultMoves is null) { throw new ArgumentNullException(nameof(resultMoves)); } var emptySquares = PiecePosition[Piece.None]; var enemies = PiecePosition[side.Invert()]; var internalTarget = Bitboard.None; if (moveTypes.IsAnySet(GeneratedMoveTypes.Quiet)) { internalTarget |= emptySquares; } if (moveTypes.IsAnySet(GeneratedMoveTypes.Capture)) { internalTarget |= enemies; } var actualTarget = target & internalTarget; if (actualTarget.IsNone) { return; } var knightPiece = side.ToPiece(PieceType.Knight); var knights = PiecePosition[knightPiece]; while (knights.IsAny) { var sourceSquareIndex = Bitboard.PopFirstSquareIndex(ref knights); var moves = KnightAttacksOrMoves[sourceSquareIndex]; var movesOnTarget = moves & actualTarget; if (movesOnTarget.IsNone) { continue; } var sourceSquare = new Square(sourceSquareIndex); if (moveTypes.IsAnySet(GeneratedMoveTypes.Capture)) { var captures = movesOnTarget & enemies; PopulateSimpleMoves(resultMoves, sourceSquare, captures, GameMoveFlags.IsRegularCapture); } //// ReSharper disable once InvertIf if (moveTypes.IsAnySet(GeneratedMoveTypes.Quiet)) { var nonCaptures = movesOnTarget & emptySquares; PopulateSimpleMoves(resultMoves, sourceSquare, nonCaptures, GameMoveFlags.None); } } }