/// <summary> /// 別方法試し中。 /// /// </summary> /// <param name="src_Sky"></param> public static KomanoKikiImpl BETUKAI(SkyConst src_Sky, Playerside tebanside) { // ①現手番の駒の移動可能場所_被王手含む List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus; Util_MovableMove.LA_Get_KomaBETUSusumeruMasus( out komaBETUSusumeruMasus, //進めるマス new MmGenjo_MovableMasuImpl( true, //本将棋か src_Sky, //現在の局面 tebanside, //手番 false //相手番か ), null ); KomanoKikiImpl self = new KomanoKikiImpl(); // // 「升ごとの敵味方」を調べます。 // foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly)// 全駒 { RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now); self.HMasu_PlayersideList[Util_Masu.AsMasuNumber(koma.Masu)] = koma.Pside; } // // 駒のない升は無視します。 // // // 駒のあるマスに、その駒の味方のコマが効いていれば 味方+1 // foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly)// 全駒 { // // 駒 // RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now); // 将棋盤上の戦駒のみ判定 if (Okiba.ShogiBan != Util_Masu.Masu_ToOkiba(koma.Masu)) { goto gt_Next1; } // // 駒の利き FIXME:貫通してないか? // komaBETUSusumeruMasus.Foreach_Entry((Finger figKoma2, SySet <SyElement> kikiZukei, ref bool toBreak) => { IEnumerable <SyElement> kikiMasuList = kikiZukei.Elements; foreach (SyElement masu in kikiMasuList) { // その枡に利いている駒のハンドルを追加 if (self.HMasu_PlayersideList[Util_Masu.AsMasuNumber(masu)] == Playerside.Empty) { // 駒のないマスは無視。 } else if (self.HMasu_PlayersideList[Util_Masu.AsMasuNumber(masu)] == koma.Pside) { // 利きのあるマスにある駒と、この駒のプレイヤーサイドが同じ。 self.Kikisu_AtMasu_Mikata[Util_Masu.AsMasuNumber(masu)] += 1; } else { // 反対の場合。 self.Kikisu_AtMasu_Teki[Util_Masu.AsMasuNumber(masu)] += 1; } } }); gt_Next1: ; } return(self); }
/// <summary> /// 駒別の進めるマスを返します。 /// /// 指定された局面で、指定された手番の駒の、移動可能マスを算出します。 /// 利きを調べる目的ではありません。 /// /// 「手目」は判定できません。 /// /// </summary> /// <param name="kouho"></param> /// <param name="sbGohosyu"></param> /// <param name="logger"></param> public static void LA_Get_KomaBETUSusumeruMasus( out List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus, MmGenjo_MovableMasu mmGenjo, MmLogGenjo log_orNull ) { if (null != log_orNull) { log_orNull.Log1(mmGenjo.Pside_genTeban3); } // 《1》 移動可能場所 komaBETUSusumeruMasus = new List_OneAndMulti <Finger, SySet <SyElement> >(); { // // 《1.1》 手番を2つのグループに分類します。 // // ┌─手番──────┬──────┐ // │ │ │ // │ 利きを調べる側 │ 喰らう側 │ // └─────────┴──────┘ Playerside tebanSeme; //手番(利きを調べる側) Playerside tebanKurau; //手番(喰らう側) { Util_MovableMove.SplitGroup_Teban(out tebanSeme, out tebanKurau, mmGenjo.IsAiteban, mmGenjo.Pside_genTeban3); if (null != log_orNull) { log_orNull.Log2(tebanSeme, tebanKurau); } } // // 《1.2》 駒を4つのグループに分類します。 // // ┌─駒──────────┬─────────┐ // │ │ │ // │ 利きを調べる側の戦駒 │ 喰らう側の戦駒 │ // ├────────────┼─────────┤ // │ │ │ // │ 利きを調べる側の持駒 │ 喰らう側の持駒 │ // └────────────┴─────────┘ // Fingers fingers_seme_IKUSA; //戦駒(利きを調べる側) Fingers fingers_kurau_IKUSA; //戦駒(喰らう側) Fingers fingers_seme_MOTI; // 持駒(利きを調べる側) Fingers fingers_kurau_MOTI; // 持駒(喰らう側) { Util_Things.AAABAAAA_SplitGroup(out fingers_seme_IKUSA, out fingers_kurau_IKUSA, out fingers_seme_MOTI, out fingers_kurau_MOTI, mmGenjo.Src_Sky, tebanSeme, tebanKurau); if (null != log_orNull) { log_orNull.Log3(mmGenjo.Src_Sky, tebanKurau, tebanSeme, fingers_kurau_IKUSA, fingers_kurau_MOTI, fingers_seme_IKUSA, fingers_seme_MOTI); } } // // 《1.3》 駒を2つのグループに分類します。 // // ┌─盤上のマス───┬──────┐ // │ │ │ // │ 利きを調べる側 │ 喰らう側 │ // └─────────┴──────┘ // SySet <SyElement> masus_seme_IKUSA; // 盤上のマス(利きを調べる側の駒) SySet <SyElement> masus_kurau_IKUSA; // 盤上のマス(喰らう側の駒) { Util_MovableMove.SplitGroup_Ikusa(out masus_seme_IKUSA, out masus_kurau_IKUSA, mmGenjo.Src_Sky, fingers_kurau_IKUSA, fingers_seme_IKUSA); // 駒のマスの位置は、特にログに取らない。 } // 《1.4》 Maps_OneAndOne <Finger, SySet <SyElement> > kmSusumeruMasus_seme_IKUSA; if (null != log_orNull) { kmSusumeruMasus_seme_IKUSA = Util_Things.Get_KmEffect_seme_IKUSA( fingers_seme_IKUSA, masus_seme_IKUSA, masus_kurau_IKUSA, mmGenjo.Src_Sky, log_orNull.Enable, Converter04.MoveToStringForLog(log_orNull.Move, mmGenjo.Pside_genTeban3) );// 盤上の駒の移動できる場所 } else { kmSusumeruMasus_seme_IKUSA = Util_Things.Get_KmEffect_seme_IKUSA( fingers_seme_IKUSA, masus_seme_IKUSA, masus_kurau_IKUSA, mmGenjo.Src_Sky, false, //log.Enable, "" ); // 盤上の駒の移動できる場所 } // 持ち駒を置ける場所 List_OneAndMulti <Finger, SySet <SyElement> > sMsSusumeruMasus_seme_MOTI; if (null != log_orNull) { sMsSusumeruMasus_seme_MOTI = Util_Things.Get_Move_Moti( fingers_seme_MOTI, masus_seme_IKUSA, masus_kurau_IKUSA, mmGenjo.Src_Sky, Converter04.MoveToStringForLog(log_orNull.Move, mmGenjo.Pside_genTeban3) ); } else { sMsSusumeruMasus_seme_MOTI = Util_Things.Get_Move_Moti( fingers_seme_MOTI, masus_seme_IKUSA, masus_kurau_IKUSA, mmGenjo.Src_Sky, "" ); } if (null != log_orNull) { log_orNull.Log4(mmGenjo.Src_Sky, tebanSeme, kmSusumeruMasus_seme_IKUSA); } try { // 《1》 = 《1.4》の戦駒+持駒 // 盤上の駒の移動できる場所を足します。 komaBETUSusumeruMasus.AddRange_New(kmSusumeruMasus_seme_IKUSA); // 持ち駒の置ける場所を足します。 komaBETUSusumeruMasus.AddRange_New(sMsSusumeruMasus_seme_MOTI); } catch (Exception ex) { //>>>>> エラーが起こりました。 throw new Exception($"{ex.GetType().Name} {ex.Message}:ランダムチョイス(50):"); } } }
/// <summary> /// まず前提として、 /// 現手番の「被王手の局面」だけがピックアップされます。 /// これはつまり、次の局面がないときは、その枝は投了ということです。 /// </summary> /// <param name="enableLog"></param> /// <param name="isHonshogi"></param> /// <param name="yomuDeep"></param> /// <param name="tesumi_yomiCur"></param> /// <param name="pside_yomiCur"></param> /// <param name="node_yomiCur"></param> /// <param name="logF_moveKiki"></param> /// <param name="logTag"></param> /// <returns>複数のノードを持つハブ・ノード</returns> private static KifuNode WAAAA_CreateNextNodes( MoveGenGenjo genjo, KifuNode node_yomiCur, SsssLogGenjo log ) { // 利きから、被王手の局面を除いたハブノード // このハブ・ノード自身は空っぽで、ハブ・ノードの次ノードが、次局面のリストになっています。 KifuNode hubNode; { // ①現手番の駒の移動可能場所_被王手含む List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus; { GraphicalLog_Board logBrd_move1 = new GraphicalLog_Board();// 盤1個分のログの準備 Util_MovableMove.LA_Get_KomaBETUSusumeruMasus( out komaBETUSusumeruMasus, //進めるマス new MmGenjo_MovableMasuImpl( genjo.Args.IsHonshogi, //本将棋か node_yomiCur.Value.ToKyokumenConst, //現在の局面 genjo.Pside_teban, //手番 false //相手番か ), new MmLogGenjoImpl( log.EnableLog, //ログを出力するかfalse, logBrd_move1, //ログ? genjo.YomuDeep, //読みの深さ genjo.Tesumi_yomiCur, //手済み node_yomiCur.Key //指し手 ) ); MoveGenRoutine.Log1(genjo, node_yomiCur, logBrd_move1);//ログ試し } // ②利きから、被王手の局面を除いたハブノード if (genjo.Args.IsHonshogi) { Maps_OneAndMulti <Finger, ShootingStarlightable> komaBETUAllMoves = Converter04.KomaBETUSusumeruMasusToKomaBETUAllMoves(komaBETUSusumeruMasus, node_yomiCur); Converter04.AssertNariMove(komaBETUAllMoves, "#WAAAA_CreateNextNodes(1)"); // 本将棋の場合、王手されている局面は削除します。 hubNode = Util_LegalMove.LA_RemoveMate( genjo.Args.IsHonshogi, komaBETUAllMoves, genjo.YomuDeep, genjo.Tesumi_yomiCur, genjo.Pside_teban, node_yomiCur, log.EnableLog, genjo.Args.LogF_moveKiki,//利き用 "読みNextルーチン"); Converter04.AddNariMove(node_yomiCur, hubNode); Converter04.AssertNariMove(hubNode, "#WAAAA_CreateNextNodes(2)");//ここで消えていた☆ } else { //そのまま変換 Dictionary <ShootingStarlightable, KyokumenWrapper> ss = Converter04.KomabetuMasusToMovebetuSky( komaBETUSusumeruMasus, node_yomiCur.Value.ToKyokumenConst, genjo.Pside_teban); hubNode = Converter04.MovebetuSky_ToHubNode(ss, KifuNodeImpl.GetReverseTebanside(genjo.Pside_teban)); } } return(hubNode); }