コード例 #1
0
        public void Add(int ix, MagicMoveTable.Info info)
        {
            Debug.Assert(ix >= 0 && ix < 64);

            if (!MagicFinder.CheckMagic(info.Mask, info.Magic))
            {
                // we don't need to warn that magic was invalid if they didn't provide a magic
                if (info.Magic != 0)
                {
                    _magicFailed = true;
                }

                info.Magic = _magicFinder.FindMagic(info.Mask);
            }

            _infos.Add(ix, info);
        }
コード例 #2
0
        private static void AddMovesFromSquare(MagicMoveTableBuilder builder, int srcFile, int srcRank, Color color)
        {
            ulong        mask        = 0;
            List <ulong> occupancies = new List <ulong>();
            List <ulong> moves       = new List <ulong>();

            int direction     = color.GetPawnDirection();
            var dstRank       = srcRank + (direction * 2);
            var inbetweenRank = srcRank + direction;

            if (IsStartingRank(srcRank, color))
            {
                mask |= Position.ValueFromFileRank(srcFile, inbetweenRank);
                mask |= Position.ValueFromFileRank(srcFile, dstRank);
            }

            int maskBits         = Bits.PopCount(mask);
            int maskPermutations = 1 << maskBits;

            for (int permutation = 0; permutation < maskPermutations; permutation++)
            {
                ulong occupancy     = Bits.ParallelBitDeposit((ulong)permutation, mask);
                ulong singularMoves = 0;

                // if there are any pieces in the 2 squares we're checking, then
                if (IsStartingRank(srcRank, color) && occupancy == 0)
                {
                    singularMoves |= Position.ValueFromFileRank(srcFile, dstRank);
                }

                occupancies.Add(occupancy);
                moves.Add(singularMoves);
            }

            var ix   = Position.IxFromFileRank(srcFile, srcRank);
            var info = new MagicMoveTable.Info
            {
                Magic = Magics[(int)color].GetOrDefault(ix),
                Mask  = mask,
                MaskedOccupancyKeys = occupancies.ToArray(),
                MovesValues         = moves.ToArray(),
            };

            builder.Add(ix, info);
        }
コード例 #3
0
        private static void AddMovesFromSquare(MagicMoveTableBuilder builder, int srcFile, int srcRank)
        {
            ulong        mask        = 0;
            List <ulong> occupancies = new List <ulong>();
            List <ulong> moves       = new List <ulong>();

            // populate mask
            // Note: mask rays don't extend to the edge of the map; this is because if a ray reaches all the way to the edge of the board, that square's occupancy doesn't affect move generation.

            // up/left
            for (int i = 1;; i++)
            {
                int dstFile = srcFile - i;
                int dstRank = srcRank + i;
                if (!InsideOuterRing(dstFile, dstRank))
                {
                    break;
                }

                mask |= Position.ValueFromFileRank(dstFile, dstRank);
            }

            // up/right
            for (int i = 1; ; i++)
            {
                int dstFile = srcFile + i;
                int dstRank = srcRank + i;
                if (!InsideOuterRing(dstFile, dstRank))
                {
                    break;
                }

                mask |= Position.ValueFromFileRank(dstFile, dstRank);
            }

            // down/left
            for (int i = 1; ; i++)
            {
                int dstFile = srcFile - i;
                int dstRank = srcRank - i;
                if (!InsideOuterRing(dstFile, dstRank))
                {
                    break;
                }

                mask |= Position.ValueFromFileRank(dstFile, dstRank);
            }

            // down/right
            for (int i = 1; ; i++)
            {
                int dstFile = srcFile + i;
                int dstRank = srcRank - i;
                if (!InsideOuterRing(dstFile, dstRank))
                {
                    break;
                }

                mask |= Position.ValueFromFileRank(dstFile, dstRank);
            }

            int maskBits         = Bits.PopCount(mask);
            int maskPermutations = 1 << maskBits;

            for (int permutation = 0; permutation < maskPermutations; permutation++)
            {
                ulong occupancy     = Bits.ParallelBitDeposit((ulong)permutation, mask);
                ulong singularMoves = 0;

                // Note: rays do now reach all the way to the edge of the board; we do want to generate moves that would reach the end of the board.

                // up/left
                for (int i = 1; ; i++)
                {
                    int dstFile = srcFile - i;
                    int dstRank = srcRank + i;
                    if (!Position.FileRankOnBoard(dstFile, dstRank))
                    {
                        break;
                    }

                    ulong move = Position.ValueFromFileRank(dstFile, dstRank);
                    singularMoves |= move;
                    if ((occupancy & move) > 0)
                    {
                        break;
                    }
                }

                // up/right
                for (int i = 1; ; i++)
                {
                    int dstFile = srcFile + i;
                    int dstRank = srcRank + i;
                    if (!Position.FileRankOnBoard(dstFile, dstRank))
                    {
                        break;
                    }

                    ulong move = Position.ValueFromFileRank(dstFile, dstRank);
                    singularMoves |= move;
                    if ((occupancy & move) > 0)
                    {
                        break;
                    }
                }

                // down/left
                for (int i = 1; ; i++)
                {
                    int dstFile = srcFile - i;
                    int dstRank = srcRank - i;
                    if (!Position.FileRankOnBoard(dstFile, dstRank))
                    {
                        break;
                    }

                    ulong move = Position.ValueFromFileRank(dstFile, dstRank);
                    singularMoves |= move;
                    if ((occupancy & move) > 0)
                    {
                        break;
                    }
                }

                // down/right
                for (int i = 1; ; i++)
                {
                    int dstFile = srcFile + i;
                    int dstRank = srcRank - i;
                    if (!Position.FileRankOnBoard(dstFile, dstRank))
                    {
                        break;
                    }

                    ulong move = Position.ValueFromFileRank(dstFile, dstRank);
                    singularMoves |= move;
                    if ((occupancy & move) > 0)
                    {
                        break;
                    }
                }

                occupancies.Add(occupancy);
                moves.Add(singularMoves);
            }

            var ix   = Position.IxFromFileRank(srcFile, srcRank);
            var info = new MagicMoveTable.Info
            {
                Magic = Magics.GetOrDefault(ix),
                Mask  = mask,
                MaskedOccupancyKeys = occupancies.ToArray(),
                MovesValues         = moves.ToArray(),
            };

            builder.Add(ix, info);
        }