//X-Chain is an algorithm using Locked which occurs when concatenating strong and weak links.
        //http://csdenpe.web.fc2.com/page48.html
        public bool XChain()
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                                          //Generate StrongLink

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

                List <int> LKRec = new List <int>();
                foreach (var CRL in _GetXChain(no, LKRec))
                {
                    int rcS = CRL[0].ID;                                 //Bit81.ID is used for information exchange(irregular use)

                    Bit81 ELM = (ConnectedCells[rcS] & CRL[1]) - CRL[2]; //CRL[2]:exclude chain of only two links(trivial solution).
                    if (ELM.IsZero())
                    {
                        continue;                                   //ELM:eliminatable cells
                    }
                    //===== X-Chain found =====
                    SolCode = 2;
                    foreach (var P in ELM.IEGetUCeNoB(pBDL, noB))
                    {
                        P.CancelB = noB;
                    }
                    string SolMsg = $"X-Chain #{(no+1)}";
                    Result = SolMsg;
                    if (SolInfoB)
                    {
                        Bit81 LKRecB = _SelectLink_XChain(LKRec, rcS, ELM, noB); //Extract related-Link
                        CRL[0] &= LKRecB; CRL[1] &= LKRecB;

                        Color Cr  = _ColorsLst[0];
                        Color Cr1 = Color.FromArgb(255, Cr.R, Cr.G, Cr.B);
                        Color Cr2 = Color.FromArgb(120, Cr.R, Cr.G, Cr.B);     //(Lightness adjustment)
                        foreach (var P in CRL[0].IEGetUCeNoB(pBDL, noB))
                        {
                            P.SetNoBBgColor(noB, AttCr, Cr2);
                        }
                        foreach (var P in CRL[1].IEGetUCeNoB(pBDL, noB))
                        {
                            P.SetNoBBgColor(noB, AttCr, Cr1);
                        }
                        pBDL[rcS].SetNoBBgColor(noB, AttCr, SolBkCr);
                        ResultLong = SolMsg;;
                    }
                    if (__SimpleAnalizerB__)
                    {
                        return(true);
                    }
                    if (!pAnMan.SnapSaveGP(true))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Пример #2
0
        public bool EndoFinnedFMFish_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 = Cov.FinB81 | Bas.EndoFin;
                    Bit81 E      = Cov.CoverB81 - Bas.BaseB81;
                    Bit81 ELM    = new Bit81();

                    //see latest viewpoint
                    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)); //27:Franken/Mutant
                            }
                            //WriteLine(ResultLong);
                            if (__SimpleAnalizerB__)
                            {
                                return(true);
                            }
                            if (!pAnMan.SnapSaveGP(true))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
