/// <summary> /// 棋譜ツリーのカレントを変更します。 /// </summary> /// <param name="isMakimodosi"></param> /// <param name="ittemodosuReference"></param> /// <param name="logTag"></param> public static void Before2( ref IttemodosuResult ittemodosuReference ) { Node <IMove, KyokumenWrapper> editNodeRef = ittemodosuReference.SyuryoNode_OrNull; IMove nextMove = editNodeRef.Key; if (ittemodosuReference.FoodKomaSyurui != PieceType.None) { // 元のキーの、取った駒の種類だけを差替えます。 nextMove = Util_Sky258A.BuildMove(editNodeRef.Key.LongTimeAgo, editNodeRef.Key.Now, ittemodosuReference.FoodKomaSyurui); // 現手番 Playerside genTebanside = ((KifuNode)editNodeRef).Value.KyokumenConst.KaisiPside; // キーを差替えたノード editNodeRef = new KifuNodeImpl(nextMove, new KyokumenWrapper(ittemodosuReference.Susunda_Sky_orNull));//, genTebanside } string nextMoveStr = ConvMoveStrSfen.ToMoveStrSfen(nextMove); ittemodosuReference.SyuryoNode_OrNull = editNodeRef;// この変数を返すのがポイント。棋譜とは別に、現局面。 //Util_IttesasuRoutine.iIttemodosuAfter3_ChangeCurrent(kifu_mutable); }
/// <summary> /// 変換:星別指し手一覧 → 次の局面の一覧をもった、入れ物ノード。 /// </summary> /// <param name="kifu"></param> /// <param name="pside_genTeban"></param> /// <returns>次の局面一覧を持った、入れ物ノード(ハブ・ノード)</returns> public static KifuNode ToNextNodes_AsHubNode( Maps_OneAndMulti <Finger, IMove> komabetuAllMove, SkyConst src_Sky//Node<Starbeamable, KyokumenWrapper> to_parentNode,//親となる予定のノード ) { KifuNode hubNode = new KifuNodeImpl(null, null);//蝶番 #if DEBUG string dump = komabetuAllMove.Dump(); #endif foreach (KeyValuePair <Finger, List <IMove> > entry1 in komabetuAllMove.Items) { Finger figKoma = entry1.Key; // 動かす駒 foreach (IMove move in entry1.Value) // 駒の動ける升 { string sfenText = ConvMoveStrSfen.ToMoveStrSfen(move); if (hubNode.ContainsKey_ChildNodes(sfenText)) { // 既存の指し手なら無視 Logger.Trace($"既存の指し手なので無視します1。sfenText=[{sfenText}]"); } else { // 指したあとの次の局面を作るだけ☆ hubNode.PutAdd_ChildNode(ConvMoveStrSfen.ToMoveStrSfen(move), new KifuNodeImpl(move, new KyokumenWrapper( Util_Sasu341.Sasu( src_Sky, // to_parentNode.Value.ToKyokumenConst,//指定局面 figKoma, //動かす駒 Util_Starlightable.AsKoma(move.Now).Masu, //移動先升 false //成りません。 )))); } } } return(hubNode); }
/// <summary> /// 棋譜データを元に、符号リスト1(*1)を出力します。 /// /// *1…「▲2六歩△8四歩▲7六歩」といった書き方。 /// /// /// FIXME: 将棋GUII には要るものの、将棋エンジンには要らないはず。 /// /// </summary> /// <param name="fugoList"></param> public static string ToJsaFugoListString( KifuTree src_kifu, string hint ) { StringBuilder sb = new StringBuilder(); sb.Append("position "); sb.Append(src_kifu.GetProperty(Word_KifuTree.PropName_Startpos)); sb.Append(" moves "); // 採譜用に、新しい対局を用意します。 KifuTree saifuKifu; { saifuKifu = new KifuTreeImpl( new KifuNodeImpl( Util_Sky258A.RootMove, new KyokumenWrapper(Util_SkyWriter.New_Hirate(Playerside.P1)) //日本の符号読取時 ) ); saifuKifu.Clear(); // 棋譜を空っぽにします。 saifuKifu.SetProperty(Word_KifuTree.PropName_Startpos, "startpos"); //平手の初期局面 // FIXME:平手とは限らないのでは? } src_kifu.ForeachHonpu(src_kifu.CurNode, (int temezumi, KyokumenWrapper kWrap, Node <IMove, KyokumenWrapper> node, ref bool toBreak) => { if (0 == temezumi) { // 初期局面はスキップします。 goto gt_EndLoop; } //------------------------------ // 符号の追加(記録係) //------------------------------ KyokumenWrapper saifu_kWrap = saifuKifu.CurNode.Value; // 採譜用新ノード KifuNode saifu_newChild = new KifuNodeImpl( node.Key, new KyokumenWrapper(SkyConst.NewInstance_ReversePside( saifu_kWrap.KyokumenConst, temezumi//FIXME:合ってるのかどうか。 )) ); // 記録係り用棋譜(採譜) UtilKifuTree282.AppendChild_And_ChangeCurrentToChild(saifuKifu, saifu_newChild, $"{hint}/ToJsaKifuText");// 新しい次ノードを追加。次ノードを、これからカレントとする。 // 後手の符号がまだ含まれていない。 string jsaFugoStr = ConvMoveStrJsa.ToMoveStrJsa(saifu_newChild //saifu_newChild.Value, ); //sb.Append(Conv_MoveStr_Jsa.ToMoveStr_Jsa(node, saifu_kWrap)); sb.Append(jsaFugoStr); gt_EndLoop: ; }); return(sb.ToString()); }
/// <summary> /// 一手指します。 /// </summary> /// <param name="ittesasuArg"></param> /// <param name="ittesasu_mutable"></param> /// <param name="ittesasuResult"></param> /// <param name="memberName"></param> /// <param name="sourceFilePath"></param> /// <param name="sourceLineNumber"></param> public static void Before1( IttesasuArg ittesasuArg, out IttesasuResult ittesasuResult, string hint , [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0 ) { //------------------------------ // 用意 //------------------------------ ittesasuResult = new IttesasuResultImpl(Fingers.Error_1, Fingers.Error_1, null, PieceType.None, null); SkyConst kaisi_Sky = ittesasuArg.KaisiKyokumen.KyokumenConst; // 一手指し開始局面(不変) Node <IMove, KyokumenWrapper> editNodeRef; // 編集対象ノード(巻き戻し時と、進む時で異なる) //------------------------------ // 符号(局面)の追加 //------------------------------ { //進むときは、必ずノードの追加と、カレントの移動がある。 //現局面ノードのクローンを作成します。 editNodeRef = new KifuNodeImpl(ittesasuArg.KorekaranoMove, new KyokumenWrapper( SkyConst.NewInstance_ReversePside(kaisi_Sky, ittesasuArg.KorekaranoTemezumi_orMinus1)) ); ittesasuResult.Susunda_Sky_orNull = editNodeRef.Value.KyokumenConst; } //------------------------------ // 動かす駒を移動先へ。 //------------------------------ Debug.Assert(null != ittesasuArg.KorekaranoMove, "これからの指し手がヌルでした。"); Finger figMovedKoma; Util_IttesasuRoutine.Do24_UgokasuKoma_IdoSakiHe( out figMovedKoma, ittesasuArg.KorekaranoMove, ittesasuArg.KaisiTebanside, kaisi_Sky, hint ); ittesasuResult.FigMovedKoma = figMovedKoma; //動かした駒更新 Debug.Assert(Fingers.Error_1 != ittesasuResult.FigMovedKoma, "動かした駒がない☆!?エラーだぜ☆!"); RO_Star korekaranoKoma = Util_Starlightable.AsKoma(ittesasuArg.KorekaranoMove.Now); IMoveHalf afterStar; { afterStar = Util_IttesasuRoutine.Do36_KomaOnDestinationMasu( korekaranoKoma.Komasyurui, ittesasuArg.KorekaranoMove, ittesasuResult.Susunda_Sky_orNull ); } // Sky 局面データは、この関数の途中で何回か変更されます。ローカル変数に退避しておくと、同期が取れなくなります。 //------------------------------------------------------------ // 駒を取る //------------------------------------------------------------ Finger figFoodKoma = Fingers.Error_1; RO_Star food_koma = null; Playerside food_pside = Playerside.Empty; SyElement food_akiMasu = Masu_Honshogi.Query_Basho(Masu_Honshogi.nError); { Util_IttesasuRoutine.Do61_KomaToru( afterStar, ittesasuResult.Susunda_Sky_orNull, out figFoodKoma, out food_koma, out food_pside, out food_akiMasu ); if (Fingers.Error_1 != figFoodKoma) { //>>>>> 指した先に駒があったなら ittesasuResult.FoodKomaSyurui = food_koma.Komasyurui; } else { ittesasuResult.FoodKomaSyurui = PieceType.None; } } Debug.Assert(figMovedKoma != Fingers.Error_1, "駒を動かせなかった?1"); if (Fingers.Error_1 != figFoodKoma) { //------------------------------------------------------------ // 指した駒と、取った駒の移動 //------------------------------------------------------------ //------------------------------ // 局面データの書き換え //------------------------------ ittesasuResult.Susunda_Sky_orNull = SkyConst.NewInstance_OverwriteOrAdd_Light( ittesasuResult.Susunda_Sky_orNull, ittesasuArg.KorekaranoTemezumi_orMinus1, // // 指した駒 // figMovedKoma, //指した駒番号 afterStar, //指した駒 // // 取った駒 // figFoodKoma, new RO_Starlight( new RO_Star( food_pside, food_akiMasu, //駒台の空きマスへ food_koma.ToNarazuCase() // 取られた駒の種類。表面を上に向ける。 ) ) ); } else { //------------------------------------------------------------ // 指した駒の移動 //------------------------------------------------------------ ittesasuResult.Susunda_Sky_orNull = SkyConst.NewInstance_OverwriteOrAdd_Light( ittesasuResult.Susunda_Sky_orNull, //駒を取って変化しているかもしれない? ittesasuArg.KorekaranoTemezumi_orMinus1, // これから作る局面の、手目済み。 // // 指した駒 // figMovedKoma, afterStar, // // 手得計算 // korekaranoKoma.Komasyurui, 0,// TODO: suji or index korekaranoKoma.Masu ); } editNodeRef.Value.SetKyokumen(ittesasuResult.Susunda_Sky_orNull); // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // この時点で、必ず現局面データに差替えあり // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // 局面データに変更があったものとして進めます。 // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ittesasuResult.FigFoodKoma = figFoodKoma; //取った駒更新 // // ノード ittesasuResult.Set_SyuryoNode_OrNull = editNodeRef;// この変数を返すのがポイント。棋譜とは別に、現局面。 }