示例#1
0
        private void Complete2More(RankInfo r0, RankInfo r1, ulong[] fillMask)
        {
            Parallel.For(0, Master.N, Master.ThreadingOptions, (i, loopState) =>
            {
                var bbIdx  = i / 8 + r0.BitboardIndex;
                var bitPos = r0.BitRank & BitBase.BitFiles[i % 8];

                if ((bitPos & fillMask[bbIdx]) == 0)
                {
                    var rootFill = GetRootFillMatrix(bbIdx, bitPos, fillMask);

                    var occupancy    = new ulong[Board.BitboardCount];
                    occupancy[bbIdx] = bitPos;

                    if (SearchLast(new Node(new ulong[][] { rootFill }, occupancy)))
                    {
                        loopState.Stop();
                    }
                    else
                    {
                        Events.OnProgress();
                    }
                }
            });
        }
示例#2
0
 /// <summary> Performs the main search stage using the recursive algorithm. </summary>
 /// <param name="nodes"> The root nodes. </param>
 /// <param name="r2"> Data regarding the 3rd available rank. </param>
 private void NormalSearch(ConcurrentBag <Node> nodes, RankInfo r2)
 {
     Parallel.ForEach(nodes, Master.ThreadingOptions, (node, loopState) =>
     {
         if (Search(node, r2.BitboardIndex, 2, r2.BitRank))
         {
             loopState.Stop();
             _cancelled = true;
         }
         else
         {
             Events.OnProgress();
         }
     });
 }
示例#3
0
        protected override void Solve()
        {
            /* The original fill mask contains not only redundant bits
             * but also the attack masks of queens in the preset.
             *
             * Additionally, we get the information about the first 3 available
             * ranks and store it in small data structures for later use. */

            var fillMask  = PresetMaker.Preset.Fill;
            var ranksInfo = new RankInfo[3];

            for (var i = 0; i < 3; i++)
            {
                ranksInfo[i] = GetFreeRankInfo(i);
            }

            // Handle special cases when there are too little available ranks:
            switch (_lastFreeRankIdx)
            {
            case 0:
                // If it's just 1 rank then create an almost-complete
                // node out of the preset, and search the remaining rank.
                var node = new Node(new ulong[][] { fillMask }, new ulong[Board.BitboardCount]);
                SearchLast(node);
                return;

            case 1:
                // For completing 2 more ranks, there's a special function.
                Complete2More(ranksInfo[0], ranksInfo[1], fillMask);
                return;
            }

            /* Now gather root nodes. Notice the 'limit' variable: now that the 1st available
             * rank may not actually be the 1st, the end of the row must be indicated specially. */

            var nodes = new ConcurrentBag <Node>();
            var limit = ranksInfo[1].BitboardIndex + Board.Dimension;

            Parallel.For(0, Master.N, Master.ThreadingOptions, i =>
            {
                var bbIdx  = i / 8 + ranksInfo[0].BitboardIndex;
                var bitPos = ranksInfo[0].BitRank & BitBase.BitFiles[i % 8];

                // The first available rank is not guaranteed to be
                // completely free so we perform the following check:
                if ((bitPos & fillMask[bbIdx]) == 0)
                {
                    var rootFill = GetRootFillMatrix(bbIdx, bitPos, fillMask);

                    for (var j = ranksInfo[1].BitboardIndex; j < limit; j++)
                    {
                        AddNode(nodes, rootFill, j, bbIdx, bitPos, ranksInfo[1].BitRank);
                    }
                }
            });

            if (_lastFreeRankIdx == 2)
            {
                // This means that, after the nodes, there is only 1 rank left
                // to complete. So we call a special last-stage function:
                LastRankSearch(nodes);
            }
            else
            {
                // More than 1 more ranks, therefore pass the nodes to the common function:
                NormalSearch(nodes, ranksInfo[2]);
            }
        }
示例#4
0
 /// <summary> Initializes a new CompletionSolver. </summary>
 public CompletionSolver()
 {
     _lastFreeRankInfo = GetFreeRankInfo(_lastFreeRankIdx);
     _bbLimit          = _lastFreeRankInfo.BitboardIndex + Board.Dimension;
     ColumnHeight      = _lastFreeRankIdx > 1 ? _lastFreeRankIdx - 1 : 1;
 }