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);
        }
Ejemplo n.º 2
0
 public UGrCells(int tfx, int no)
 {
     this.tfx = tfx; this.no = no;
     B81      = new Bit81();
 }
 private void SetUsed(ref Bit81 UsedCs, GroupedLink GLKnxt)
 {
     UsedCs |= GLKnxt.UGCellsB.B81;
 }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
 public UGrCells(UCell X, int no)
 {
     this.tfx = -9; this.no = no;
     B81      = new Bit81();
     this.Add(X);
 }
Ejemplo n.º 6
0
        private bool _XYZwingALSSub(int wsz)    //simple UVWXYZwing
        {
            List <UCell> FBCX = pBDL.FindAll(p => p.FreeBC == wsz);

            if (FBCX.Count == 0)
            {
                return(false);
            }

            foreach (var P0 in FBCX)    //Forcused Cell
            {
                int b0 = P0.b;          //Forcused Block

                for (int no = 0; no < 9; no++)
                {
                    int noB = 1 << no;

                    Bit81 P0con = (new Bit81(pBDL, noB)) & ConnectedCells[P0.rc];
                    Bit81 Pin   = P0con & HouseCells[18 + b0];

                    for (int dir = 0; dir < 2; dir++)                                //dir 0:row 1:col
                    {
                        int   rcDir = (dir == 0)? P0.r: (9 + P0.c);
                        Bit81 Pin2  = Pin - HouseCells[rcDir];                   //ALS candidate position in the block
                        if (Pin2.IsZero())
                        {
                            continue;
                        }

                        Bit81 Pout = (P0con & HouseCells[rcDir]) - HouseCells[18 + P0.b];    //ALS candidate position outside the block
                        foreach (var ALSout in ALSMan.IEGetCellInHouse(1, noB, Pout, rcDir)) //ALS out of Forcused Block
                        {
                            int   FreeBOut2 = ALSout.FreeB.DifSet(noB);
                            Bit81 EOut      = new Bit81();                      //#no existence position(outer-ALS)
                            foreach (var P in ALSout.UCellLst.Where(p => (p.FreeB & noB) > 0))
                            {
                                EOut.BPSet(P.rc);
                            }

                            foreach (var ALSin in ALSMan.IEGetCellInHouse(1, noB, Pin2, 18 + b0))
                            {
                                int FreeBin2 = ALSin.FreeB.DifSet(noB);

                                Bit81 Ein = new Bit81();                          //#no existence position(inner-ALS)
                                foreach (var P in ALSin.UCellLst.Where(p => (p.FreeB & noB) > 0))
                                {
                                    Ein.BPSet(P.rc);
                                }

                                int Cover = P0.FreeB.DifSet(ALSout.FreeB | ALSin.FreeB);
                                if (Cover != 0)
                                {
                                    continue;                                   //Numbers in inner-ALS and outer-ALS cover numbers in the Forcused cell
                                }
                                Bit81 Epat = EOut | Ein;                        //Cells covered by excluded Cells&Digit
                                if (Epat.IsZero())
                                {
                                    continue;
                                }
                                bool   SolFound = false;
                                string msg3     = "";

                                int FreeBin3 = P0.FreeB.DifSet(FreeBOut2 | FreeBin2);
                                foreach (var E in pBDL.Where(p => (p.FreeB & noB) > 0))
                                {
                                    if (E.rc == P0.rc || Pout.IsHit(E.rc) || Pin2.IsHit(E.rc))
                                    {
                                        continue;
                                    }
                                    if (!(Epat - ConnectedCells[E.rc]).IsZero())
                                    {
                                        continue;
                                    }
                                    if (FreeBin3 > 0 && !ConnectedCells[E.rc].IsHit(P0.rc))
                                    {
                                        continue;
                                    }
                                    E.CancelB = noB; SolFound = true;
                                    msg3     += " " + E.rc.ToRCString();
                                }

                                if (SolFound)
                                {
                                    SolCode = 2;
                                    string[] xyzWingName = { "XYZ-Wing", "WXYZ-Wing", "VWXYZ-Wing", "UVWXYZ-Wing" };
                                    string   SolMsg      = xyzWingName[wsz - 3] + "(ALS)";

                                    if (SolInfoB)
                                    {
                                        P0.SetNoBBgColor(P0.FreeB, AttCr, SolBkCr2);
                                        foreach (var P in ALSin.UCellLst)
                                        {
                                            P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr);
                                        }
                                        foreach (var P in ALSout.UCellLst)
                                        {
                                            P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr);
                                        }

                                        string msg0 = " Pivot: " + P0.rc.ToRCString();
                                        string st   = ""; foreach (var P in ALSin.UCellLst)
                                        {
                                            st += " " + P.rc.ToRCString();
                                        }
                                        string msg1 = " in: " + st.ToString_SameHouseComp();
                                        st = "";  foreach (var P in ALSout.UCellLst)
                                        {
                                            st += " " + P.rc.ToRCString();
                                        }
                                        string msg2 = " out: " + st.ToString_SameHouseComp();
                                        st = ""; foreach (var rc in Pin2.IEGet_rc())
                                        {
                                            st += " " + rc.ToRCString();
                                        }

                                        Result     = SolMsg + msg0 + msg1 + msg2;
                                        ResultLong = SolMsg + "\r" + msg0 + "\r   " + msg1 + "\r  " + msg2 + "\r Eliminated: " + msg3.ToString_SameHouseComp();
                                    }

                                    if (__SimpleAnalizerB__)
                                    {
                                        return(true);
                                    }
                                    if (!pAnMan.SnapSaveGP(true))
                                    {
                                        return(true);
                                    }
                                    foreach (var E in pBDL.Where(p => (p.FreeB & noB) > 0))
                                    {
                                        E.CancelB = 0;
                                    }
                                    SolFound = false;
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 7
0
 public UALSPair(UALS ALSpre, UALS ALSnxt, int RCC, int nRCC, Bit81 rcB = null)
 {
     this.ALSpre = ALSpre; this.ALSnxt = ALSnxt; this.RCC = RCC; this.nRCC = nRCC;
     this.rcUsed = rcB ?? (ALSpre.B81 | ALSnxt.B81);
 }
        }                                        //UVWXYZ-wing

        private bool _UVWXYZwing(int wsz)        //simple UVWXYZwing
        {
            if (pAnMan.GStage != GStageMemo)
            {
                GStageMemo = pAnMan.GStage;
                FBCX       = pBDL.FindAll(p => p.FreeBC == wsz);
            }
            if (FBCX.Count == 0)
            {
                return(false);
            }

            bool wingF = false;

            foreach (var P0 in FBCX)                       //focused Cell
            {
                int b0 = P0.b;                             //focused Block
                foreach (int no in P0.FreeB.IEGet_BtoNo()) //focused Digit
                {
                    int   noB   = 1 << no;
                    Bit81 P0con = (new Bit81(pBDL, noB, FreeBC: 2)) & ConnectedCells[P0.rc];
                    Bit81 Pin   = P0con & HouseCells[18 + P0.b];

                    Bit81 Pout = null, Pin2 = null;
                    for (int dir = 0; dir < 2; dir++) //dir 0:row 1:col
                    {
                        int rcDir = (dir == 0)? P0.r: (9 + P0.c);
                        Pin2 = Pin - HouseCells[rcDir];
                        if (Pin2.IsZero())
                        {
                            continue;
                        }
                        Pout = (P0con & HouseCells[rcDir]) - HouseCells[18 + P0.b];
                        if (Pin2.Count + Pout.Count != (wsz - 1))
                        {
                            continue;
                        }

                        int FreeBin  = Pin2.AggregateFreeB(pBDL);
                        int FreeBout = Pout.AggregateFreeB(pBDL);
                        if ((FreeBin | FreeBout) != P0.FreeB)
                        {
                            continue;
                        }
                        Bit81 ELst = HouseCells[rcDir] & HouseCells[18 + P0.b];
                        ELst.BPReset(P0.rc);
                        string msg3 = "";
                        foreach (var E in ELst.IEGet_rc().Select(p => pBDL[p]))
                        {
                            if ((E.FreeB & noB) > 0)
                            {
                                E.CancelB = noB; wingF = true;
                                msg3     += " " + E.rc.ToRCString();
                            }
                        }
                        if (!wingF)
                        {
                            continue;
                        }

                        //--- ...wing found -------------
                        SolCode = 2;
                        string[] xyzWingName = { "XYZ-Wing", "WXYZ-Wing", "VWXYZ-Wing", "UVWXYZ-Wing" };
                        string   SolMsg      = xyzWingName[wsz - 3];

                        if (SolInfoB)
                        {
                            P0.SetNoBBgColor(P0.FreeB, AttCr, SolBkCr2);
                            foreach (var P in Pin2.IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr);
                            }
                            foreach (var P in Pout.IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr);
                            }

                            string msg0 = " Pivot: " + P0.rc.ToRCString();
                            string st   = ""; foreach (var rc in Pin2.IEGet_rc())
                            {
                                st += " " + rc.ToRCString();
                            }
                            string msg1 = " in: " + st.ToString_SameHouseComp();
                            st = "";  foreach (var rc in Pout.IEGet_rc())
                            {
                                st += " " + rc.ToRCString();
                            }
                            string msg2 = " out: " + st.ToString_SameHouseComp();
                            st = ""; foreach (var rc in Pin2.IEGet_rc())
                            {
                                st += " " + rc.ToRCString();
                            }

                            ResultLong = SolMsg + "\r" + msg0 + "\r   " + msg1 + "\r  " + msg2 + "\r Eliminated: " + msg3.ToString_SameHouseComp();
                            Result     = SolMsg + msg0 + msg1 + msg2;
                        }
                        if (__SimpleAnalizerB__)
                        {
                            return(true);
                        }
                        if (!pAnMan.SnapSaveGP(true))
                        {
                            return(true);
                        }
                        wingF = false;
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 9
0
        private bool _ALS_DeathBlossomSubEx(int sz, bool stmLinked = false)
        {
            int szM = (stmLinked? sz - 1: sz);

            foreach (var SC in pBDL.Where(p => p.FreeBC == sz))                    //Stem Cell
            {
                if (pAnMan.CheckTimeOut())
                {
                    return(false);
                }
                List <LinkCellALS> LinkCeAlsLst = ALSMan.LinkCeAlsLst[SC.rc];
                if (LinkCeAlsLst == null || LinkCeAlsLst.Count < sz)
                {
                    continue;
                }

                int nxt = 0, PFreeB = SC.FreeB;
                var cmb = new Combination(LinkCeAlsLst.Count, szM);                //Select szM ALSs in Combination
                while (cmb.Successor(nxt))
                {
                    int FreeB = SC.FreeB, AFreeB = 0x1FF;
                    for (int k = 0; k < szM; k++)
                    {
                        nxt = k;
                        var LK = LinkCeAlsLst[cmb.Index[k]];                      //Link[cell-ALS]
                        if ((FreeB & (1 << LK.nRCC)) == 0)
                        {
                            goto LNxtCmb;
                        }
                        FreeB   = FreeB.BitReset(LK.nRCC);                      //nRCC:RCC of stemCell-ALS
                        AFreeB &= LK.ALS.FreeB;
                        if (AFreeB == 0)
                        {
                            goto LNxtCmb;
                        }
                    }

                    if (stmLinked)
                    {
                        if (FreeB.BitCount() != 1 || (FreeB & AFreeB) == 0)
                        {
                            continue;
                        }
                        int no  = FreeB.BitToNum();
                        int noB = FreeB;

                        Bit81 Ez = new Bit81();
                        for (int k = 0; k < szM; k++)
                        {
                            var ALS   = LinkCeAlsLst[cmb.Index[k]].ALS;
                            var UClst = ALS.UCellLst;
                            foreach (var P in UClst.Where(p => (p.FreeB & noB) > 0))
                            {
                                Ez.BPSet(P.rc);
                            }
                        }

                        foreach (var P in ConnectedCells[SC.rc].IEGet_rc().Select(rc => pBDL[rc]))
                        {
                            if ((P.FreeB & noB) == 0)
                            {
                                continue;
                            }
                            if ((Ez - ConnectedCells[P.rc]).IsZero())
                            {
                                P.CancelB = noB; SolCode = 2;
                            }
                        }
                        if (SolCode < 1)
                        {
                            continue;
                        }

                        var LKCAsol = new List <LinkCellALS>();
                        Array.ForEach(cmb.Index, nx => LKCAsol.Add(LinkCeAlsLst[nx]));
                        _DeathBlossom_SolResult(LKCAsol, SC, no, stmLinked);

                        if (__SimpleAnalizerB__)
                        {
                            return(true);
                        }
                        if (!pAnMan.SnapSaveGP(true))
                        {
                            return(true);
                        }
                    }
                    else if (FreeB == 0 && AFreeB > 0)
                    {
                        AFreeB = AFreeB.DifSet(SC.FreeB);
                        foreach (var no in AFreeB.IEGet_BtoNo())
                        {
                            int   noB = (1 << no);
                            Bit81 Ez  = new Bit81();
                            for (int k = 0; k < sz; k++)
                            {
                                var ALS   = LinkCeAlsLst[cmb.Index[k]].ALS;
                                var UClst = ALS.UCellLst;
                                foreach (var P in UClst.Where(p => (p.FreeB & noB) > 0))
                                {
                                    Ez.BPSet(P.rc);
                                }
                            }

                            foreach (var P in pBDL.Where(p => (p.FreeB & noB) > 0))
                            {
                                if ((Ez - ConnectedCells[P.rc]).IsZero())
                                {
                                    P.CancelB = noB; SolCode = 2;
                                }
                            }
                            if (SolCode < 1)
                            {
                                continue;
                            }

                            var LKCAsol = new List <LinkCellALS>();
                            Array.ForEach(cmb.Index, nx => LKCAsol.Add(LinkCeAlsLst[nx]));
                            _DeathBlossom_SolResult(LKCAsol, SC, no, stmLinked);

                            if (__SimpleAnalizerB__)
                            {
                                return(true);
                            }
                            if (!pAnMan.SnapSaveGP(true))
                            {
                                return(true);
                            }
                        }
                    }

LNxtCmb:
                    continue;
                }
            }
            return(false);
        }
        private int _NL_CheckSolution(UCellLink LK0, UCellLink LKnxt, Stack <UCellLink> SolStack, Bit81 UsedCells)
        {
            bool SolFound = false;
            int  SolType  = CeLKMan.Check_CellCellSequence(LKnxt, LK0)? 1: 2; //1:Continuous 2:DisContinuous

            if (SolType == 1)                                                 //===== continuous =====
            //=== Change WeakLink to StrongLink
            {
                List <UCellLink> SolLst     = SolStack.ToList();
                Bit81            UsedCellsT = UsedCells | (new Bit81(LK0.rc1));
                foreach (var L in SolLst)
                {
                    int noB = 1 << L.no;
                    foreach (var P in pBDL.IEGetCellInHouse(L.tfx, noB))
                    {
                        if (UsedCellsT.IsHit(P.rc))
                        {
                            continue;
                        }
                        P.CancelB |= noB;
                        SolFound   = true;
                    }
                }

                //=== S-S (There are no other numbers)
                SolLst.Reverse();
                SolLst.Add(LK0);
                var LKpre = SolLst[0];
                foreach (var LK in SolLst.Skip(1))
                {
                    if (LKpre.type == 1 && LK.type == 1) //S-S
                    {
                        UCell P   = pBDL[LK.rc1];
                        int   noB = P.FreeB.DifSet((1 << LKpre.no) | (1 << LK.no));
                        if (noB > 0)
                        {
                            P.CancelB = noB; SolFound = true;
                        }
                    }
                    LKpre = LK;
                }
                if (SolFound)
                {
                    SolCode = 2;
                }
            }
            else if (SolType == 2)               //===== discontinuous =====
            {
                UCell P     = pBDL[LK0.UCe1.rc]; //(for MultiAns code)
                int   dcTyp = LK0.type * 10 + LKnxt.type;
                switch (dcTyp)
                {
                case 11:
                    P.FixedNo = LK0.no + 1;         //Cell number determination
                    P.CancelB = P.FreeB.DifSet(1 << (LK0.no));
                    SolCode   = 1; SolFound = true; //(1:Fixed)
                    break;

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

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

                case 22:
                    if (LK0.no == LKnxt.no)
                    {
                        P.CancelB = 1 << LK0.no; SolFound = true; SolCode = 2;
                    }
                    break;
                }
            }
            if (SolFound)
            {
                return(SolType);
            }
            return(-1);
        }
        private bool _NL_Search(UCellLink LK0, UCellLink LKpre, Stack <UCellLink> SolStack, Bit81 UsedCells, int szCtrl)
        {
            if (szCtrl <= 0)
            {
                return(false);
            }

            foreach (var LKnxt in CeLKMan.IEGet_CeCeSeq(LKpre))     //links that satisfy concatenation conditions
            {
                int rc2Nxt = LKnxt.rc2;
                if (UsedCells.IsHit(rc2Nxt))
                {
                    continue; //UsedCells does not include Origin Cell
                }
                {             //===== Chain Search =====
                    SolStack.Push(LKnxt);
                    //___Debug_Print_NLChain(SolStack);
                    if (rc2Nxt == LK0.rc1 && szCtrl == 1)
                    {
                        if (SolStack.Count > 2)                                               //Loop was formed (the next cell matches the Origin Cell)
                        {
                            int SolType = _NL_CheckSolution(LK0, LKnxt, SolStack, UsedCells); //Solved?
                            if (SolType > 0)
                            {
                                if (SolInfoB)
                                {
                                    _NL_SolResult(LK0, LKnxt, SolStack, SolType);
                                }

                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(false))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                    else
                    {
                        Bit81 UsedCellsNxt = UsedCells | (new Bit81(rc2Nxt));       //Create a new bit expression of used cell
                        _NL_Search(LK0, LKnxt, SolStack, UsedCellsNxt, szCtrl - 1); //Next step Search(recursive call
                        if (SolCode > 0)
                        {
                            return(true);
                        }
                    }
                    SolStack.Pop();                                 //Failure(Cancel link extension processing)
                } //-----------------------------
            }
            return(false);
        }
        //XYwing is an algorithm that consists of two WeakLinks with common cells.
        //http://csdenpe.web.fc2.com/page42.html
        public bool XYwing( )
        {
            Prepare();
            CeLKMan.PrepareCellLink(2);                                         //Generate WeakLinks

            if (BVCellLst == null)
            {
                BVCellLst = pBDL.FindAll(p => (p.FreeBC == 2));                 //Generate BVs(BV:bivalue).
            }
            if (BVCellLst.Count < 3)
            {
                return(false);
            }

            bool XYwing = false;

            foreach (var P0 in BVCellLst)                                       //Choose one BV_Cell(=>PS)
            {
                List <UCellLink> BVLKLst = CeLKMan.IEGetRcNoBTypB(P0.rc, 0x1FF, 2).Where(R => R.BVFlag).ToList();
                //Extract WeakLinks starting from P0
                //foreach( var P in BVLKLst ) WriteLine(P);
                if (BVLKLst.Count < 2)
                {
                    continue;
                }

                var cmb = new Combination(BVLKLst.Count, 2);
                int nxt = 1;
                while (cmb.Successor(nxt))                                              //Combine two WLinks from BVLKLst
                {
                    UCellLink LKA = BVLKLst[cmb.Index[0]], LKB = BVLKLst[cmb.Index[1]]; //(
                    UCell     Q = LKA.UCe2, R = LKB.UCe2;
                    if (Q.rc == R.rc || LKA.no == LKB.no)
                    {
                        continue;                                               //Two WLinks have different end and different digits
                    }
                    Bit81 Q81 = ConnectedCells[LKA.rc2] & ConnectedCells[LKB.rc2];
                    if (Q81.Count <= 0)
                    {
                        continue;                                               //Two WLinks have cells connected indirectly
                    }
                    int noB = Q.FreeB.DifSet(1 << LKA.no) & R.FreeB.DifSet(1 << LKB.no);
                    if (noB == 0)
                    {
                        continue;                                               //Two WLinks have common digit(=>no).
                    }
                    int no = noB.BitToNum();

                    string msg2 = "";
                    foreach (var A in Q81.IEGetUCeNoB(pBDL, noB))
                    {
                        if (A == P0 || A == Q || A == R)
                        {
                            continue;
                        }
                        A.CancelB = noB; XYwing = true;                             //cell(A)/digit(no) can be excluded
                        if (SolInfoB)
                        {
                            msg2 += $" {A.rc.ToRCNCLString()}(#{no+1})";
                        }
                    }

                    if (XYwing)
                    {
                        SolCode = 2;
                        P0.SetNoBColor(P0.FreeB, AttCr); P0.SetCellBgColor(SolBkCr);
                        Q.SetCellBgColor(SolBkCr); R.SetCellBgColor(SolBkCr);

                        string msg0 = $" Pivot: {_XYwingResSub(P0)}";
                        string msg1 = $" Pin: {_XYwingResSub(R)} ,{_XYwingResSub(Q)}";
                        Result = "XY Wing" + msg0;
                        if (SolInfoB)
                        {
                            ResultLong = $"XY Wing\r     {msg0}\r       {msg1}\r Eliminated:{msg2}";
                        }

                        if (__SimpleAnalizerB__)
                        {
                            return(true);
                        }
                        if (!pAnMan.SnapSaveGP())
                        {
                            return(true);
                        }
                        XYwing = false;
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 13
0
        private bool _ALSXZ_DoublyLinked(UALS UA, UALS UB, int RCC)                 // *=*=* DoublyLinked subroutine *=*=*
        //----- RCC -----
        {
            Bit81 UEz  = new Bit81(); //Covered cells
            bool  solF = false;

            foreach (int no in RCC.IEGet_BtoNo())
            {
                int noB = 1 << no;
                UEz.Clear();
                foreach (var P in UA.UCellLst.Where(p => (p.FreeB & noB) > 0))
                {
                    UEz.BPSet(P.rc);
                }
                foreach (var P in UB.UCellLst.Where(p => (p.FreeB & noB) > 0))
                {
                    UEz.BPSet(P.rc);
                }

                Bit81 Elm = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81);    //Scan Cells
                foreach (var rc in Elm.IEGet_rc())
                {
                    if ((UEz - ConnectedCells[rc]).IsZero())
                    {
                        pBDL[rc].CancelB |= noB; solF = true;
                    }
                }
            }

            //----- ALS element digit other than RCC -----
            int nRCC = UA.FreeB.DifSet(RCC);

            foreach (int no in nRCC.IEGet_BtoNo())
            {
                int noB = 1 << no;
                UEz.Clear();
                foreach (var P in UA.UCellLst.Where(p => (p.FreeB & noB) > 0))
                {
                    UEz.BPSet(P.rc);
                }
                Bit81 Elm = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81);   //Scan Cells
                foreach (var rc in Elm.IEGet_rc())
                {
                    if ((UEz - ConnectedCells[rc]).IsZero())
                    {
                        pBDL[rc].CancelB |= noB; solF = true;
                    }
                }
            }
            nRCC = UB.FreeB.DifSet(RCC);
            foreach (int no in nRCC.IEGet_BtoNo())
            {
                int noB = 1 << no;
                UEz.Clear();
                foreach (var P in UB.UCellLst.Where(p => (p.FreeB & noB) > 0))
                {
                    UEz.BPSet(P.rc);
                }
                Bit81 Elm = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81);    //Scan Cells
                foreach (var rc in Elm.IEGet_rc())
                {
                    if ((UEz - ConnectedCells[rc]).IsZero())
                    {
                        pBDL[rc].CancelB |= noB; solF = true;
                    }
                }
            }
            return(solF);
        }
        public bool CannibalisticFMFish_sub(int sz, int no, int FMSize, bool FinnedF, bool EndoF = false, bool CannF = false)
        {
            int     noB = (1 << no);
            int     BaseSel = 0x7FFFFFF, CoverSel = 0x7FFFFFF;
            FishMan FMan = new FishMan(this, FMSize, no, sz, (sz >= 3));

            foreach (var Bas in FMan.IEGet_BaseSet(BaseSel, FinnedF:FinnedF, EndoFlg:EndoF))     //BaseSet
            {
                foreach (var Cov in FMan.IEGet_CoverSet(Bas, CoverSel, CannF))                   //CoverSet
                {
                    if (pAnMan.CheckTimeOut())
                    {
                        return(false);
                    }
                    Bit81 FinB81 = Bas.BaseB81 - Cov.CoverB81;

                    if (FinB81.Count == 0)
                    {
                        foreach (var P in Cov.CannFin.IEGetUCeNoB(pBDL, noB))
                        {
                            P.CancelB = noB; SolCode = 2;
                        }
                        if (SolCode > 0)
                        {
                            if (SolInfoB)
                            {
                                _Fish_FishResult(no, sz, Bas, Cov, (FMSize == 27)); //FMSize 27:Franken/Mutant
                            }
                            //WriteLine(ResultLong); //___Debug_CannFish("Cannibalistic");
                            if (__SimpleAnalizerB__)
                            {
                                return(true);
                            }
                            if (!pAnMan.SnapSaveGP(true))
                            {
                                return(true);
                            }
                        }
                    }
                    else
                    {
                        FinB81 |= Cov.CannFin;
                        Bit81 ELM = null;
                        Bit81 E   = (Cov.CoverB81 - Bas.BaseB81) | Cov.CannFin;
                        ELM = new Bit81();
                        foreach (var rc in E.IEGet_rc())
                        {
                            if ((FinB81 - ConnectedCells[rc]).Count == 0)
                            {
                                ELM.BPSet(rc);
                            }
                        }
                        if (ELM.Count > 0)
                        {
                            foreach (var P in ELM.IEGetUCeNoB(pBDL, noB))
                            {
                                P.CancelB = noB; SolCode = 2;
                            }
                            if (SolCode > 0)
                            {
                                if (SolInfoB)
                                {
                                    _Fish_FishResult(no, sz, Bas, Cov, (FMSize == 27));
                                }
                                //WriteLine(ResultLong); //___Debug_CannFish("Finned Cannibalistic");
                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(true))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }
        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 expression 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);
        }
Ejemplo n.º 16
0
        public IEnumerable <UBasCov> IEGet_BaseSet(int sz, int rnk)
        {
            if (UGLLst == null)
            {
                yield break;
            }

            BSstatus = new BaseSet_Status(sz, rnk);

            List <UGLink> basUGLs   = BSstatus.basUGLs;                                     //BaseSet List
            Bit981        HB981     = BSstatus.HB981;                                       //BaseSet bitPattern
            Bit324        usedLK    = BSstatus.usedLK;                                      //usedLink(by serial number)
            List <int>    usedLKLst = BSstatus.usedLKLst;

            long RCBN_frameA = 0;

            _jkc_ = 0;
            var cmbBas = new Combination(UGLLst.Count, sz);
            int nxt    = int.MaxValue; //(skip function)

            while (cmbBas.Successor(nxt))
            {
                GeneralLogicGen.ChkBas0++;   //*****

                _jkc_++;
                //  sz=1  *==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*
                if (sz == 1)
                {
                    UGLink UGL = UGLLst[cmbBas.Index[0]];
                    if (UGL.UC is UCell)
                    {
                        goto LNextSet;                                                      //only row/column/block link.
                    }
                    HB981.Clear(); HB981.BPSet(UGL.rcBit81.no, UGL.rcBit81, tfbSet: false); //accumulate rcbn info. in HB981.
                    basUGLs.Clear(); basUGLs.Add(UGL);                                      //set UGL in BaseSet

                    GeneralLogicGen.ChkBas1++;                                              //*****
                    goto LBSFound;                                                          //possibility of solution
                }
                //===================================================================================================================

                //  sz>=2  *==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*
                HB981.Clear();
                basUGLs.Clear();
                usedLKLst.Clear();
                BSstatus.Clear();

                RCBN_frameA = 0;
                int[] _RCB_frameB = new int[9];
                for (int k = 0; k < sz; k++)                                                   //(r:row c:column b:block n:digit => rcbn)
                {
                    nxt = k;
                    UGLink UGL = UGLLst[cmbBas.Index[k]];
                    RCBN_frameA |= UGL.RCBN_frameB;                                         //bit expression of rcbn

                    if (!Check_rcbnCondition(sz, rnk, k, RCBN_frameA))
                    {
                        goto LNextSet;                                   //### extremely efficient
                    }
                    if (UGL.rcBit81 is Bit81)                            // ........................ rcb link  ........................
                    {
                        int no = UGL.rcBit81.no;
                        if (k > 0 && HB981.IsHit(no, UGL.rcBit81))
                        {
                            goto LNextSet;                          //elements already included in HB981
                        }
                        HB981.BPSet(no, UGL.rcBit81, tfbSet: true); //accumulate rcbn info. in HB981.
                        usedLKLst.Add(UGL.rcBit81.ID);              //(ID=tfx<<4 | no)              //[rcb_link type]register ID to used list.
                        _RCB_frameB[no] |= (int)UGL.RCBN_frameB & 0x3FFFFFF;
                    }
                    else                                                // ....................... Cell link ........................
                    {
                        UCell UC = UGL.UC;
                        int   rc = UC.rc;
                        //In UGLLst, rcb-Links is first, and cell-Links is second.
                        //Even in combination, this order is maintained.
                        //Therefore, the condition "cell-links have common parts with rcb-Links?" is satisfied.
                        foreach (var no in UC.FreeB.IEGet_BtoNo(9))
                        {
                            if (k > 0 && HB981.IsHit(no, rc))
                            {
                                goto LNextSet;                                              //Not BaseSet as it has no intersection.
                            }
                            HB981.BPSet(no, rc, tfbSet: true);                              //accumulate rcbn info. in HB981.
                            _RCB_frameB[no] |= rc.ToRCBitPat();
                        }
                        int IDrc = rc << 4 | 0xF; //( 0xF:Cell type identification flag )
                        usedLKLst.Add(IDrc);      //(ID=rc<<4| no)               //[cell type]register ID to used list.
                    }
                    basUGLs.Add(UGL);             //set UGL in BaseSet
                                                  // ...........................................................
                }
                BSstatus.RCB_frameB = _RCB_frameB;
                __UsedLinkToFrame(HB981, usedLKLst, BSstatus);

////                if(SDK_Ctrl.UGPMan.stageNo==8 && _usedLKLst_ToRCBString("",usedLKLst)==" c1#3 c1#6"){
////                    Board_Check("*** Check_6 ?");
////                }

                if (SDK_Ctrl.UGPMan.stageNo == 20 && _usedLKLst_ToRCBString("", usedLKLst) == " r3#2 r4#2 r3#8")
                {
                    WriteLine(_usedLKLst_ToRCBString($"usedLKLst:{_jkc_}", usedLKLst, addFreeBB: true));
                    Board_Check();
                }

                //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*
//                Board_Check();
                //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2

                if (!BSstatus.Check_1())
                {
                    goto LNextSet;                            //A and B are not linked by other link(C).
                }
                if (!BSstatus.Check_2())
                {
                    goto LNextSet;                            //Each cell(A) is in a position to link with other cells.
                }
                if (!BSstatus.Check_3())
                {
                    goto LNextSet;                            //There is a limit to the number of cells that have no links other than BaseSet.
                }
                //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*

                /*
                 *        //if(SDK_Ctrl.UGPMan.stageNo==12 && sz>=3){// && rnk==1 ){
                 *          if(SDK_Ctrl.UGPMan.stageNo==9 && sz>=2){// && rnk==1 ){
                 *              WriteLine($"\r sz:{sz} rnk:{rnk} jkc:{_jkc_}");
                 *              Check_rcbnCondition(sz,rnk,sz,RCBN_frameA,printB:true);
                 *              basUGLs.ForEach(P=>WriteLine(P.ToString("BaseSet")));
                 *          }
                 */

LBSFound:
                usedLK.Clear();
                basUGLs.ForEach(P => usedLK.BPSet(P.IDnum)); //IDrc: rc<<17 | 1<<16
                UBasCov UBC = new UBasCov(basUGLs, HB981, sz, usedLK);
                yield return(UBC);

                //---------------------------------------------------------------------------------------
LNextSet:
                continue;
            }
            yield break;

            void __UsedLinkToFrame(Bit981 HB981, List <int> usedLKLst, BaseSet_Status BSstatus)
            {
                int[] _frame_0 = new int[9];
                int[] _frame_1 = new int[9];
                Bit81 _frame_T = new Bit81();
                int   frm, _cellC = 0;

                foreach (var no in HB981.noBit.IEGet_BtoNo())
                {
                    _frame_0[no] = frm = HB981._BQ[no].IEGetRC().Aggregate(0, (Q, rc) => Q | rc.ToRCBitPat());
                    _frame_1[no] = ___frame_ResetUsed(frm, no, usedLKLst);
                    _frame_T    |= HB981._BQ[no];
                }
                Bit81 _frame_81 = new Bit81(_frame_T);

                usedLKLst.ForEach(P => { if ((P & 0xF) == 0xF)
                                         {
                                             _frame_81.BPReset(P >> 4); _cellC++;
                                         }
                                  });

                BSstatus._frame_0  = _frame_0;
                BSstatus._frame_1  = _frame_1;
                BSstatus._frame_T  = _frame_T;
                BSstatus._frame_81 = _frame_81;
                BSstatus._cellC    = _cellC;        //(Number of cell links in BaseSet)
            }
        }
Ejemplo n.º 17
0
 public Bit81(Bit81 P) : this()
 {
     this._BP[0] = P._BP[0]; this._BP[1] = P._BP[1]; this._BP[2] = P._BP[2];
 }
        //XY-Chain is an algorithm using Locked which occurs in the concatenation of bivalues.
        //http://csdenpe.web.fc2.com/page49.html
        public bool XYChain()
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                //Generate StrongLink

            List <int> LKRec = new List <int>();

            foreach (var CRL in _GetXYChain(LKRec))
            {
                int rcS = CRL[0].ID, no = CRL[1].ID, noB = (1 << no);

                Bit81 ELM = ConnectedCells[rcS] - (CRL[0] | CRL[1]);
                if (ELM.IsZero())
                {
                    continue;
                }

                Bit81 ELM2     = new Bit81();
                bool  XYChainF = false;
                foreach (var E in ELM.IEGetUCeNoB(pBDL, noB))
                {
                    if (CRL[0].IsHit(ConnectedCells[E.rc]))
                    {
                        E.CancelB = noB; XYChainF = true;
                        ELM2     |= CRL[0] & ConnectedCells[E.rc];
                        break;
                    }
                }
                if (!XYChainF)
                {
                    continue;
                }

                //===== XY-Chain found =====
                SolCode = 2;
                String SolMsg = "XY Chain";
                Result = SolMsg;

                int rcE;
                foreach (var P in ELM2.IEGetUCeNoB(pBDL, noB))
                {
                    P.SetNoBBgColor(noB, AttCr, SolBkCr);
                }
                Bit81 ELM2cpy = new Bit81(ELM2);
                while ((rcE = ELM2.FindFirstrc()) >= 0)
                {
                    string stR      = "";
                    Bit81  XYchainB = _SelectLink_XYChain(LKRec, rcS, rcE, noB, ref stR) - ELM2cpy;
                    if (SolInfoB)
                    {
                        SolMsg += "\r " + stR;
                    }

                    foreach (var P in XYchainB.IEGetUCeNoB(pBDL, 0x1FF))
                    {
                        P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr2);
                    }
                    ELM2.BPReset(rcE);
                }
                if (SolInfoB)
                {
                    ResultLong = SolMsg;
                }
                pBDL[rcS].SetNoBBgColor(noB, AttCr, SolBkCr);

                if (__SimpleAnalizerB__)
                {
                    return(true);
                }
                if (!pAnMan.SnapSaveGP(true))
                {
                    return(true);
                }
                XYChainF = false;
            }
            return(false);
        }
        private bool _ALSXYWingSub(int szT)
        {
            //(ALS sorted by size)
            foreach (var UC in ALSMan.ALSLst.Where(p => p.Size <= szT - 2))
            {
                if (!UC.singly)
                {
                    continue;
                }
                int szS = szT - UC.Size;

                UALS UA, UB, UApre = null;
                int  nxt = 0, RccAC = -1, RccBC = -1;
                var  cmb = new Combination(ALSMan.ALSLst.Count, 2);
                while (cmb.Successor(nxt))
                {
                    nxt = 0;
                    UA  = ALSMan.ALSLst[cmb.Index[0]];
                    if (!UA.singly || UA == UC || UA.Size > szS - 1)
                    {
                        continue;
                    }
                    if (UA != UApre)
                    {
                        RccAC = ALSMan.Get_AlsAlsRcc(UA, UC);    //RCC
                        if (RccAC.BitCount() != 1)
                        {
                            continue;
                        }
                        UApre = UA;
                    }

                    UB = ALSMan.ALSLst[cmb.Index[1]];
                    if (!UB.singly || UB.Size > (szS - UA.Size))
                    {
                        continue;                                      //Skip using "Sort by size"
                    }
                    nxt = 1;
                    if (UB == UC || UB.Size != (szS - UA.Size))
                    {
                        continue;
                    }
                    if (!(UA.B81 & UB.B81).IsZero())
                    {
                        continue;                               //Overlap
                    }
                    RccBC = ALSMan.Get_AlsAlsRcc(UB, UC);       //RCC
                    if (RccBC.BitCount() != 1)
                    {
                        continue;
                    }
                    if (RccAC == RccBC)
                    {
                        continue;
                    }

                    int EFrB = (UA.FreeB & UB.FreeB).DifSet(RccAC | RccBC);
                    if (EFrB == 0)
                    {
                        continue;
                    }
                    foreach (var no in EFrB.IEGet_BtoNo())
                    {
                        int   noB = (1 << no);
                        Bit81 UE  = new Bit81();
                        foreach (var P in UA.UCellLst.Where(p => (p.FreeB & noB) > 0))
                        {
                            UE.BPSet(P.rc);
                        }
                        foreach (var P in UB.UCellLst.Where(p => (p.FreeB & noB) > 0))
                        {
                            UE.BPSet(P.rc);
                        }

                        Bit81 TBD = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81 | UC.B81);
                        foreach (var rc in TBD.IEGet_rc())
                        {
                            if (!(UE - ConnectedCells[rc]).IsZero())
                            {
                                continue;
                            }
                            pBDL[rc].CancelB = noB; SolCode = 2;
                        }

                        if (SolCode > 0) //===== ALS XY-Wing found =====
                        {
                            ALSXYWing_SolResult(UA, UB, UC, RccAC, RccBC);
                            if (__SimpleAnalizerB__)
                            {
                                return(true);
                            }
                            if (!pAnMan.SnapSaveGP(true))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
        public bool ForceChain_HouseEx( )
        {
            if (GNPXApp000.GMthdOption["ForceChainCellHouseOn"] != "1")
            {
                return(false);
            }

            GroupedLink._IDsetB = false;  //ID set for debug

            Prepare();
            pSprLKsMan.PrepareSuperLinkMan(AllF: true);
            string dspOpt = GNPXApp000.GMthdOption["ForceLx"];

            Bit81[] sPass = new Bit81[9];
            for (int k = 0; k < 9; k++)
            {
                sPass[k] = new Bit81();
            }

            bool solvedA = false;

            for (int hs0 = 0; hs0 < 27; hs0++)
            {
                int noBs = pBDL.IEGetCellInHouse(hs0).Aggregate(0, (Q, P) => Q | (P.FreeB));

                bool solvedB = false;
                foreach (var no0 in noBs.IEGet_BtoNo())
                {
                    int     noB   = (1 << no0);
                    Bit81[] sTrue = new Bit81[9];
                    for (int k = 0; k < 9; k++)
                    {
                        sTrue[k] = new Bit81(all_1: true);
                    }

                    foreach (var P0 in pBDL.IEGetCellInHouse(hs0, noB))
                    {
                        USuperLink USLK = pSprLKsMan.get_L2SprLK(P0.rc, no0, FullSearchB: false, DevelopB: false);
                        if (USLK == null || !USLK.SolFound)
                        {
                            goto nextSearch;
                        }

                        for (int k = 0; k < 9; k++)
                        {
                            sTrue[k] &= (USLK.Qtrue[k] - USLK.Qfalse[k]);
                            sTrue[k].BPReset(P0.rc);
                        }
                    }

                    for (int nox = 0; nox < 9; nox++)
                    {
                        if (!sTrue[nox].IsZero())
                        {
                            solvedB = true; break;
                        }
                    }

                    if (solvedB)
                    {
                        solvedA = true;
                        _ForceChainHouseDispEx(sPass, sTrue, hs0, no0);
                        if (!SDK_Ctrl.MltAnsSearch && dspOpt == "ForceL0")
                        {
                            return(true);
                        }
                    }
                }

                if (solvedA && dspOpt == "ForceL1")
                {
                    _ForceChainHouseDispEx(sPass, null, hs0, -1);
                    if (!SDK_Ctrl.MltAnsSearch)
                    {
                        return(true);
                    }
                }

nextSearch:
                continue;
            }
            if (solvedA && !SDK_Ctrl.MltAnsSearch && dspOpt == "ForceL2")
            {
                _ForceChainHouseDispEx(sPass, null, -1, -1);
            }

            return(SolCode > 0);
        }