private void SetGroupedLink(int tfx, int type, int no, UGrCells LA, UGrCells LB, bool Print = false)
        {
            if (LA.Count == 0 || LB.Count == 0)
            {
                return;
            }
            if (LA.Count == 1 && LB.Count == 1)
            {
                return;
            }
            GroupedLink GrpLK = new GroupedLink(LA, LB, tfx, type);
            int         ix    = GrpCeLKLst.FindIndex(P => (P.Equals(GrpLK)));

            if (ix >= 0)
            {
                return;
            }
            GrpCeLKLst.Add(GrpLK);

            if (Print)
            {
                WriteLine($"\r*LA tfx:{tfx} type:{type} no:{(no+1)}");
                LA.ForEach(P => WriteLine(P));
                WriteLine("*LB");
                LB.ForEach(P => WriteLine(P));
            }
        }
        private int GroupedNLEx_CheckSolution(USuperLink GNL_Result, ref int contDiscontF)
        {
            bool SolFound = false;

            GroupedLink GLKnxt = GNL_Result.resultGLK;

            if (GLKnxt == null)
            {
                return(-1);                                     //Not established
            }
            List <GroupedLink> SolLst = Convert_ChainToList_GNL(GNL_Result);

            if (SolLst == null || SolLst.Count < 2)
            {
                return(-1);                                    //Not established
            }
            GroupedLink GLKorg  = SolLst[0];
            bool        SolType = Check_SuperLinkSequence(GLKnxt, GLKorg); //true:Continuous  false:DisContinuous

            contDiscontF = SolType? 1: 2;

            if (SolType)         //==================== continuous ====================
            {
                Bit81 UsedCs = SolLst.Aggregate(new Bit81(), (Q, P) => Q | P.UGCellsB.B81);

                foreach (var LK in SolLst.Where(P => (P.type == W)))
                {
                    int   noB   = 1 << LK.no;
                    Bit81 SolBP = new Bit81();
                    LK.UGCellsA.ForEach(P => { if ((P.FreeB & noB) > 0)
                                               {
                                                   SolBP.BPSet(P.rc);
                                               }
                                        });
                    LK.UGCellsB.ForEach(P => { if ((P.FreeB & noB) > 0)
                                               {
                                                   SolBP.BPSet(P.rc);
                                               }
                                        });
                    if (SolBP.BitCount() <= 1)
                    {
                        continue;
                    }
                    foreach (var P in pBDL.Where(p => (p.FreeB & noB) > 0))
                    {
                        if (UsedCs.IsHit(P.rc))
                        {
                            continue;
                        }
                        if (!(SolBP - ConnectedCells[P.rc]).IsZero())
                        {
                            continue;
                        }
                        if ((P.FreeB & noB) == 0)
                        {
                            continue;
                        }
                        P.CancelB |= noB; �@�@//exclusion digit
        private bool CheckUsed(Bit81 UsedPre, GroupedLink GLKnxt)
        {
            Bit81 BP = GLKnxt.UGCellsB.B81;

            if (GLKnxt is ALSLink)
            {
                BP -= (GLKnxt.UGCellsA.B81);
            }
            return(UsedPre.IsHit(BP)); //Overlap Check
        }
        private bool _GroupedNL_LoopCheck(GroupedLink GLK0, GroupedLink GLKnxt)
        {
            UGrCells Qorg = GLK0.UGCellsA;
            UGrCells Qdst = GLKnxt.UGCellsB;

            if (Qdst.Count != 1)
            {
                return(false);
            }
            return(Qdst[0].rc == Qorg[0].rc);
        }
        public string _GenMessage2true(USuperLink USLK, UCell PX, int noX)
        {
            GroupedLink Pdes = (GroupedLink)USLK.chainDesLKT[PX.rc, noX];            //��
            string      st   = "";

            if (Pdes != null)
            {
                st += "   " + _chainToString2(PX, Pdes, -(noX + 1));                     //��_chainToString2
            }
            return(st);
        }
        public string _GenMessage2false(USuperLink USLK, UCell P, int no)
        {
            GroupedLink Pdes = (GroupedLink)USLK.chainDesLKF[P.rc, no];           //��
            string      st   = "";

            if (Pdes != null)
            {
                st += "   " + _chainToString2(P, Pdes, -(no + 1));                      //��_chainToString2
            }
            return(st);
        }
 public USuperLink(int rc0, int no0)
 {
     this.rc0 = rc0; this.no0 = no0;
     Qtrue    = new Bit81[9];
     Qfalse   = new Bit81[9];
     for (int k = 0; k < 9; k++)
     {
         Qtrue[k] = new Bit81();  Qfalse[k] = new Bit81();
     }
     chainDesLK  = new object[81, 9];
     chainDesLKT = new object[81, 9]; //��
     chainDesLKF = new object[81, 9]; //��
     resultGLK   = null;
 }
        public bool Check_SuperLinkSequence(GroupedLink GLKpre, GroupedLink GLKnxt)
        {
            if (GLKpre == null)
            {
                WriteLine("null");
            }
            int typP = GLKpre.type;

            if (GLKpre is ALSLink)
            {
                typP = S;
            }
            int noP = GLKpre.no2;

            int typN = GLKnxt.type;
            int noN  = GLKnxt.no;

            UCellLink LKpre = GLKpre.UCelLK;
            UCellLink LKnxt = GLKnxt.UCelLK;

            int FreeBC = 0;

            if (LKpre != null)
            {
                FreeBC = pBDL[LKpre.rc2].FreeBC;

                if (LKnxt != null)   //singleLink -> singleLink
                {
                    return(_Check_SWSequenceSub(typP, noP, LKnxt.type, noN, FreeBC));
                }
                else                //singleLink -> multiLink
                {
                    UGrCells UGrCs = GLKnxt.UGCellsA;
                    if (UGrCs.Count == 1) //singleCell -> singleCell
                    {
                        return(_Check_SWSequenceSub(typP, noP, typN, noN, FreeBC));
                    }
                }
            }
            else if (GLKpre.UGCellsB.Count == 1 && LKnxt != null) // multiLink -> singleLink
            {
                FreeBC = GLKpre.UGCellsB.FreeB.BitCount();
                return(_Check_SWSequenceSub(typP, noP, typN, noN, FreeBC));
            }

            FreeBC = GLKpre.UGCellsB.FreeB.BitCount();
            return(_Check_SWSequenceSub(typP, noP, typN, noN, FreeBC));
        }
Ejemplo n.º 9
0
        private string _GenMessage(USuperLink USLK, UCell P, int no)
        {
            string st           = "";
            var    pQtrue       = USLK.Qtrue;
            var    pQfalse      = USLK.Qfalse;
            var    pchainDesLKT = USLK.chainDesLKT;
            var    pchainDesLKF = USLK.chainDesLKF;

            if (pQfalse[no].IsHit(P.rc))
            {
                GroupedLink Pdes = (GroupedLink)pchainDesLKF[P.rc, no];
                st += _chainToString(P, Pdes, -(no + 1)) + "\r";
            }
            if (pQtrue[no].IsHit(P.rc))
            {
                GroupedLink Pdes = (GroupedLink)pchainDesLKT[P.rc, no];
                st += _chainToString(P, Pdes, no + 1) + "\r";
            }
            return(st);
        }
        public string _chainToString2(UCell U, GroupedLink Gdes, int noRem)
        {
            string st = "";

            try{
                if (Gdes == null)
                {
                    return(st);
                }
                var Qlst = new List <GroupedLink>();

                var X = Gdes;
                while (!(X.tfx == -1 && X.no == X.no2 && X.rootF))
                {
                    Qlst.Add(X);
                    X = X.preGrpedLink as GroupedLink;
                    if (X == null || Qlst.Count > 20)
                    {
                        break;
                    }
                }
                Qlst.Reverse();
                st = "";
                foreach (var R in Qlst)
                {
                    st += R.GrLKToString() + " => ";
                }
                ;
                if (st.Length > 4)
                {
                    st = st.Substring(0, st.Length - 4);
                }

                if (Qlst.Count > 20)
                {
                    st = " ## loop? error ##" + st;
                }
            }
            catch (Exception e) { WriteLine($"{e.Message}\r{e.StackTrace}"); }
            return(st);
        }
Ejemplo n.º 11
0
        private bool _IsLooped(GroupedLink P)
        {
            UGrCells PB = P.UGCellsB;
            var      Q  = P.preGrpedLink as GroupedLink;
            int      nc = 0;

            while (Q != null)
            {
                UGrCells QA = Q.UGCellsA;
                if (QA.Equals(PB))
                {
                    return(true);
                }
                Q = Q.preGrpedLink as GroupedLink;
                if (++nc > 20)
                {
                    return(true);                   //БеБеБеБе ГoГOВаВш БеБеБеБе
                }
            }
            return(false);
        }
Ejemplo n.º 12
0
        public List <GroupedLink> Convert_ChainToList_GNL(USuperLink GNL_Result)
        {
            if (GNL_Result == null)
            {
                return(null);
            }

            var         SolLst = new List <GroupedLink>();
            GroupedLink GLKnxt = GNL_Result.resultGLK;

            //===================== convert chain to list ===========================
            GroupedLink X = GLKnxt;

            while (X != null && SolLst.Count < 50)
            {
                SolLst.Add(X);
                X = X.preGrpedLink as GroupedLink;
            }
            SolLst.Reverse();

            return(SolLst);
        }
Ejemplo n.º 13
0
        private string _chainToString(UCell U, GroupedLink Gdes, int noRem)
        {
            string st = "";

            if (Gdes == null)
            {
                return(st);
            }
            var Qlst = new List <GroupedLink>();

            var X = Gdes;

            while (X != null)
            {
                Qlst.Add(X);
                X = X.preGrpedLink as GroupedLink;
                if (Qlst.Count > 10)
                {
                    break;               //error
                }
            }
            Qlst.Reverse();
            string pm = ((noRem > 0)? "+":"") + noRem;

            st = "r" + (U.r + 1) + "c" + (U.c + 1) + "(" + U.rc + ")/" + pm + " ";
            foreach (var R in Qlst)
            {
                st += R.GrLKToString() + " => ";
            }
            ;
            st = st.Substring(0, st.Length - 4);

            if (Qlst.Count > 20)
            {
                st = " ##loop? error##" + st;
            }
            return(st);
        }
Ejemplo n.º 14
0
        public string __Debug_ChainPrint(GroupedLink P, bool PrintOn = true)
        {
            GroupedLink Q  = P;
            string      st = "";

            if (Q == null)
            {
                st += "null";
            }
            else
            {
                int nc = 0;
                do
                {
                    st = Q.GrLKToString() + st;
                    Q  = Q.preGrpedLink as GroupedLink;
                    if (Q == null)
                    {
                        break;
                    }
                    st = " Бб " + st;
                    if (++nc > 20)
                    {
                        break;
                    }
                }while(true);
            }
            st = $"\tБЯ{++_dbCC}БЯ{st}";
            if (P.UGCellsB.B81.Count == 1)
            {
                st += "БЬБЬБЬ";
            }
            if (PrintOn)
            {
                WriteLine(st);
            }
            return(st);
        }
//============================================================================================================
        public bool GenMessage2(USuperLink USLK, UCell P, int no)
        {
            var pQtrue  = USLK.Qtrue;
            var pQfalse = USLK.Qfalse;

            if (!pQfalse[no].IsHit(P.rc) || !pQtrue[no].IsHit(P.rc))
            {
                return(false);
            }

            var pchainDesLKT = USLK.chainDesLKT;                    //��
            var pchainDesLKF = USLK.chainDesLKF; �@�@               //��

            GroupedLink Pdes = (GroupedLink)pchainDesLKT[P.rc, no]; //��
            string      st   = "";

            if (Pdes != null)
            {
                st += "   " + _chainToString2(P, Pdes, -(no + 1)); //��_chainToString2
            }
            Pdes = (GroupedLink)pchainDesLKF[P.rc, no]; �@         //��
            if (Pdes != null)
            {
                if (st.Length > 4)
                {
                    st += "\r";
                }
                else
                {
                    st = "";
                }
                st += "   " + _chainToString2(P, Pdes, no + 1);                             //��_chainToString2
            }
            USLK.stMsg = st;
            return(true);
        }
        public string _chainToStringGNL(USuperLink GNL_Result, ref string st3)
        {
            string st = "";

            if (GNL_Result == null)
            {
                return(st);
            }

            GroupedLink GLKnxt = GNL_Result.resultGLK;
            //pSprLKsMan.Debug_ChainPrint(GLKnxt);
            var         SolLst = pSprLKsMan.Convert_ChainToList_GNL(GNL_Result);
            GroupedLink GLKorg = SolLst[0];

            {//===================== cells coloring ===========================
                foreach (var LK in SolLst)
                {
                    bool bALK = LK is ALSLink;
                    int  type = (LK is ALSLink)? S: LK.type;//ALSLink, in ALS, is S
                    foreach (var P1 in LK.UGCellsA.Select(p => pBDL[p.rc]))
                    {
                        //WriteLine($"---------- {P1}");
                        int noB = (1 << LK.no);
                        if (!bALK)
                        {
                            P1.SetCellBgColor(SolBkCr);
                        }
                        if (type == S)
                        {
                            P1.SetNoBColor(noB, AttCr2);
                        }
                        else
                        {
                            P1.SetNoBColor(noB, AttCr3);
                        }
                    }

                    if (type == W)
                    {
                        foreach (var P2 in LK.UGCellsB.Select(p => pBDL[p.rc]))
                        {
                            int noB2 = (1 << LK.no);
                            if (!bALK)
                            {
                                P2.SetCellBgColor(SolBkCr);
                            }
                            P2.SetNoBColor(noB2, AttCr);
                        }
                    }
                }

                int cx = 2;
                foreach (var LK in SolLst)      // ALS
                {
                    ALSLink ALK = LK as ALSLink;
                    if (ALK == null)
                    {
                        continue;
                    }
                    Color crG = _ColorsLst[cx++];
                    foreach (var P in ALK.ALSbase.B81.IEGet_rc().Select(rc => pBDL[rc]))
                    {
                        P.SetCellBgColor(crG);
                    }
                }
            }

            {//===================== result report ===========================
                st3 = "";
                int SolType = GNL_Result.contDiscontF;
                if (SolType == 1)
                {
                    st = "Nice Loop(Cont.)";             //<>continuous
                }
                else                                     //<>discontinuous
                {
                    int rc = GLKorg.UGCellsA[0].rc;
                    var P  = pBDL[rc];
                    st = "Nice Loop(Discont.) r" + (rc / 9 + 1) + "c" + (rc % 9 + 1);
                    int dcTyp = GLKorg.type * 10 + GLKnxt.type;
                    switch (dcTyp)
                    {
                    case 11: st += $" is {(GLKorg.no+1)}";     P.SetCellBgColor(SolBkCr2); break;

                    case 12: st += $" is not {(GLKnxt.no+1)}"; P.CancelB = 1 << GLKnxt.no; break;

                    case 21: st += $" is not {(GLKorg.no+1)}"; P.CancelB = 1 << GLKorg.no; break;

                    case 22: st += $" is not {(GLKorg.no+1)}"; P.CancelB = 1 << GLKorg.no; break;
                    }
                }

                string st2 = __chainToStringGNLsub(SolLst, ref st3);
                st         = st3 + st;
                Result     = st;
                ResultLong = st + "\r" + st2;
            }
            return(st);
        }
        public USuperLink GNL_EvalSuperLinkChain(GroupedLink GLK_000, int rc0, bool DevelopB = false)
        {
            try{
                if (DevelopB)
                {
                    WriteLine("\r\r10 *1st:" + GLK_000.GrLKToString()); __Debug_ChainPrint(GLK_000);
                }
                int dbX = 0;
                _dbCC = 0;

                int        no0        = GLK_000.no;
                USuperLink GNL_Result = new USuperLink(rc0, no0);
                var        Qtrue      = GNL_Result.Qtrue;
                var        Qfalse     = GNL_Result.Qfalse;
                Qtrue  = GNL_Result.Qtrue;
                Qfalse = GNL_Result.Qfalse;
                var rcQue = new Queue <GroupedLink>();

                GLK_000.preGrpedLink = null;                                            //sentinel(right GroupedLink's preGrpedLink is null)
                GLK_000.UsedCs       = GLK_000.UGCellsB.B81;                            //Set Used

                int contDiscontF = 0;
                rcQue.Enqueue(GLK_000); //Enqueue first GLK

                {                       //====================== First GLK Process ==============================================================
                    GroupedLink RR = GLK_000;
                    int         no2 = RR.no2, no2B = 1 << no2;
                    if (RR.type == S)                       //---------- Check connection conditions. case StrongLink(F->T) ----------
                    {
                        if (RR.UGCellsB.Count == 1)         //if the link's next element is a single cell
                        {
                            UCell RRnxtC = RR.UGCellsB[0];  //RRnxtC:next cell
                            Qtrue[no2].BPSet(RRnxtC.rc);    //set RRnxtC.rc#no2 is true
                            foreach (int nox in RRnxtC.FreeB.IEGet_BtoNo().Where(q => (q != no2)))
                            {
                                Qfalse[nox].BPSet(RRnxtC.rc);                             //set RRnxtC.rc#no2 to false
                                GroupedLink RRR = new GroupedLink(RRnxtC, no2, nox, W);   //GLK_ViVal:GLink in cell(RRnxtC#no2 WeakLink)
                                RRR.preGrpedLink = RR;                                    //set preLink
                                rcQue.Enqueue(RRR);                                       //enqueue next-GLink to RadiationSearchQueue
                                if (DevelopB)
                                {
                                    WriteLine($"        11 S ->RRnxtC[rc:{RRnxtC.rc}]#{nox} is false."); __Debug_ChainPrint(RRR);
                                }
                            }
                        }
                    }
                    else if (RR.type == W)               //---------- Check connection conditions. case WeakLink(T->F) ----------
                    {
                        foreach (UCell P in RR.UGCellsB) //foreach next GLink
                        {
                            if ((P.FreeB & no2B) > 0)
                            {
                                Qfalse[no2].BPSet(P.rc);                                //set P.rc#no2 is true
                                if (DevelopB)
                                {
                                    WriteLine($"        12 W *Rad->{P}   #{no2} is false.");
                                }
                            }
                        }
                    }
                }

                //====================== Radiation Search ==============================================================
                while (rcQue.Count > 0)
                {
                    {   //----- Distinct -----
                        var Q2 = rcQue.ToList().Distinct();
                        rcQue.Clear();
                        foreach (var X in Q2)
                        {
                            rcQue.Enqueue(X);
                        }
                        //if(DevelopB){ WriteLine(); foreach(var P in rcQue) WriteLine($"--rcQue---{P.GrLKToString()}"); WriteLine(); }
                    }

                    GroupedLink R = rcQue.Dequeue();                                                            //dequeue next element(pre-GLink)
                    if (DevelopB)
                    {
                        WriteLine($"\r20�� {dbX++}---Queue:" + R.GrLKToString()); __Debug_ChainPrint(R);
                    }

                    foreach (GroupedLink RR in IEGet_SuperLink(R).Where(p => p.AvailableF))
                    {
                        if (_IsLooped(RR))
                        {
                            continue;
                        }
                        if (R.type != RR.type && R.UGCellsA.Equals(RR.UGCellsB))
                        {
                            continue;                                                                               //Skip back_links
                        }
                        if (!(R.UsedCs & RR.UGCellsB.B81).IsZero())
                        {
                            continue;
                        }
                        RR.preGrpedLink = R;                                                //set preLink
                        RR.UsedCs       = R.UsedCs | RR.UGCellsB.B81;
                        rcQue.Enqueue(RR);                                                  //enqueue next-GLink to RadiationSearchQueue
                        if (DevelopB)
                        {
                            __Debug_ChainPrint(RR); WriteLine($"��   {dbX++}-{++chkX}--RR:" + RR.GrLKToString());
                        }

                        int no2 = RR.no2; //no2:next digit
                        if (RR.type == S) //========== Check connection conditions. case StrongLink(F->T) ==========
                        //if(!(RR.UGCellsB.B81&Qtrue[RR.no2]).IsZero() )  continue;   //xxx if the next element is already setted true, go to the next process
                        {
                            if (RR.UGCellsB.Count == 1)                                        //if the link's next element is a single cell
                            {
                                UCell P = RR.UGCellsB[0];                                      //RRnxtC:next cell

                                if (P.rc == rc0)                                               //Check Loop completion
                                {
                                    GNL_Result.resultGLK = RR;
                                    SolCode = GroupedNLEx_CheckSolution(GNL_Result, ref contDiscontF);  //There are cells/#n that can be excluded.
                                    if (SolCode > 0)
                                    {
                                        goto  LoopCompletion;                               //Established Sudoku solution
                                    }
                                    goto ErrorTrial;                                        //Failed
                                }

                                if (Qtrue[no2].IsHit(P.rc))
                                {
                                    RR.AvailableF = false; continue;
                                }                                                           //AvailableF=false
                                Qtrue[no2].BPSet(P.rc);                                     // set P.rc#no2 is true
                                if (DevelopB)
                                {
                                    WriteLine($"        30S ->P:{P}  +#{no2} is true.");
                                }

                                foreach (int nox in P.FreeB.IEGet_BtoNo().Where(q => (q != no2)))                               // P.rc#no2:True => #nox(!=no2):False
                                {
                                    if (Qfalse[nox].IsHit(P.rc))
                                    {
                                        continue;
                                    }
                                    Qfalse[nox].BPSet(P.rc);                                //set P.rc#no2 to false
                                    if (DevelopB)
                                    {
                                        WriteLine($"        31S ->P:{P}  -#{nox} is false.");
                                    }
                                }
                            }
                        }

                        else if (RR.type == W)                         //========== Check connection conditions. case WeakLink(T->F) ==========
                        {
                            if (!(RR.UGCellsB.B81 & Qfalse[RR.no2]).IsZero())
                            {
                                continue;                                                                               //if the next element is setted false, go to the next process
                            }
                            foreach (UCell P in RR.UGCellsB)                                                            //foreach next GLink
                            {
                                if (Qfalse[no2].IsHit(P.rc))
                                {
                                    continue;
                                }
                                Qfalse[no2].BPSet(P.rc);                                                                    //set P.rc#no2 is true
                                if (DevelopB)
                                {
                                    WriteLine($"       -40W *RR:{P}  -#{no2} is false.");
                                }
                            }
                            rcQue.Enqueue(RR);                                              //enqueue next-GLink to RadiationSearchQueue

                            if (RR.UGCellsB.Count == 1)                                     //if the link's next element is a single cell
                            {
                                UCell P = RR.UGCellsB[0];
                                if (P.FreeBC == 2)                                                                          //If the next is a binary cell
                                {
                                    int nox = P.FreeB.DifSet(1 << no2).BitToNum();
                                    //if(!_Check_LogicalError_GNL(no2,P.rc,Qtrue) )  goto ErrorTrial; //No check required!
                                    //if(Qtrue[nox].IsHit(P.rc)){ RR.AvailableF=false; continue; }//AvailableF=false. No check required!
                                    Qtrue[nox].BPSet(P.rc);                                   //set P.rc#no2 is true

                                    GroupedLink RRR = new GroupedLink(P, no2, nox, S);        //GLK_ViVal:GLink in cell(P#no2 StrongLink)
                                    RRR.preGrpedLink = RR;                                    //set preLink
                                    if (DevelopB)
                                    {
                                        WriteLine($"       +41W *RR:{P}  -#{nox} is true. :{RRR.GrLKToString()}");
                                    }

                                    if (P.rc == rc0)
                                    {
                                        GNL_Result.resultGLK = RR;
                                        SolCode = GroupedNLEx_CheckSolution(GNL_Result, ref contDiscontF);
                                        if (SolCode > 0)
                                        {
                                            goto  LoopCompletion;                          //Solution found
                                        }
                                        goto ErrorTrial;
                                    }
                                }
                            }
                        }
                    }
                }
                return(null);

ErrorTrial:
                return(null);

LoopCompletion:
                GNL_Result.contDiscontF = contDiscontF;

                if (DevelopB)
                {
                    L2SprLkB81[no0].BPSet(rc0);                                                        // Set the searched flag
                    if (DevelopB)
                    {
                        developDisp(rc0, no0, GNL_Result, DevelopB);
                    }
                    L2SprLK[rc0, no0] = GNL_Result;
                }

                return(GNL_Result);
            }
            catch (Exception ex) {
                WriteLine($"{ex.Message}+\r{ex.StackTrace}");
            }
            return(null);
        }
 private void SetUsed(ref Bit81 UsedCs, GroupedLink GLKnxt)
 {
     UsedCs |= GLKnxt.UGCellsB.B81;
 }
        private int _GroupedNL_CheckSolution(GroupedLink GLK0, GroupedLink GLKnxt,
                                             Stack <GroupedLink> SolStack, Bit81 UsedCs)
        {
            bool SolFound = false;
            int  SolType  = pSprLKsMan.Check_SuperLinkSequence(GLKnxt, GLK0)? 1: 2; //1:Continuous 2:DisContinuous

            if (SolType == 1)                                                       //<>continuous
            {
                List <GroupedLink> SolLst = SolStack.ToList();
                //___Debug_Print_GNLChain(SolStack);

                SolLst.Reverse();
                SolLst.Add(GLK0);

                Bit81 UsedCsTmp = new Bit81(UsedCs);
                SetUsed(ref UsedCsTmp, GLKnxt);

                foreach (var LK in SolLst.Where(P => (P.type == W)))
                {
                    int   noB   = 1 << LK.no;
                    Bit81 SolBP = new Bit81();

                    LK.UGCellsA.ForEach(P => { if ((P.FreeB & noB) > 0)
                                               {
                                                   SolBP.BPSet(P.rc);
                                               }
                                        });
                    LK.UGCellsB.ForEach(P => { if ((P.FreeB & noB) > 0)
                                               {
                                                   SolBP.BPSet(P.rc);
                                               }
                                        });
                    if (SolBP.BitCount() <= 1)
                    {
                        continue;
                    }
                    foreach (var P in pBDL.Where(p => (p.FreeB & noB) > 0))
                    {
                        if (UsedCsTmp.IsHit(P.rc))
                        {
                            continue;
                        }
                        if (!(SolBP - ConnectedCells[P.rc]).IsZero())
                        {
                            continue;
                        }
                        if ((P.FreeB & noB) == 0)
                        {
                            continue;
                        }
                        P.CancelB |= noB;   //exclusion digit
                            SolFound = true;
                    }
                }

                var LKpre = SolLst[0];
                foreach (var LK in SolLst.Skip(1))
                {
                    if (LKpre.type == S && LK.type == S && LK.UGCellsA.Count == 1)
                    {
                        var P    = pBDL[LK.UGCellsA[0].rc]; //(for MultiAns code)
                        int noB2 = P.FreeB - ((1 << LKpre.no2) | (1 << LK.no));
                        if (noB2 > 0)
                        {
                            P.CancelB |= noB2; SolFound = true;
                        }
                    }
                    LKpre = LK;
                }
                if (SolFound)
                {
                    SolCode = 1;
                }
            }
            else
            {
                                                         //<>discontinuous
                int   dcTyp = GLK0.type * 10 + GLKnxt.type;
                UCell P     = pBDL[GLK0.UGCellsA[0].rc]; //(for MultiAns code)
                switch (dcTyp)
                {
                case 11:
                    P.FixedNo = GLK0.no + 1;        //Cell number determination
                    P.CancelB = P.FreeB.DifSet(1 << (GLK0.no));
                    SolCode   = 1; SolFound = true; //(1:Fixed)
                    break;

                case 12: P.CancelB = 1 << GLKnxt.no; SolCode = 2; SolFound = true; break;//(2:Exclude from candidates)

                case 21: P.CancelB = 1 << GLK0.no; SolCode = 2; SolFound = true; break;

                case 22:
                    if (GLK0.no == GLKnxt.no)
                    {
                        P.CancelB = 1 << GLK0.no; SolFound = true; SolCode = 2;
                    }
                    break;
                }
            }

            if (SolFound)
            {
                return(SolType);
            }
            return(-1);
        }
        public IEnumerable <GroupedLink> IEGet_SuperLink(GroupedLink GLKpre)
        {
            int  SWCtrl = GLKpre.type;
            bool ALSpre = GLKpre is ALSLink;

            if (GLKpre.UGCellsB.Count == 1)
            {
                UCell            U    = GLKpre.UGCellsB[0];
                List <UCellLink> Plst = CeLKMan.CeLK81[U.rc];
                if (Plst != null)
                {
                    foreach (var LK in Plst)
                    {
                        if (ALSpre && LK.type != W)
                        {
                            continue;
                        }
                        GroupedLink GLK = new GroupedLink(LK);
                        if (Check_SuperLinkSequence(GLKpre, GLK))
                        {
                            yield return(GLK);
                        }
                    }
                }
            }

            if (GNPXApp000.GMthdOption["GroupedCells"] == "1")
            {
                foreach (var GP in GLKMan.GrpCeLKLst)
                {
                    if (ALSpre && GP.type != W)
                    {
                        continue;
                    }
                    if (!GLKpre.UGCellsB.EqualsRC(GP.UGCellsA))
                    {
                        continue;
                    }
                    if (GLKpre.no2 != GP.no)
                    {
                        continue;
                    }
                    if (Check_SuperLinkSequence(GLKpre, GP))
                    {
                        yield return(GP);
                    }
                }
            }

            if (GNPXApp000.GMthdOption["ALS"] == "1" && ALSMan.AlsInnerLink != null)
            {
                if (GLKpre.type == W)
                {
                    foreach (var GP in ALSMan.AlsInnerLink.Where(p => (p.ALSbase.Level == 1)))
                    {
                        if (GLKpre.no2 != GP.no)
                        {
                            continue;
                        }
                        if (GLKpre.UGCellsB.Equals(GP.UGCellsA))
                        {
                            yield return(GP);
                        }
                    }
                }
            }

            if (ALSpre)
            {
                ALSLink ALK   = GLKpre as ALSLink;
                int     noB   = 1 << ALK.no2;
                Bit81   BPnoB = new Bit81(pBDL, noB);

                Bit81 BP = BPnoB & ALK.UGCellsB.B81;
                //      ALK.UGCellsB.ForEach(P=>{ if((P.FreeB&noB)>0) BP.BPSet(P.rc); });

                Bit81 UsedCs = GLKpre.UsedCs;
                for (int tfx = 0; tfx < 27; tfx++)
                {
                    Bit81 HS = BPnoB & pHouseCells[tfx];
                    if (!(BP - HS).IsZero())
                    {
                        continue;
                    }
                    if ((HS - BP).IsZero())
                    {
                        continue;
                    }

                    Bit81 NxtBP = HS - BP - UsedCs;
                    if (NxtBP.IsZero())
                    {
                        continue;
                    }

//C                        WriteLine("\n tfx:"+tfx );
//C                        WriteLine( "   BP:"+BP );
//C                        WriteLine( "   HS:"+HS );
//C                        WriteLine( "HS-BP:"+(HS-BP) );
//C                        WriteLine( "NxtBP:"+NxtBP );

                    List <UCell> NxtCs = NxtBP.ToList().ConvertAll(rc => pBDL[rc]);
                    for (int k = 1; k < (1 << NxtCs.Count); k++)
                    {
                        UGrCells NxtGrpdCs = new UGrCells(tfx, ALK.no2);
                        int      kb        = k;
                        for (int n = 0; n < NxtCs.Count; n++)
                        {
                            if ((kb & 1) > 0)
                            {
                                NxtGrpdCs.Add(new UGrCells(NxtCs[n], ALK.no2));
                            }
                            kb >>= 1;
                        }
                        GroupedLink GP = new GroupedLink(GLKpre.UGCellsB, NxtGrpdCs, tfx, W);
//C                        WriteLine( GP );
                        yield return(GP);
                    }
                }
            }
            yield break;
        }
        //##### There is a bug #####
        public USuperLink Eval_SuperLinkChain(int rc0, int no0, bool Gbreak, int typeSel, bool DevelopB)
        {
            try{
                int dbX = 0;

                USuperLink USLK        = new USuperLink(rc0, no0);
                var        Qtrue       = USLK.Qtrue;
                var        Qfalse      = USLK.Qfalse;
                var        chainDesLKT = USLK.chainDesLKT;
                var        chainDesLKF = USLK.chainDesLKF;
                var        rcQue       = new Queue <GroupedLink>();

                UCell P0   = pBDL[rc0];                 //Origin Cell
                int   no0B = 1 << no0;                  //Origin Digit
                Qtrue[no0].BPSet(rc0);
                GroupedLink GLKnoR0 = new GroupedLink(P0, no0, no0, W, rootF: true);
                GLKnoR0.preGrpedLink  = null;
                chainDesLKT[rc0, no0] = GLKnoR0;

                if ((typeSel & 2) > 0)//====================== Start with WeakLink(origin:rc#no0) ======================
                {
                    foreach (var GLKH in IEGet_SuperLinkFirst(P0, no0).Where(X => X.type == W))
                    {
                        if (DevelopB)
                        {
                            WriteLine("*1st:" + GLKH.GrLKToString());
                        }
                        GLKH.UsedCs      |= GLKH.UGCellsB.B81;                                          //set usedcells(accumulate)
                        GLKH.preGrpedLink = GLKnoR0;                                                    //set pre-GLink
                        rcQue.Enqueue(GLKH);                                                            //enqueue next-GLink to RadiationSearchQueue

                        foreach (var P in GLKH.UGCellsB.Where(p => (p.FreeB & no0B) > 0))
                        {
                            int no2 = GLKH.no2;
                            Qfalse[no2].BPSet(P.rc);                                                            //set p.rc#no2 to false
                            chainDesLKF[P.rc, no2] = GLKH;                                                      //record in retroactive chain
                            if (Gbreak && Qtrue[no2].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], no2))
                            {
                                goto FTBreak;                                                                   //found error
                            }
                            if (P.FreeBC == 2)                                                                  //If the next is a binary cell
                            {
                                int nox = P.FreeB.DifSet(1 << no2).BitToNum();                                  //nox:another digit in the cell
                                Qtrue[nox].BPSet(P.rc);                                                         //P.rc#nox is true
                                GroupedLink GLKbv = new GroupedLink(P, no2, nox, S);                            //GLKbv:GLink in cell
                                GLKbv.preGrpedLink     = GLKH;                                                  //set preLink
                                chainDesLKT[P.rc, nox] = GLKbv;                                                 //record in retroactive chain
                                if (DevelopB)
                                {
                                    WriteLine($"        12 W *Rad->{P}  --#{no2} is false.");
                                }
                                if (Gbreak && Qfalse[nox].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], nox))
                                {
                                    goto FTBreak;                                                                                                         //found error
                                }
                            }
                        }
                    }

                    //S start cell, non-conscious digits
                    foreach (var nox in P0.FreeB.IEGet_BtoNo().Where(n => (n != no0)))              //non-conscious digits in originCell
                    {
                        Qfalse[nox].BPSet(rc0);                                                     // is false
                    }
                }

                if ((typeSel & 1) > 0)//====================== Start with StrongLink(origin:rc#no0) ======================
                {
                    foreach (var GLKH in IEGet_SuperLinkFirst(P0, no0).Where(X => X.type == S))
                    {
                        int         nox     = GLKH.no2;
                        GroupedLink GLKnoR1 = new GroupedLink(P0, no0, nox, W, rootF: false);           //nextGLink
                        GLKnoR1.preGrpedLink  = GLKnoR0;                                                //set pre-GLink to next-GLink
                        chainDesLKF[rc0, nox] = GLKnoR1;                                                //record in retroactive chain

                        GLKH.UsedCs      |= GLKH.UGCellsB.B81;                                          //set usedcells(accumulate)
                        GLKH.preGrpedLink = GLKnoR1;                                                    //set pre-GLink
                        rcQue.Enqueue(GLKH);                                                            //enqueue next-GLink to RadialSearchQueue
                        if (GLKH.UGCellsB.Count == 1)                                                   //if the link's next element is a single cell
                        {
                            int no2 = GLKH.no2;                                                         //no2:next digit
                            var P   = GLKH.UGCellsB[0];                                                 //P:next cell
                            Qtrue[no2].BPSet(P.rc);                                                     //set P.rc#no2 is true
                            chainDesLKT[P.rc, no2] = GLKH;                                              //record in retroactive chain
                            if (Gbreak && Qfalse[no2].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], no2))
                            {
                                goto FTBreak;                                                                 //found error
                            }
                            Qtrue[nox].BPSet(P.rc);                                                           //set P.rc#no is true

                            GroupedLink GLKno = new GroupedLink(P, nox, no2, W);                              //GLKno:GLink in cell
                            GLKno.preGrpedLink     = GLKH;                                                    //set preLink
                            chainDesLKF[P.rc, no2] = GLKno;                                                   //record in retroactive chain
                            if (Gbreak && Qtrue[nox].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], nox))
                            {
                                goto FTBreak;                                                                                                //found error
                            }
                        }
                    }
                }

                //====================== Radiation Search ===============================
                while (rcQue.Count > 0)
                {
                    GroupedLink R = rcQue.Dequeue();                                                                //dequeue next element
                    if (DevelopB)
                    {
                        WriteLine($"{dbX++}---Queue:" + R.GrLKToString());
                    }

                    foreach (var GLKH in IEGet_SuperLink(R))                                    //foreach next GLink
                    {
                        if (DevelopB)
                        {
                            WriteLine($"   {dbX++}--GLKH:" + GLKH.GrLKToString());
                        }
                        if (R.type != GLKH.type && R.UGCellsA.Equals(GLKH.UGCellsB))
                        {
                            continue;                                                                               //Skip back links
                        }
                        GLKH.preGrpedLink = R;                                                                      //set preLink
                        int no2 = GLKH.no2;                                                                         //no2:next digit
                        if (GLKH.type == S)                                                                         //Check connection conditions. case StrongLink
                        {
                            if (!(GLKH.UGCellsB.B81 & Qtrue[GLKH.no2]).IsZero())
                            {
                                continue;                                                                               //if the next element is setted true, go to the next process
                            }
                            if (GLKH.UGCellsB.Count == 1)                                                               //if the link's next element is a single cell
                            {
                                var P = GLKH.UGCellsB[0];                                                               //P:next cell
                                Qtrue[no2].BPSet(P.rc);                                                                 //set P.rc#no2 is true
                                chainDesLKT[P.rc, no2] = GLKH;                                                          //record in retroactive chain
                                if (Gbreak && Qfalse[no2].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], no2))
                                {
                                    goto FTBreak;                                                                                                         //found error
                                }
                                foreach (var nox in P.FreeB.IEGet_BtoNo().Where(q => (q != no2)))
                                {
                                    Qfalse[nox].BPSet(P.rc);                                                                      //set p.rc#no2 to false
                                    GroupedLink GLKno = new GroupedLink(P, no2, nox, W);                                          //GLKbv:GLink in cell(P#no2 WeakLink)
                                    GLKno.preGrpedLink     = GLKH;                                                                //set preLink
                                    chainDesLKF[P.rc, nox] = GLKno;                                                               //record in retroactive chain

                                    if (Gbreak && Qtrue[nox].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], nox))
                                    {
                                        goto FTBreak;                                                                                                            //found error
                                    }
                                    if (DevelopB)
                                    {
                                        WriteLine($"        31S ->P:{P}  --#{nox} is false.");
                                    }
                                }
                            }
                        }
                        if (GLKH.type == W)                                                                         //Check connection conditions. case WeakLink
                        {
                            if (!(GLKH.UGCellsB.B81 & Qfalse[GLKH.no2]).IsZero())
                            {
                                continue;                                                                               //if the next element is setted false, go to the next process
                            }
                            foreach (var P in GLKH.UGCellsB)                                                            //foreach next GLink
                            {
                                Qfalse[no2].BPSet(P.rc);                                                                //set P.rc#no2 is true
                                chainDesLKF[P.rc, no2] = GLKH;                                                          //record in retroactive chain
                                if (Gbreak && Qtrue[no2].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], no2))
                                {
                                    goto FTBreak;                                                                                                        //found error
                                }
                                if (DevelopB)
                                {
                                    WriteLine($"        40S ->P:{P}  ++#{no2} is false.");
                                }
                            }

                            if (GLKH.UGCellsB.Count == 1)                                                               //if the link's next element is a single cell
                            {
                                var P = GLKH.UGCellsB[0];
                                if (P.FreeBC == 2)                                                                            //If the next is a binary cell
                                {
                                    int nox = P.FreeB.DifSet(1 << no2).BitToNum();
                                    Qtrue[nox].BPSet(P.rc);                                                                                   //set P.rc#no2 is true
                                    if (DevelopB)
                                    {
                                        WriteLine($"        41S ->P:{P}  ++#{nox} is true.");
                                    }
                                    GroupedLink GLKno = new GroupedLink(P, no2, nox, S);                                          //GLKbv:GLink in cell(P#no2 StrongLink)
                                    GLKno.preGrpedLink     = GLKH;                                                                //set preLink
                                    chainDesLKT[P.rc, nox] = GLKno;                                                               //record in retroactive chain
                                    if (Gbreak && Qfalse[nox].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], nox))
                                    {
                                        goto FTBreak;                                                                                                             //found error
                                    }
                                }
                            }
                        }
                        rcQue.Enqueue(GLKH);                                                                        //enqueue next-GLink to RadiationSearchQueue
                    }
                }

                USLK.SolFound = true;                                                                       //Solution found
                return(USLK);

