예제 #1
0
        /// <summary>
        /// Calculates attacks for the specified piece.
        /// </summary>
        /// <param name="pieceBitboard">The bitboard with set bit at piece position.</param>
        /// <param name="excludedFields">The bitboard with excluded fields from attacks calculating.</param>
        /// <param name="opt">The generator parameters.</param>
        private static void CalculateAttacks(ulong pieceBitboard, ulong excludedFields, GeneratorParameters opt)
        {
            if ((opt.Mode & GeneratorMode.CalculateAttacks) == 0)
            {
                return;
            }

            var pieceIndex       = BitOperations.GetBitIndex(pieceBitboard);
            var blockersToRemove = opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Bishop)] |
                                   opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Queen)];

            var allPiecesOccupancy = opt.OccupancySummary & ~blockersToRemove;

            var pattern = MagicContainer.GetBishopAttacks(pieceIndex, allPiecesOccupancy);

            pattern  = CalculatePawnBlockers(pieceIndex, pattern, opt);
            pattern ^= excludedFields;

            while (pattern != 0)
            {
                var patternLSB = BitOperations.GetLSB(pattern);
                pattern = BitOperations.PopLSB(pattern);

                var patternIndex = BitOperations.GetBitIndex(patternLSB);

                opt.Bitboard.Attacks[patternIndex] |= pieceBitboard;
                opt.Bitboard.AttacksSummary[(int)opt.FriendlyColor] |= patternLSB;
            }
        }
예제 #2
0
        /// <summary>
        /// Calculates moves for the specified piece.
        /// </summary>
        /// <param name="pieceType">The piece type.</param>
        /// <param name="pieceBitboard">The bitboard with set bit at piece position.</param>
        /// <param name="opt">The generator parameters.</param>
        /// <returns>The bitboard with available moves for the specified piece.</returns>
        private static ulong CalculateMoves(PieceType pieceType, ulong pieceBitboard, GeneratorParameters opt)
        {
            if ((opt.Mode & GeneratorMode.CalculateMoves) == 0)
            {
                return(0);
            }

            var pieceIndex    = BitOperations.GetBitIndex(pieceBitboard);
            var piecePosition = BitPositionConverter.ToPosition(pieceIndex);

            var pattern = MagicContainer.GetBishopAttacks(pieceIndex, opt.OccupancySummary);

            pattern &= ~opt.FriendlyOccupancy;

            if (opt.QuiescenceSearch)
            {
                pattern &= opt.EnemyOccupancy;
            }

            var excludeFromAttacks = pattern;

            while (pattern != 0)
            {
                var patternLSB = BitOperations.GetLSB(pattern);
                pattern = BitOperations.PopLSB(pattern);

                var patternIndex = BitOperations.GetBitIndex(patternLSB);
                var to           = BitPositionConverter.ToPosition(patternIndex);

                if ((patternLSB & opt.EnemyOccupancy) == 0)
                {
                    opt.Bitboard.Moves.AddLast(new QuietMove(piecePosition, to, pieceType, opt.FriendlyColor));
                }
                else
                {
                    opt.Bitboard.Moves.AddLast(new KillMove(piecePosition, to, pieceType, opt.FriendlyColor));
                }

                if ((opt.Mode & GeneratorMode.CalculateAttacks) != 0)
                {
                    opt.Bitboard.Attacks[patternIndex] |= pieceBitboard;
                    opt.Bitboard.AttacksSummary[(int)opt.FriendlyColor] |= patternLSB;
                }
            }

            return(excludeFromAttacks);
        }