示例#1
0
        public void Init()
        {
            var rooks   = new MagicBitboardGenerationEntry[64];
            var bishops = new MagicBitboardGenerationEntry[64];

            //var positions = Enumerable.Range(0, 64);
            //Parallel.ForEach(positions, pos =>
            //foreach (var pos in positions)
            for (var pos = 0; pos < 64; pos++)
            {
                var rank         = pos >> 3;
                var file         = pos & 7;
                var diagonal     = file + rank;
                var antidiagonal = rank - file + 7;


                Bitboard rookMask = BitboardConstants.Ranks[rank];
                rookMask |= BitboardConstants.Files[file];
                if (rank != 0)
                {
                    rookMask &= ~BitboardConstants.Ranks[0];
                }
                if (rank != 7)
                {
                    rookMask &= ~BitboardConstants.Ranks[7];
                }
                if (file != 0)
                {
                    rookMask &= ~BitboardConstants.Files[0];
                }
                if (file != 7)
                {
                    rookMask &= ~BitboardConstants.Files[7];
                }
                rookMask &= ~(1UL << pos);
                var rookEntry = InitEntry(rookMask, false, pos);
                rooks[pos] = rookEntry;

                Bitboard bishopMask = BitboardConstants.Diagonals[diagonal];
                bishopMask |= BitboardConstants.Antidiagonals[antidiagonal];
                bishopMask &= ~BitboardConstants.Ranks[0];
                bishopMask &= ~BitboardConstants.Ranks[7];
                bishopMask &= ~BitboardConstants.Files[0];
                bishopMask &= ~BitboardConstants.Files[7];
                bishopMask &= ~(1UL << pos);
                var bishopEntry = InitEntry(bishopMask, true, pos);
                bishops[pos] = bishopEntry;
            }//);
            MagicBitboards.Rooks   = rooks.Select(x => new MagicBitboardEntry(x.BlockerMask, x.MagicNumber, (byte)(64 - x.BitCount), x.Moveboards)).ToArray();
            MagicBitboards.Bishops = bishops.Select(x => new MagicBitboardEntry(x.BlockerMask, x.MagicNumber, (byte)(64 - x.BitCount), x.Moveboards)).ToArray();
            //PrintBitboardArray(rooks.Select(x => x.MagicNumber).ToList());
            //PrintBitboardArray(bishops.Select(x => x.MagicNumber).ToList());
        }
示例#2
0
        private MagicBitboardGenerationEntry InitEntry(Bitboard blockerMask, bool bishop, int pos)
        {
            var entry = new MagicBitboardGenerationEntry();

            entry.Position    = pos;
            entry.BlockerMask = blockerMask;
            entry.Bishop      = bishop;

            var maskCopy = blockerMask;
            var bits     = new List <int>();

            while (maskCopy != 0)
            {
                var blockerPosition = maskCopy.BitScanForward();
                bits.Add(blockerPosition);
                maskCopy &= maskCopy - 1;
            }

            var permutations = 1 << bits.Count;

            entry.BitCount    = (byte)bits.Count;
            entry.Occupancies = new Bitboard[permutations];
            entry.Moveboards  = new Bitboard[permutations];

            for (var i = 0; i < permutations; i++)
            {
                Bitboard occMask = 0;
                for (var j = 0; j < bits.Count; j++)
                {
                    var shouldSet = (i & (1 << j)) > 0;
                    if (shouldSet)
                    {
                        var bit = bits[j];
                        occMask |= 1UL << bit;
                    }
                }

                entry.Occupancies[i] = occMask;
                var moveboard = bishop ? _otherSlideGenerator.DiagonalAntidiagonalSlide(occMask, pos) : _otherSlideGenerator.HorizontalVerticalSlide(occMask, pos);
                entry.Moveboards[i] = moveboard;
            }

            entry.MagicNumber = FindMagicNumber(entry);

            return(entry);
        }
示例#3
0
        private Bitboard FindMagicNumber(MagicBitboardGenerationEntry generationEntry)
        {
            const Bitboard invalid = ~0UL;

            Bitboard magicNumber = 0UL;
            var      success     = false;
            ulong    iterations  = 0;

            while (true)
            {
                var table = Enumerable.Repeat(invalid, 1 << generationEntry.BitCount).ToArray();
                iterations++;
                magicNumber = _candidateProvider.GetMagicNumberCandidate(generationEntry.Position, generationEntry.Bishop);
                success     = true;
                for (var i = 0; i < generationEntry.Occupancies.Length; i++)
                {
                    var occupancy     = generationEntry.Occupancies[i];
                    var moveboard     = generationEntry.Moveboards[i];
                    var multiplied    = occupancy * magicNumber;
                    var magicIndex    = multiplied >> (64 - generationEntry.BitCount);
                    var magicIndexInt = (int)magicIndex;
                    if (table[magicIndexInt] == invalid || table[magicIndexInt] == moveboard)
                    {
                        table[magicIndexInt] = moveboard;
                    }
                    else
                    {
                        success = false;
                        break;
                    }
                }

                if (success)
                {
                    generationEntry.MagicNumber = magicNumber;
                    generationEntry.Moveboards  = table;
                    break;
                }
            }

            Console.WriteLine($"{(generationEntry.Bishop ? "Bishop" : "Rook")} at position {generationEntry.Position}: {iterations} iterations");
            return(magicNumber);
        }