/// <summary> /// 無ければ追加、あれば上書き。 /// </summary> /// <param name="hKoma"></param> /// <param name="masus"></param> public static void AddOverwrite( Maps_OneAndMulti <Finger, SyElement> komabetuMasu, Finger finger, SyElement masu) { if (komabetuMasu.Items.ContainsKey(finger)) { komabetuMasu.Items[finger].Add(masu);//追加します。 } else { // 無かったので、新しく追加します。 List <SyElement> list = new List <SyElement>(); list.Add(masu); komabetuMasu.Items.Add(finger, list); } }
/// <summary> /// 変換「自駒が動ける升」→「自駒が動ける手」 /// </summary> /// <param name="kmDic_Self"></param> /// <returns></returns> public static Maps_OneAndMulti <Finger, ShootingStarlightable> KomabetuMasusToKomabetuMove( Maps_OneAndOne <Finger, SySet <SyElement> > kmDic_Self, Node <ShootingStarlightable, KyokumenWrapper> siteiNode_genzai ) { Maps_OneAndMulti <Finger, ShootingStarlightable> komaTe = new Maps_OneAndMulti <Finger, ShootingStarlightable>(); // // kmDic_Self.Foreach_Entry((Finger key, SySet <SyElement> value, ref bool toBreak) => { foreach (SyElement masuHandle in value.Elements) { RO_Star_Koma koma = Util_Koma.AsKoma(siteiNode_genzai.Value.ToKyokumenConst.StarlightIndexOf(key).Now); ShootingStarlightable move = new RO_ShootingStarlight( //key, // 元 koma, // 先 new RO_Star_Koma( koma.Pside, Masu_Honshogi.Items_All[Util_Masu.AsMasuNumber(masuHandle)], koma.Haiyaku //TODO:成るとか考えたい ), PieceType.None //取った駒不明 ); //sbSfen.Append(sbSfen.ToString()); if (komaTe.ContainsKey(key)) { // すでに登録されている駒 komaTe.AddExists(key, move); } else { // まだ登録されていない駒 komaTe.AddNew(key, move); } } }); return(komaTe); }
/// <summary> /// 変換「各(自駒が動ける升)」→「各(自駒が動ける手)」 /// </summary> /// <param name="komaBETUSusumeruMasus"></param> /// <returns></returns> public static Maps_OneAndMulti <Finger, ShootingStarlightable> KomaBETUSusumeruMasusToKomaBETUAllMoves( List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus, Node <ShootingStarlightable, KyokumenWrapper> siteiNode_genzai ) { Maps_OneAndMulti <Finger, ShootingStarlightable> komabetuAllMove = new Maps_OneAndMulti <Finger, ShootingStarlightable>(); komaBETUSusumeruMasus.Foreach_Entry((Finger figKoma, SySet <SyElement> susumuMasuSet, ref bool toBreak) => { RO_Star_Koma srcKoma = Util_Koma.AsKoma(siteiNode_genzai.Value.ToKyokumenConst.StarlightIndexOf(figKoma).Now); foreach (SyElement susumuMasu in susumuMasuSet.Elements) { // 移動先の駒 RO_Star_Koma dstKoma = new RO_Star_Koma( srcKoma.Pside, Masu_Honshogi.Items_All[Util_Masu.AsMasuNumber(susumuMasu)], srcKoma.Haiyaku//TODO:ここで、駒の種類が「成り」に上書きされているバージョンも考えたい ); ShootingStarlightable move = new RO_ShootingStarlight( //figKoma,//駒 srcKoma, // 移動元 dstKoma, // 移動先 PieceType.None //取った駒不明 ); komabetuAllMove.AddOverwrite(figKoma, move); // これが通称【水際のいんちきプログラム】なんだぜ☆ // 必要により、【成り】の指し手を追加します。 Converter04.AddKomaBETUAllNariMoves( komabetuAllMove, figKoma, srcKoma, dstKoma ); } }); //Converter04.AssertNariMove(komabetuAllMove, "#KomabetuMasus_ToKomabetuAllMove");//ここはOK return(komabetuAllMove); }
/// <summary> /// 指し手一覧を、駒毎に分けます。 /// </summary> /// <param name="hubNode">指し手一覧</param> /// <param name="logTag"></param> /// <returns>駒毎の、全指し手</returns> public Maps_OneAndMulti <Finger, ShootingStarlightable> SplitMoveByKoma(Node <ShootingStarlightable, KyokumenWrapper> hubNode) { SkyConst src_Sky = this.Value.ToKyokumenConst; Maps_OneAndMulti <Finger, ShootingStarlightable> enable_teMap = new Maps_OneAndMulti <Finger, ShootingStarlightable>(); hubNode.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) => { ShootingStarlightable nextMove = nextNode.Key; Finger figKoma = Util_Sky.Fingers_AtMasuNow(src_Sky, Util_Koma.AsKoma(nextMove.LongTimeAgo).Masu).ToFirst(); enable_teMap.AddOverwrite(figKoma, nextMove); }); return(enable_teMap); }
/// <summary> /// 次の局面の一覧をもった、入れ物ノードを返します。 /// </summary> /// <param name="kifu"></param> /// <param name="pside_genTeban"></param> /// <returns></returns> public static KifuNode ToNextNodes_AsHubNode( Maps_OneAndMulti <Finger, ShootingStarlightable> komabetuAllMove, Node <ShootingStarlightable, KyokumenWrapper> siteiNode, Playerside pside_genTeban) { KifuNode hubNode = new KifuNodeImpl(null, null, Playerside.Empty);//蝶番 #if DEBUG string dump = komabetuAllMove.Dump(); #endif foreach (KeyValuePair <Finger, List <ShootingStarlightable> > entry1 in komabetuAllMove.Items) { Finger figKoma = entry1.Key;// 駒 // 駒の動ける升全て foreach (ShootingStarlightable move in entry1.Value) { RO_Star_Koma koma = Util_Koma.AsKoma(move.Now); SyElement masu = koma.Masu; SkyConst nextSky = Util_Sasu.Sasu(siteiNode.Value.ToKyokumenConst, figKoma, masu, pside_genTeban); Node <ShootingStarlightable, KyokumenWrapper> nextNode = new KifuNodeImpl(move, new KyokumenWrapper(nextSky), KifuNodeImpl.GetReverseTebanside(pside_genTeban));//次のノード string sfenText = Util_Sky.ToSfenMoveText(move); if (hubNode.ContainsKey_NextNodes(sfenText)) { // 既存の指し手なら無視 System.Console.WriteLine("既存の指し手なので無視します。sfenText=[" + sfenText + "]"); } else { hubNode.Add_NextNode(Util_Sky.ToSfenMoveText(move), nextNode); } } } return(hubNode); }
public static void AssertNariMove(Maps_OneAndMulti <Finger, ShootingStarlightable> komabetuAllMove, string hint) { /* * foreach(KeyValuePair<Finger, List<ShootingStarlightable>> komaAllMove in komabetuAllMove.Items) * { * foreach(ShootingStarlightable move in komaAllMove.Value) * { * Starlightable lightable = move.Now; * RO_Star_Koma koma = Util_Koma.AsKoma(lightable); * * if (KomaSyurui14Array.IsNari(koma.Syurui)) * { * MessageBox.Show("指し手に成りが含まれています。[" + koma.Masu.Word + "][" + koma.Syurui + "]", "デバッグ:" + hint); * //System.Console.WriteLine("指し手に成りが含まれています。"); * goto gt_EndMethod; * } * } * } * gt_EndMethod: * ; */ }
/// <summary> /// これが通称【水際のいんちきプログラム】なんだぜ☆ /// 必要により、【成り】の指し手を追加します。 /// </summary> private static void AddKomaBETUAllNariMoves( Maps_OneAndMulti <Finger, ShootingStarlightable> komaBETUAllMoves, Finger figKoma, RO_Star_Koma srcKoma, RO_Star_Koma dstKoma ) { bool isPromotionable; if (!Converter04.IsPromotionable(out isPromotionable, srcKoma, dstKoma)) { goto gt_EndMethod; } // 成りの資格があれば、成りの指し手を作ります。 if (isPromotionable) { //MessageBox.Show("成りの資格がある駒がありました。 src=["+srcKoma.Masu.Word+"]["+srcKoma.Syurui+"]"); ShootingStarlightable move = new RO_ShootingStarlight( //figKoma,//駒 srcKoma,// 移動元 new RO_Star_Koma( dstKoma.Pside, dstKoma.Masu, KomaSyurui14Array.ToNariCase(dstKoma.Syurui) //強制的に【成り】に駒の種類を変更 ), // 移動先 PieceType.None //取った駒不明 ); // TODO: 一段目の香車のように、既に駒は成っている場合があります。無い指し手だけ追加するようにします。 komaBETUAllMoves.AddNotOverwrite(figKoma, move); } gt_EndMethod: ; }
public Maps_OneAndMulti <T1, T2> ToClone() { Maps_OneAndMulti <T1, T2> map2 = new Maps_OneAndMulti <T1, T2>(); foreach (KeyValuePair <T1, List <T2> > entry1 in this.Items) { T1 key1 = entry1.Key; List <T2> values1 = entry1.Value; foreach (T2 value1 in values1) { if (map2.ContainsKey(key1)) { map2.AddExists(key1, value1); } else { map2.AddNew(key1, value1); } } } return(map2); }
/// <summary> /// 指定された手の中から、王手局面を除外します。 /// /// 王手回避漏れを防ぎたいんだぜ☆ /// </summary> /// <param name="km_available">自軍の各駒の移動できる升セット</param> /// <param name="sbGohosyu"></param> /// <param name="logTag"></param> public static KifuNode LA_RemoveMate( bool isHonshogi, Maps_OneAndMulti <Finger, ShootingStarlightable> genTeban_komabetuAllMove1, // 現手番の、どの駒が、どんな手を指すことができるか int yomuDeep, //脳内読み手数 int tesumi_yomiGenTeban, Playerside pside_yomiGenTeban, KifuNode siteiNode_yomiGenTeban, bool enableLog, GraphicalLog_File logF_kiki, string hint) { Node <ShootingStarlightable, KyokumenWrapper> hubNode = UtilKomabetuMove.ToNextNodes_AsHubNode( genTeban_komabetuAllMove1, siteiNode_yomiGenTeban, pside_yomiGenTeban ); // ハブ・ノード自身はダミーノードなんだが、子ノードに、次のノードが入っている。 Converter04.AssertNariMove(hubNode, "#LA_RemoveMate(1)"); //ここはok Util_LegalMove.Log1(hubNode, enableLog, tesumi_yomiGenTeban, hint); if (isHonshogi) { // 王手が掛かっている局面を除きます。 Util_LegalMove.LAA_RemoveNextNode_IfMate( hubNode, enableLog, yomuDeep, tesumi_yomiGenTeban, pside_yomiGenTeban, logF_kiki); } Converter04.AssertNariMove(hubNode, "#LA_RemoveMate(2)王手局面削除直後");//ここはok // 「指し手一覧」を、「駒別の全指し手」に分けます。 Maps_OneAndMulti <Finger, ShootingStarlightable> komabetuAllMoves2 = siteiNode_yomiGenTeban.SplitMoveByKoma(hubNode); Converter04.AssertNariMove(komabetuAllMoves2, "#LA_RemoveMate(3)更に変換後");//ここはok // // 「駒別の指し手一覧」を、「駒別の進むマス一覧」になるよう、データ構造を変換します。 // Maps_OneAndOne <Finger, SySet <SyElement> > komabetuSusumuMasus = new Maps_OneAndOne <Finger, SySet <SyElement> >();// 「どの駒を、どこに進める」の一覧 foreach (KeyValuePair <Finger, List <ShootingStarlightable> > entry in komabetuAllMoves2.Items) { Finger finger = entry.Key; List <ShootingStarlightable> teList = entry.Value; // ポテンシャル・ムーブを調べます。 SySet <SyElement> masus_PotentialMove = new SySet_Default <SyElement>("ポテンシャルムーブ"); foreach (ShootingStarlightable te in teList) { RO_Star_Koma koma = Util_Koma.AsKoma(te.Now); masus_PotentialMove.AddElement(koma.Masu); } if (!masus_PotentialMove.IsEmptySet()) { // 空でないなら Util_KomabetuMasus.AddOverwrite(komabetuSusumuMasus, finger, masus_PotentialMove); } } // まず、ディクショナリー構造へ変換。 Dictionary <ShootingStarlightable, KyokumenWrapper> movebetuSky = Converter04.KomabetuMasus_ToMovebetuSky( komabetuSusumuMasus, siteiNode_yomiGenTeban.Value.ToKyokumenConst, pside_yomiGenTeban); // 棋譜ノード構造へ変換。 return(Converter04.MovebetuSky_ToHubNode(movebetuSky, KifuNodeImpl.GetReverseTebanside(pside_yomiGenTeban))); }
/// <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); }