リンク2(Cell-ALS)
セルーALSリンク要素クラス(UCellLink)
セルとALSを繋ぐリンクの要素クラスです。
public class LinkCellAls: IComparable{
public readonly UCell UC;
public readonly UALS ALS;
public readonly int nRCC=-1; //no:0...8 (doubly の場合は個別にリンクを作る)
public LinkCellAls( UCell UC, UALS ALS, int nRCC ){
this.UC=UC; this.ALS=ALS; this.nRCC=nRCC;
}
public override bool Equals( object obj ){
var A = obj as LinkCellAls;
return (this.ALS.ID==A.ALS.ID);
}
public int CompareTo( object obj ){
LinkCellAls A = obj as LinkCellAls;
return (this.ALS.ID-A.ALS.ID);
}
}セルーALSリンクの生成関数(LinkCellAls)
セルとALSを繋ぐリンクの生成関数です。セルーALSリンクは今後開発するアルゴリズムでも使う予定なので、汎用的に作ります。
セルとALSの両方に関わるので、どちらのクラスでもよいのですが、ここではセル管理クラス(CellLinkMan)の関数とします。
リンクは解析途上の盤面ごとに生成しますが、同じ盤面で複数のアルゴリズムが利用することがあり、生成済みの場合にはそれを用います。
生成は次の手順で行います。
- 着目するALSを選ぶ。
- ALSのもつ要素数字を着目数字とする。
- ALS内の着目数字の位置を、行・列・ブロックで集計する(rcbDir)。
- 行・列・ブロックが1方向のみのとき、その方向のセルに着目数字を探す。
該当するセル位置をインデックスとして、リンク配列(LinkCeAlsLst)に登録する。
public partial class CellLinkMan{
public List[] LinkCeAlsLst;
public void Create_Cell2ALS_Link( ALSMan ALSman ){
if( LinkCeAlsLst!=null ) return ;
LinkCeAlsLst = new List<LinkCellAls>[81];
if( ALSman.ALSLst==null || ALSman.ALSLst.Count<2 ) return;
List<UCell> qBDL=pSA.pGP.BDL;
foreach( var PA in ALSman.ALSLst.Where(P=>P.singly) ){
foreach( var no in PA.FreeB.IEGet_BtoNo() ){
if( !PA.singly ) continue;
int noB=(1<<no);
int rcbDir=0;
foreach( var P in PA.UCellLst.Where(q=>(q.FreeB&noB)>0) ){
rcbDir |= ( (1<<(P.b+18)) | (1<<(P.c+9)) | (1<<(P.r)) );
}
for( int tx=0; tx<27; tx+=9 ){
int d = rcbDir&(0x1FF<<tx);
if( d.BitCount()!=1 ) continue;
int tfx=d.BitToNum(27);
foreach( var P in qBDL.IEGet(tfx,noB) ){
if( PA.B81.IsHit(P.rc) ) continue;
var Q = new LinkCellAls(P,PA,no);
if( LinkCeAlsLst[P.rc]==null ){
LinkCeAlsLst[P.rc]=new List<LinkCellAls>();
}
else if( LinkCeAlsLst[P.rc].Contains(Q) ) continue;
LinkCeAlsLst[P.rc].Add(Q);
}
}
}
}
for( int rc=0; rc<81; rc++ ) if( LinkCeAlsLst[rc]!=null ) LinkCeAlsLst[rc].Sort();
}
}