Exemple #1
0
        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));
                }
            }
        }
Exemple #2
0
        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;
                    }
                }
            }
        }
Exemple #3
0
        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);
 }
Exemple #6
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);
            }
        }
Exemple #7
0
        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);
                }
            }
        }