LockedCandidate

LockedCandidateには、2つのタイプがあります。

タイプ1

着目ブロックで数字Nの入るのが1行(または1列)のみのとき、行方向(列方向)のブロックの同じ行(列)では数字Nが候補から除外されます。

LockedCandidate

ブロックb5では、数字5が入るのはr6のみです。
従って、ブロックb6のr6c9では数字5は候補から除外されます。

.3.1.5.8...........8.....2...9.1.2...5.3.9.4..6.....7.7..6.1..851..7..69..8...7..


タイプ2

着目ブロックと行方向(列方向)で関連するブロックに着目します。 数字Nの入るのが2行(または2)のとき、 着目ブロックでは行方向(列方向)の同じ2行(2列)では数字Nが候補から除外される。

LockedCandidate

数字7に着目すると、ブロックb1とb2では2・3行目にあります。
従って、ブロックb3では1行目に限定され、r2c8では数字7は候補から除外されます。

...3.9...3.......564.....89.........89..2..51..6.5.8..5.1...7.8.3.5.4.2.7..1.2..3

解析プログラム LockedCandidate

>public class LockedCandidateGen: AnalyzerBaseV2{
    public LockedCandidateGen( GNPX_AnalyzerMan AnMan ): base(AnMan){ }

    public override void Initialize(){}

    public bool LockedCandidate( ){
        for( int no=0; no<9; no++ ){
            int noB=(1<<no);
            int[] BRCs = new int[9];
            foreach( var P in pBDL.Where(Q=>(Q.FreeB&noB)>0) )
                BRCs[P.b] |= (1<<P.r)|(1<<(P.c+9));

            //==== Type-1 =====
            for( int b0=0; b0<9; b0++ ){
                for( int hs=0; hs<10; hs+=9 ){  //0:行 9:列
                    int RCH=BRCs[b0]&(0x1FF<<hs);
                    if( RCH.BitCount()==1 ){
                        int hs0=RCH.BitToNum(18);
                        if( pBDL.IEGetCellsInHouse(hs0,noB).Any(Q=>Q.b!=b0) ){
                            SolCode=2;
                            foreach( var P in pBDL.IEGetCellsInHouse(hs0,noB) ){ 
                                if(P.b!=b0) P.CancelB=noB;
                                else        P.SetNoBBgColor(noB,AttCr3,SolBkCr);
                            }
                            string SolMsg= "Locked Candidate B"+(b0+1)+" #"+(no+1);
                            Result=SolMsg;
                            if(SolInfoDsp) ResultLong=SolMsg;
                            if(!AnMan.SnapSaveGP())  return true;
                        }
                    }
                }
            }
            
            //==== Type-2 =====
            for( int b0=0; b0<9; b0++ ){
                int b1, b2, rcB0, rcB1, rcB2;
                for( int hs=0; hs<10; hs+=9 ){  //0:行 9:列
                    int hsX=0x1FF<<hs;
                    //関連ブロック
                    if(hs==0){ b1=b0/3*3+(b0+1)%3; b2=b0/3*3+(b0+2)%3; }// b1,b2:行方向
                    else{      b1=(b0+3)%9;        b2=(b0+6)%9; }       // b1,b2:列方向

                    if( (rcB0=BRCs[b0]&hsX).BitCount() <=1 )  continue;
                    if( (rcB1=BRCs[b1]&hsX) <=0 )  continue;
                    if( (rcB2=BRCs[b2]&hsX) <=0 )  continue;

                    int rcB12 = rcB1|rcB2;
                    int hs0=(rcB0.DifSet(rcB12)).BitToNum(18);
                    if( rcB12.BitCount()==2 && hs0>=0 ){ //発見
                        SolCode=2;
                        foreach( var P in pBDL.IEGetCellsInHouse(18+b0,noB) ){  //着目ブロック
                            if( !HouseCells[hs0].IsHit(P.rc) ) P.CancelB=noB;
                            else   P.SetNoBBgColor(noB,AttCr3,SolBkCr);
                        }
                        foreach( var P in pBDL.IEGetCellsInHouse(18+b1,noB) )
                            P.SetNoBBgColor(noB,AttCr3,SolBkCr);//他ブロック情報設定
                        foreach( var P in pBDL.IEGetCellsInHouse(18+b2,noB) ) 
                            P.SetNoBBgColor(noB,AttCr3,SolBkCr);
                        string SolMsg= "Locked Candidate B"+(b0+1)+" #"+(no+1);
                        Result=SolMsg;
                        if(SolInfoDsp) ResultLong=SolMsg;
                        if(!AnMan.SnapSaveGP())  return true;
                    }
                }
            }
        }
        return false;
    }
}

Top