Пример #3
0
        //Link between Cell and ALS
        public void QSearch_Cell2ALS_Link( )
        {
            if (ALSLst == null)
            {
                PrepareALSLinkMan(1);
            }
            if (LinkCeAlsLst != null)
            {
                return;
            }
            LinkCeAlsLst = new List <LinkCellALS> [81];
            if (ALSLst == null || ALSLst.Count < 2)
            {
                return;
            }

            foreach (var PA in ALSLst.Where(P => P.singly))
            {
                foreach (var no in PA.FreeB.IEGet_BtoNo())
                {
                    int   noB = (1 << no);
                    Bit81 H   = new Bit81(true);
                    foreach (var P in PA.UCellLst.Where(q => (q.FreeB & noB) > 0))
                    {
                        H &= pConnectedCells[P.rc];
                    }
                    if (H.IsZero())
                    {
                        continue;
                    }
                    foreach (var P in H.IEGetUCeNoB(pBDL, noB))
                    {
                        var Q = new LinkCellALS(P, PA, no);
                        if (LinkCeAlsLst[P.rc] == null)
                        {
                            LinkCeAlsLst[P.rc] = new List <LinkCellALS>();
                        }
                        LinkCeAlsLst[P.rc].Add(Q);
                    }
                }
            }
            for (int rc = 0; rc < 81; rc++)
            {
                if (LinkCeAlsLst[rc] != null)
                {
                    LinkCeAlsLst[rc].Sort();
                }
            }
        }
        private Bit81 _SelectLink_XChain(List <int> LKRec, int rcS, Bit81 ELM, int noB)
        {
            Bit81 LKRecB = new Bit81();

            foreach (var P in ELM.IEGetUCeNoB(pBDL, noB))
            {
                int rcX = P.rc;
                LKRecB.BPSet(rcX);
                while (rcX != rcS)
                {
                    rcX = LKRec.Find(p => (p & 0xFF) == rcX);
                    if (rcX == 0)
                    {
                        break;
                    }
                    rcX = (rcX >> 8);
                    LKRecB.BPSet(rcX);
                }
            }
            return(LKRecB);
        }
        //W-Wing is an algorithm composed of bivalue cell and link.
        //http://csdenpe.web.fc2.com/page43.html
        public bool  Wwing( )
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);    //Generate StrongLink

            if (BVCellLst == null)
            {
                BVCellLst = pBDL.FindAll(p => (p.FreeBC == 2));             //BV:BiValue
            }
            if (BVCellLst.Count < 2)
            {
                return(false);
            }
            BVCellLst.Sort((A, B) => (A.FreeB - B.FreeB));                       //Important!!!

            bool Wwing = false;
            var  cmb   = new Combination(BVCellLst.Count, 2);
            int  nxt   = 99;

            while (cmb.Successor(nxt))
            {
                UCell P = BVCellLst[cmb.Index[0]];
                UCell Q = BVCellLst[cmb.Index[1]];
                nxt = 1;
                if (P.FreeB != Q.FreeB)
                {
                    nxt = 0; continue;
                }                                                           //BVCellLst is sorted, so possible to skip.
                if (ConnectedCells[P.rc].IsHit(Q.rc))
                {
                    continue;
                }

                foreach (var L in CeLKMan.IEGetCellInHouse(1))               //1:StrongLink(Link has a direction. The opposite link is different.)
                {
                    int no1B = (1 << L.no);
                    if ((P.FreeB & no1B) == 0)
                    {
                        continue;
                    }
                    if (L.rc1 == P.rc || L.rc2 == Q.rc)
                    {
                        continue;
                    }
                    if (!ConnectedCells[P.rc].IsHit(L.rc1))
                    {
                        continue;                                           //L.rc1 is in the connected area of ​​P.rc?
                    }
                    if (!ConnectedCells[Q.rc].IsHit(L.rc2))
                    {
                        continue;                                           //L.rc2 is in the connected area of Q.rc?
                    }
                    int no2B = P.FreeB.BitReset(L.no);                      //another digit

                    string msg2 = "";
                    Bit81  ELM  = ConnectedCells[P.rc] & ConnectedCells[Q.rc]; //ELM:Common part of the influence area of ​​cell P and cell Q
                    foreach (var E in ELM.IEGetUCeNoB(pBDL, no2B))             //Cell/digit in ELM can be excluded
                    {
                        E.CancelB = no2B; Wwing = true;                        //W-Wing found
                        if (SolInfoB)
                        {
                            msg2 += " " + E.rc.ToRCString();
                        }
                    }
                    if (!Wwing)
                    {
                        continue;
                    }

                    SolCode = 2;
                    if (SolInfoB)
                    {
                        UCell A = pBDL[L.rc1], B = pBDL[L.rc2];
                        int   noBX = P.FreeB.DifSet(no2B);
                        P.SetNoBBgColor(noBX, AttCr, SolBkCr2);
                        Q.SetNoBBgColor(noBX, AttCr, SolBkCr2);

                        A.SetNoBBgColor(no1B, AttCr, SolBkCr);
                        B.SetNoBBgColor(no1B, AttCr, SolBkCr);

                        string msg0 = $" bvCell: {_XYwingResSub(P)} ,{_XYwingResSub(Q)}";
                        string msg1 = $"  SLink: {A.rc.ToRCNCLString()}-{B.rc.ToRCNCLString()}(#{(L.no+1)})";
                        Result     = $"W Wing Eli.;#{(no2B.BitToNum()+1)} in {msg2.ToString_SameHouseComp()}";
                        ResultLong = "W Wing\r" + msg0 + "\r" + msg1
                                     + $"\r Eliminated: #{(no2B.BitToNum()+1)} in {msg2.ToString_SameHouseComp()}";
                    }

                    if (__SimpleAnalizerB__)
                    {
                        return(true);
                    }
                    if (!pAnMan.SnapSaveGP(true))
                    {
                        return(true);
                    }
                    Wwing = false;
                }
            }
            return(false);
        }
        public bool ExtFishSub(int sz, int no, int FMSize, int BaseSel, int CoverSel, bool FinnedF, bool _Fdef = true)
        {
            int  noB     = (1 << no);
            bool extFlag = (sz >= 3 && ((BaseSel | CoverSel).BitCount() > 18));

            if (_Fdef)
            {
                FMan = new FishMan(this, FMSize, no, sz, extFlag);
            }

            foreach (var Bas in FMan.IEGet_BaseSet(BaseSel, FinnedF:FinnedF))     //select BaseSet
            {
                if (pAnMan.CheckTimeOut())
                {
                    return(false);
                }

                foreach (var Cov in FMan.IEGet_CoverSet(Bas, CoverSel, FinnedF))   //select CoverSet
                {
                    Bit81 FinB81 = Cov.FinB81;

                    Bit81 ELM      = null;
                    var   FinZeroB = FinB81.IsZero();
                    if (!FinnedF && FinZeroB)    //===== no Fin =====
                    {
                        if (!FinnedF && (ELM = Cov.CoverB81 - Bas.BaseB81).Count > 0)
                        {
                            foreach (var P in ELM.IEGetUCeNoB(pBDL, noB))
                            {
                                P.CancelB = noB; SolCode = 2;
                            }
                            if (SolCode > 0)       //solved!(
                            {
                                if (SolInfoB)
                                {
                                    _Fish_FishResult(no, sz, Bas, Cov, (FMSize == 27)); //FMSize 18:regular 27:Franken/Mutant
                                }
                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(true))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                    else if (FinnedF && !FinZeroB)      //===== Finned =====
                    {
                        Bit81 Ecand = Cov.CoverB81 - Bas.BaseB81;
                        ELM = new Bit81();
                        foreach (var P in Ecand.IEGetUCeNoB(pBDL, noB))
                        {
                            if ((FinB81 - ConnectedCells[P.rc]).Count == 0)
                            {
                                ELM.BPSet(P.rc);
                            }
                        }
                        if (ELM.Count > 0)     //there are cells/digits can be excluded
                        {
                            foreach (var P in ELM.IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.CancelB = noB; SolCode = 2;
                            }
                            if (SolCode > 0)   //solved!
                            {
                                if (SolInfoB)
                                {
                                    _Fish_FishResult(no, sz, Bas, Cov, (FMSize == 27)); //FMSize 18:regular 27:Franken/Mutant
                                }
                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(true))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                    continue;
                }
            }
            return(false);
        }
Пример #7
0
        //Skyscraper is an algorithm consisting of two StrongLinks.
        //http://csdenpe.web.fc2.com/page40.html
        public bool Skyscraper()
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                                             //Generate StrongLink

            for (int no = 0; no < 9; no++)
            {
                int noB   = (1 << no);
                var SSLst = CeLKMan.IEGetNoType(no, 1).ToList();         //select only StrongLink of #no
                if (SSLst.Count <= 2)
                {
                    continue;
                }

                var prm  = new Permutation(SSLst.Count, 2);
                int nxtX = 99;
                while (prm.Successor(nxtX))
                {
                    UCellLink UCLa = SSLst[prm.Index[0]], UCLb = SSLst[prm.Index[1]];

                    nxtX = 1;
                    if (UCLa.ID > UCLb.ID)
                    {
                        nxtX = 0; continue;
                    }                                                   //next permutation data skip_generation(nxtX=0)
                    if ((UCLa.B81 | UCLb.B81).Count != 4)
                    {
                        continue;                                       //All cells are different?
                    }
                    Bit81 ConA1 = ConnectedCells[UCLa.rc1];             //ConA1:cell group related to cell rc1
                    if (!ConA1.IsHit(UCLb.rc1) || ConA1.IsHit(UCLb.rc2))
                    {
                        continue;
                    }

                    Bit81 ConA2 = ConnectedCells[UCLa.rc2];               //ConA2:cell group related to cell rc1
                    if (ConA2.IsHit(UCLb.rc1) || ConA2.IsHit(UCLb.rc2))
                    {
                        continue;
                    }
                    //Only UCLa.rc1 and UCLb.rc1 belong to the same house.

                    Bit81 ELM = ConA2 & ConnectedCells[UCLb.rc2];
                    ELM -= (ConA1 | ConnectedCells[UCLb.rc1]);          //ELM:eliminatable cells

                    bool SSfound = false;
                    foreach (UCell P in ELM.IEGetUCeNoB(pBDL, noB))
                    {
                        P.CancelB = P.FreeB & noB; SSfound = true;
                    }
                    if (!SSfound)
                    {
                        continue;           //Skyscraper found
                    }
                    #region Result
                    SolCode = 2;
                    if (SolInfoB)
                    {
                        pBDL[UCLa.rc1].SetNoBBgColor(noB, AttCr, SolBkCr);
                        pBDL[UCLa.rc2].SetNoBBgColor(noB, AttCr, SolBkCr);
                        pBDL[UCLb.rc1].SetNoBBgColor(noB, AttCr, SolBkCr);
                        pBDL[UCLb.rc2].SetNoBBgColor(noB, AttCr, SolBkCr);

                        string msg = "\r", msg2 = "";
                        msg += $"  on {(no+1)} in {UCLa.rc1.ToRCNCLString()} {UCLb.rc1.ToRCNCLString()}";
                        msg += $"\r  connected by {UCLa.rc2.ToRCNCLString()} {UCLb.rc2.ToRCNCLString()}";
                        msg += "\r  eliminated ";
                        foreach (UCell P in ELM.IEGetUCeNoB(pBDL, noB))
                        {
                            msg2 += " " + P.rc.ToRCString();
                        }
                        msg2      += " " + msg2.ToString_SameHouseComp();
                        ResultLong = "Skyscraper" + msg + msg2;
                        Result     = $"Skyscraper #{(no+1)} in {msg2}";
                    }
                    else
                    {
                        Result = $"Skyscraper #{(no+1)}";
                    }
                    #endregion Result
                    if (__SimpleAnalizerB__)
                    {
                        return(true);
                    }
                    if (!pAnMan.SnapSaveGP(true))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        private void SearchGroupedLink()
        {
            try{
                UGrCells[] LQ = new UGrCells[3];
                for (int no = 0; no < 9; no++)
                {
                    int   noB   = 1 << no;
                    Bit81 BPnoB = new Bit81(pBDL, noB);

                    //------------------------------------------
                    for (int tfx = 0; tfx < 18; tfx++)
                    {
                        Bit81 BPnoB2 = BPnoB & pHouseCells[tfx];

                        List <Bit81> houseLst = new List <Bit81>();
                        List <int>   tfxLst   = new List <int>();
                        for (int k = 0; k < 9; k++)
                        {
                            int   hx = (tfx < 9)? (k + 9): k;
                            Bit81 BX = BPnoB2 & pHouseCells[hx];
                            if (BX.IsZero())
                            {
                                continue;
                            }
                            houseLst.Add(BX);
                            tfxLst.Add(hx);
                        }
                        for (int k = 0; k < 3; k++)
                        {
                            int hx = (tfx < 9)? (tfx / 3 * 3 + k): ((tfx - 9) / 3 + k * 3);
                            hx += 18;
                            Bit81 BX = BPnoB2 & pHouseCells[hx];
                            if (BX.IsZero())
                            {
                                continue;
                            }
                            houseLst.Add(BX);
                            tfxLst.Add(hx);
                        }

                        if (houseLst.Count < 2)
                        {
                            continue;
                        }
                        Permutation prm = new Permutation(houseLst.Count, 2);
                        while (prm.Successor())
                        {
                            int   na = prm.Index[0], nb = prm.Index[1];
                            Bit81 HA = houseLst[na];
                            Bit81 HB = houseLst[nb];
                            if (!(HA & HB).IsZero())
                            {
                                continue;
                            }
                            UGrCells LA = new UGrCells(tfxLst[na], no);
                            UGrCells LB = new UGrCells(tfxLst[nb], no);
                            foreach (var P in HA.IEGetUCeNoB(pBDL, 0x1FF))
                            {
                                LA.Add(P);
                            }
                            foreach (var P in HB.IEGetUCeNoB(pBDL, 0x1FF))
                            {
                                LB.Add(P);
                            }
                            SetGroupedLink(tfxLst[nb], W, no, LA, LB);
                            if (!(BPnoB2 - (HA | HB)).IsZero())
                            {
                                continue;
                            }
                            SetGroupedLink(tfxLst[nb], S, no, LA, LB);
                        }
                    }

                    //------------------------------------------
                    for (int tfx = 18; tfx < 27; tfx++)
                    {
                        int bx = tfx - 18;
                        int b0 = (bx / 3 * 27 + (bx % 3) * 3); //Cell number at the top left of the block

                        Bit81        BPnoB2   = BPnoB & pHouseCells[tfx];
                        List <Bit81> houseLst = new List <Bit81>();
                        List <int>   tfxLst   = new List <int>();
                        for (int k = 0; k < 3; k++)
                        {
                            int   r0 = (b0 / 9 + k);
                            Bit81 BX = BPnoB2 & pHouseCells[r0];
                            if (BX.IsZero())
                            {
                                continue;
                            }
                            houseLst.Add(BX);
                            tfxLst.Add(r0);
                        }
                        for (int k = 0; k < 3; k++)
                        {
                            int   c0 = (b0 % 9) + k;
                            Bit81 BX = BPnoB2 & pHouseCells[c0 + 9];
                            if (BX.IsZero())
                            {
                                continue;
                            }
                            houseLst.Add(BX);
                            tfxLst.Add(c0 + 9);
                        }

                        if (houseLst.Count >= 2)
                        {
                            Permutation prm = new Permutation(houseLst.Count, 2);
                            while (prm.Successor())
                            {
                                int   na = prm.Index[0], nb = prm.Index[1];
                                Bit81 HA = houseLst[na];
                                Bit81 HB = houseLst[nb] - HA;
                                if (HB.IsZero())
                                {
                                    continue;
                                }
                                UGrCells LA = new UGrCells(tfxLst[na], no);
                                UGrCells LB = new UGrCells(tfxLst[nb], no);
                                foreach (var P in HA.IEGetUCeNoB(pBDL, 0x1FF))
                                {
                                    LA.Add(P);
                                }
                                foreach (var P in HB.IEGetUCeNoB(pBDL, 0x1FF))
                                {
                                    LB.Add(P);
                                }
                                SetGroupedLink(tfxLst[nb], W, no, LA, LB);
                                if (!(BPnoB2 - (HA | HB)).IsZero())
                                {
                                    continue;
                                }
                                SetGroupedLink(tfxLst[nb], S, no, LA, LB);
                            }
                        }
                        if (houseLst.Count >= 1)
                        {
                            for (int na = 0; na < houseLst.Count; na++)
                            {
                                Bit81    HA = houseLst[na];
                                UGrCells LA = new UGrCells(tfxLst[na], no);
                                foreach (var P in HA.IEGetUCeNoB(pBDL, 0x1FF))
                                {
                                    LA.Add(P);
                                }
                                foreach (var rc in BPnoB2.IEGet_rc())
                                {
                                    if (HA.IsHit(rc))
                                    {
                                        continue;
                                    }
                                    UGrCells LB = new UGrCells(-9, no, pBDL[rc]);
                                    SetGroupedLink(tfxLst[na], W, no, LA, LB);
                                    SetGroupedLink(-9, W, no, LB, LA);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex) {
                WriteLine(ex.Message);
                WriteLine(ex.StackTrace);
            }
        }
        //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);
        }
        //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);
        }