FTBreak:        //Failed
                USLK.SolFound = false;
                return(USLK);
            }
            catch (Exception ex) {
                WriteLine($"{ex.Message}+\r{ex.StackTrace}");
            }
            return(null);
        }
        private void _GroupedNL_SolResult(GroupedLink LK0, GroupedLink LKnxt, Stack <GroupedLink> SolStack, int SolType)
        {
            string st = "";

            List <GroupedLink> SolLst = SolStack.ToList();

            SolLst.Reverse();
            SolLst.Add(LK0);

            foreach (var LK in SolLst)
            {
                bool bALK = LK is ALSLink;
                int  type = (LK is ALSLink)? S: LK.type;//ALSLink, in ALS, is S
                foreach (var P1 in LK.UGCellsA.Select(p => pBDL[p.rc]))
                {
                    int noB = (1 << LK.no);
                    if (!bALK)
                    {
                        P1.SetCellBgColor(SolBkCr);
                    }
                    if (type == S)
                    {
                        P1.SetNoBColor(noB, AttCr);
                    }
                    else
                    {
                        P1.SetNoBColor(noB, AttCr3);
                    }
                }

                if (type == W)
                {
                    foreach (var P2 in LK.UGCellsB.Select(p => pBDL[p.rc]))
                    {
                        int noB2 = (1 << LK.no);
                        if (!bALK)
                        {
                            P2.SetCellBgColor(SolBkCr);
                        }
                        P2.SetNoBColor(noB2, AttCr);
                    }
                }
            }

            int cx = 2;

            foreach (var LK in SolLst)
            {
                ALSLink ALK = LK as ALSLink;
                if (ALK == null)
                {
                    continue;
                }
                Color crG = _ColorsLst[cx++];
                foreach (var P in ALK.ALSbase.B81.IEGet_rc().Select(rc => pBDL[rc]))
                {
                    P.SetCellBgColor(crG);
                }
            }

            string st3 = "";

            if (SolType == 1)
            {
                st = "Nice Loop(Cont.)";             //<>continuous
            }
            else                                     //<>discontinuous
            {
                int rc = LK0.UGCellsA[0].rc;
                var P  = pBDL[rc];
                st = "Nice Loop(Discont.) r" + (rc / 9 + 1) + "c" + (rc % 9 + 1);
                int dcTyp = LK0.type * 10 + LKnxt.type;
                switch (dcTyp)
                {
                case 11: st += $" is {(LK0.no+1)}";       P.SetCellBgColor(SolBkCr2); break;

                case 12: st += $" is not {(LKnxt.no+1)}"; P.CancelB = 1 << LKnxt.no; break;

                case 21: st += $" is not {(LK0.no+1)}";   P.CancelB = 1 << LK0.no; break;

                case 22: st += $" is not {(LK0.no+1)}";   P.CancelB = 1 << LK0.no; break;
                }
            }

            string st2 = _ToGroupedRCSequenceString(SolStack, ref st3);

            st         = st3 + st;
            Result     = st;
            ResultLong = st + "\r" + st2;
        }
        //Search for groupedLink_sequence starting from rc0#no0 as true.
        public USuperLink Eval_SuperLinkChainEx(int rc0, int no0, bool DevelopB)
        {
            try{
                int dbX = 0;
                _dbCC = 0;

                USuperLink GNL_Result  = new USuperLink(rc0, no0);
                var        Qtrue       = GNL_Result.Qtrue;
                var        Qfalse      = GNL_Result.Qfalse;
                var        chainDesLKT = GNL_Result.chainDesLKT;
                var        chainDesLKF = GNL_Result.chainDesLKF;

                var rcQue = new Queue <GroupedLink>();

                UCell P0   = pBDL[rc0];                 //Origin Cell
                int   no0B = 1 << no0;                  //Origin Digit
                Qtrue[no0].BPSet(rc0);

                //P is Cell.  R,RR,RRR is GroupedLink
                {//====================== Start with WeakLink(origin:rc#no0) ======================
                    foreach (var R in IEGet_SuperLinkFirst(P0, no0).Where(X => X.type == W))
                    {
                        if (DevelopB)
                        {
                            Write("*1st:" + R.GrLKToString()); __Debug_ChainPrint(R);
                        }

                        R.UsedCs       = R.UGCellsA.B81;            //set usedcells(accumulate)
                        R.preGrpedLink = null;                      //GLKnoR0;                              //set pre-GLink
                        rcQue.Enqueue(R);                           //enqueue next-GLink to RadiationSearchQueue

                        foreach (var P in R.UGCellsB.Where(p => (p.FreeB & no0B) > 0))
                        {
                            int no2 = R.no2;
                            Qfalse[no2].BPSet(P.rc);                              //set p.rc#no2 to false
                            chainDesLKF[P.rc, no2] = R;                           //��                              //record in retroactive chain
                            if (DevelopB)
                            {
                                WriteLine($"        12 W *Rad->{P}  --#{no2} is false.");
                            }
                        }
                    }
                    foreach (var nox in pBDL[rc0].FreeB.IEGet_BtoNo().Where(p => p != no0))
                    {
                        Qfalse[nox].BPSet(rc0);
                    }
                }

                //====================== Radiation Search ===============================
                while (rcQue.Count > 0)
                {
                    {   //----- Distinct -----
                        var Q2 = rcQue.ToList().Distinct();
                        rcQue.Clear();
                        foreach (var X in Q2)
                        {
                            rcQue.Enqueue(X);
                        }
                        //if(DevelopB){ WriteLine(); foreach(var P in rcQue) WriteLine($"--rcQue---{P.GrLKToString()}"); WriteLine(); }
                    }

                    GroupedLink R = rcQue.Dequeue();                                                         //dequeue next element
                    if (DevelopB)
                    {
                        WriteLine($"\r{dbX++}---Queue:" + R.GrLKToString());
                    }

                    foreach (var RR in IEGet_SuperLink(R).Where(p => p.AvailableF)) //foreach next GLink
                    {
                        RR.preGrpedLink = R;                                        //set preLink
                        if (!(R.UsedCs & RR.UGCellsB.B81).IsZero())
                        {
                            continue;                                                    //Skip by used Cells
                        }
                        if (DevelopB)
                        {
                            WriteLine($"\r   {dbX++}--RR:" + RR.GrLKToString());
                        }

                        RR.UsedCs = R.UsedCs | RR.UGCellsA.B81;
                        if (DevelopB)
                        {
                            __Debug_ChainPrint(RR); WriteLine($"��   {dbX++}-{++chkX}--RR:" + RR.GrLKToString());
                        }

                        int no2 = RR.no2;                               //no2:next digit
                        if (RR.type == S)                               // F->T   *=*=* Check connection conditions. case StrongLink *=*=*
                        {
                            if (RR.UGCellsB.Count == 1)                 //if the link's next element is a single cell
                            {
                                var P = RR.UGCellsB[0];                 //P:next cell
                                if (Qtrue[no2].IsHit(P.rc))
                                {
                                    continue;                                            //Already setted. Eliminate unnecessary trials and speed up.
                                }
                                Qtrue[no2].BPSet(P.rc);                                  //set P.rc#no2 is true
                                chainDesLKT[P.rc, no2] = RR;                             //record in retroactive chain
                                if (DevelopB)
                                {
                                    WriteLine($"        31S ->P:{P}  ++#{no2} is true.");
                                }

                                foreach (var nox in P.FreeB.IEGet_BtoNo().Where(q => (q != no2)))
                                {
                                    Qfalse[nox].BPSet(P.rc);                                                                 //set p.rc#nox to false
                                    if (DevelopB)
                                    {
                                        WriteLine($"        32S ->P:{P}  --#{nox} is false.");
                                    }
                                }
                            }
                        }

                        else if (RR.type == W)                          // T->F   *=*=* Check connection conditions. case WeakLink *=*=*
                        {
                            foreach (var P in RR.UGCellsB)              //foreach next GLink
                            {
                                Qfalse[no2].BPSet(P.rc);                //set P.rc#no2 is false
                                if (DevelopB)
                                {
                                    WriteLine($"        40W ->P:{P}  ++#{no2} is false.");
                                }
                                chainDesLKF[P.rc, no2] = RR;                                                             //record in retroactive chain
                            }

                            if (RR.UGCellsB.Count == 1)                                                              //if the link's next element is a single cell
                            {
                                var P = RR.UGCellsB[0];
                                if (P.FreeBC == 2)                                                                       //If the next is a binary cell
                                {
                                    int nox = P.FreeB.DifSet(1 << no2).BitToNum();
                                    if (Qtrue[nox].IsHit(P.rc))
                                    {
                                        continue;                                        //Already setted. Eliminate unnecessary trials and speed up.
                                    }
                                    Qtrue[nox].BPSet(P.rc);                              //set P.rc#no2 is true
                                    if (DevelopB)
                                    {
                                        WriteLine($"        41W ->P:{P}  ++#{nox} is true.");
                                    }

                                    GroupedLink RRR = new GroupedLink(P, no2, nox, S);                                       //GLKbv:GLink in cell(P#no2 StrongLink)
                                    RRR.preGrpedLink       = RR;                                                             //set preLink
                                    chainDesLKT[P.rc, nox] = RRR;                                                            //record in retroactive chain
                                }
                            }
                        }
                        rcQue.Enqueue(RR);                                                                       //enqueue next-GLink to RadiationSearchQueue                                              //enqueue next-GLink to RadiationSearchQueue
                    }
                }

                GNL_Result.SolFound = true;                                                              //Solution found
                return(GNL_Result);
            }
            catch (Exception ex) {
                WriteLine($"{ex.Message}+\r{ex.StackTrace}");
            }
            return(null);
        }
        private bool GNL_RecursiveSearch(GroupedLink GLK0, GroupedLink GLKpre, Stack <GroupedLink> SolStack, int szCtrl)
        {
            if (szCtrl < 0)
            {
                return(false);
            }

            Bit81 UsedCs = GLKpre.UsedCs;

            foreach (var GLKnxt in pSprLKsMan.IEGet_SuperLink(GLKpre))    //links that satisfy concatenation conditions
            {
                UGrCells GCsNxt = GLKnxt.UGCellsB;
                int      no     = GLKnxt.no;

                {                          //===== Chain Search =====
                    SolStack.Push(GLKnxt); //( link extension --> Push )
                    ___Debug_Print_GNLChain(SolStack);

                    //Loop was formed (the next cell matches the Origin Cell)
                    if (_GroupedNL_LoopCheck(GLK0, GLKnxt))
                    {
                        if (szCtrl == 0 && SolStack.Count > 3)
                        {
                            int SolType = _GroupedNL_CheckSolution(GLK0, GLKnxt, SolStack, UsedCs);
                            if (SolType > 0)
                            {
                                if (___GNLCC == 2898)
                                {
                                    WriteLine("-----------------");
                                }
                                ___Debug_Print_GNLChain(SolStack, "<+><+>");

                                if (SolInfoB)
                                {
                                    _GroupedNL_SolResult(GLK0, GLKnxt, SolStack, SolType);
                                }

                                __SolGL = SolCode;

                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(false))
                                {
                                    return(false);
                                }
                                Thread.Sleep(10);
                                if ((++SolLimBrk) > (int)SDK_Ctrl.MltAnsOption["OneMethod"])
                                {
                                    SolLimBrk = int.MaxValue;
                                    return(false);
                                }
                            }
                        }
                    }
                    else if (!CheckUsed((UsedCs | GLK0.UsedCs), GLKnxt))
                    {
                        Bit81 UsedCsNxt = new Bit81(UsedCs);   //Create a new bit representation of used cell
                        SetUsed(ref UsedCsNxt, GLKnxt);

                        GLKnxt.UsedCs = UsedCsNxt;
                        GNL_RecursiveSearch(GLK0, GLKnxt, SolStack, szCtrl - 1); //Next step Search(recursive call
                        if (SolLimBrk == int.MaxValue)
                        {
                            return(false);
                        }
                        if (SolCode > 0)
                        {
                            return(true);
                        }
                    }
                    SolStack.Pop();     // Failure(Cancel link extension processing --> Pop )
                } //-----------------------------
            }
            return(false);
        }