/// <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="existsNode"></param> public void PutTuginoitte_Override( Node <IMove, KyokumenWrapper> existsNode ) { // SFENをキーに、次ノードを増やします。 this.NextNodes[ConvMoveStrSfen.ToMoveStrSfen(existsNode.Key)] = existsNode; existsNode.SetParentNode(this); }
/// <summary> /// ************************************************************************************************************************ /// SFEN符号表記。 /// ************************************************************************************************************************ /// /// ファイル名にも使えるように、ファイル名に使えない文字を置換します。 /// </summary> /// <returns></returns> public static string ToMoveStrSfenForFilename( IMove move, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0 ) { string moveText = ConvMoveStrSfen.ToMoveStrSfen(move); moveText = Conv_Filepath.ToEscape(moveText); return(moveText); }
//Dictionary<Starbeamable, KyokumenWrapper> public static Dictionary <string, SasuEntry> KomabetuMasusToMoveBetuSky( List_OneAndMulti <Finger, SySet <SyElement> > sMs, SkyConst src_Sky) { Dictionary <string, SasuEntry> moveBetuEntry = new Dictionary <string, SasuEntry>(); sMs.Foreach_Entry((Finger key, SySet <SyElement> value, ref bool toBreak) => { RO_Star koma = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(key).Now); foreach (SyElement dstMasu in value.Elements) { IMove move = Util_Sky258A.BuildMove( new RO_Star(src_Sky.KaisiPside, koma.Masu, koma.Haiyaku), new RO_Star(src_Sky.KaisiPside, dstMasu, koma.Haiyaku),//FIXME:配役は適当。 PieceType.None ); string moveStr = ConvMoveStrSfen.ToMoveStrSfen(move);//重複防止用のキー SasuEntry sasuEntry = new SasuEntry( move, key, //動かす駒 dstMasu, //移動先升 false //成りません。 ); if (!moveBetuEntry.ContainsKey(moveStr)) { moveBetuEntry.Add(moveStr, sasuEntry); } } }); return(moveBetuEntry); /* * Dictionary<Starbeamable, KyokumenWrapper> result = new Dictionary<Starbeamable, KyokumenWrapper>(); * foreach (KeyValuePair<string, SasuEntry> entry in movebetuEntry) * { * result.Add( * entry.Value.NewMove, * new KyokumenWrapper(Util_Sasu341.Sasu( * src_Sky,//指定局面 * entry.Value.Finger,//動かす駒 * entry.Value.Masu,//移動先升 * entry.Value.Naru,//成りません。 * logTag * ))); * } * * return result; */ }
/// <summary> /// ************************************************************************************************************************ /// SFEN符号表記。(取った駒付き) /// ************************************************************************************************************************ /// </summary> /// <returns></returns> public static string ToMoveStrSfenWithTottaKomasyurui(RO_Starbeam ss) { StringBuilder sb = new StringBuilder(); sb.Append(ConvMoveStrSfen.ToMoveStrSfen(ss)); if (PieceType.None != (PieceType)ss.FoodKomaSyurui) { sb.Append("("); sb.Append(ss.FoodKomaSyurui); sb.Append(")"); } return(sb.ToString()); }
/// <summary> /// 棋譜ツリーの、ノードに格納されている、局面評価明細を、出力していきます。 /// </summary> public static void AA_Write_ForeachLeafs_ForDebug( IEngineConf engineConf, ref int logFileCounter, string nodePath, KifuNode node, KifuTree kifu, string treeFolder, KyokumenPngEnvironment reportEnvironment ) { // 次ノードの有無 if (0 < node.Count_ChildNodes) { // 葉ノードではないなら int logFileCounter_temp = logFileCounter; // 先に奥の枝から。 node.Foreach_ChildNodes((string key, Node <IMove, KyokumenWrapper> nextNode, ref bool toBreak) => { float score = ((KifuNode)nextNode).Score; // 再帰 Util_KifuTreeLogWriter.AA_Write_ForeachLeafs_ForDebug( engineConf, ref logFileCounter_temp, $"{nodePath} {ConvMoveStrSfen.ToMoveStrSfenForFilename(nextNode.Key)}", (KifuNode)nextNode, kifu, $"{treeFolder}{(int)score}点_{ConvMoveStrSfen.ToMoveStrSfen(nextNode.Key)}/", reportEnvironment ); }); logFileCounter = logFileCounter_temp; } // 盤1個分の png 画像ログ出力 Util_KifuTreeLogWriter.AAA_Write_Node( engineConf, ref logFileCounter, nodePath, node, kifu, treeFolder, reportEnvironment ); }
/// <summary> /// 棋譜データを元に、符号リスト2(*1)を出力します。 /// /// *1…「position startpos moves 7g7f 3c3d 2g2f」といった書き方。 /// /// </summary> /// <param name="fugoList"></param> public static string ToSfen_PositionCommand(KifuTree src_kifu) { StringBuilder sb = new StringBuilder(); sb.Append("position "); sb.Append(src_kifu.GetProperty(Word_KifuTree.PropName_Startpos)); sb.Append(" moves "); // 本譜 int count = 0; src_kifu.ForeachHonpu(src_kifu.CurNode, (int temezumi, KyokumenWrapper kWrap, Node <IMove, KyokumenWrapper> node, ref bool toBreak) => { if (0 == temezumi) { // 初期局面はスキップします。 goto gt_EndLoop; } sb.Append(ConvMoveStrSfen.ToMoveStrSfen(node.Key)); //// TODO:デバッグ用 //switch (move.TottaKoma) //{ // case KomaSyurui.UNKNOWN: // case KomaSyurui.TOTTA_KOMA_NASI: // break; // default: // sb.Append("("); // sb.Append(Converter.SyuruiToSfen(move.Pside,move.TottaKoma)); // sb.Append(")"); // break; //} sb.Append(" "); gt_EndLoop: count++; }); return(sb.ToString()); }
/// <summary> /// ************************************************************************************************************************ /// 棋譜に 次の一手 を追加します。 /// ************************************************************************************************************************ /// /// KifuIO を通して使ってください。 /// /// ①コマ送り用。 /// ②「成り」フラグの更新用。 /// ③マウス操作用 /// /// カレントノードは変更しません。 /// </summary> public void PutTuginoitte_New( Node <IMove, KyokumenWrapper> newNode ) { // 同じ指し手があれば追加してはいけない? #if DEBUG string moveStr = ConvMoveStrSfen.ToMoveStrSfen(newNode.Key); System.Diagnostics.Debug.Assert( !this.HasTuginoitte(moveStr), $"指し手[{moveStr}]は既に指されていました。" ); #endif // SFENをキーに、次ノードを増やします。 this.PutAdd_ChildNode(ConvMoveStrSfen.ToMoveStrSfen(newNode.Key), newNode); //手番はここでは変更できない。 newNode.SetParentNode(this); }
/// <summary> /// 新しいノードを、次ノードとして追加します。 /// そして、追加した新しいノードを、カレント・ノードとします。 /// </summary> /// <param name="nextNode_and_nextCurrent"></param> public static void AppendChild_And_ChangeCurrentToChild( KifuTree kifuRef, KifuNode nextNode_and_nextCurrent, string hint ) { string moveStr = ConvMoveStrSfen.ToMoveStrSfen(nextNode_and_nextCurrent.Key); if (!((KifuNode)kifuRef.CurNode).HasTuginoitte(moveStr)) { //---------------------------------------- // 次ノート追加 //---------------------------------------- kifuRef.GetSennititeCounter().CountUp_New(Conv_Sky.ToKyokumenHash(nextNode_and_nextCurrent.Value.KyokumenConst), $"{hint}/AppendChild_And_ChangeCurrentToChild"); ((KifuNode)kifuRef.CurNode).PutTuginoitte_New(nextNode_and_nextCurrent); } kifuRef.SetCurNode(nextNode_and_nextCurrent);//次ノードを、これからのカレントとします。 Debug.Assert(kifuRef.CurNode != null, "カレントノードがヌル。"); }
public static Dictionary <string, SasuEntry> ToMoveBetuSky1( Maps_OneAndOne <Finger, SySet <SyElement> > komabetuSusumuMasus, SkyConst src_Sky ) { Dictionary <string, SasuEntry> result_komabetuEntry = new Dictionary <string, SasuEntry>(); komabetuSusumuMasus.Foreach_Entry((Finger key, SySet <SyElement> value, ref bool toBreak) => { RO_Star koma = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(key).Now); foreach (SyElement dstMasu in value.Elements) { IMove move = Util_Sky258A.BuildMove( //key, new RO_Star(src_Sky.KaisiPside, koma.Masu, koma.Haiyaku), new RO_Star(src_Sky.KaisiPside, dstMasu, koma.Haiyaku),//FIXME:配役は適当。 PieceType.None ); string moveStr = ConvMoveStrSfen.ToMoveStrSfen(move);//重複防止用のキー if (!result_komabetuEntry.ContainsKey(moveStr)) { result_komabetuEntry.Add( moveStr, new SasuEntry( move, key, //動かす駒 dstMasu, //移動先升 false //成りません ) ); } } }); return(result_komabetuEntry); }
/// <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> /// これが通称【水際のいんちきプログラム】なんだぜ☆ /// 必要により、【成り】の指し手を追加します。 /// </summary> public static Dictionary <string, SasuEntry> CreateNariMove( SkyConst src_Sky, Dictionary <string, SasuEntry> a_moveBetuEntry ) { //---------------------------------------- // 『進める駒』と、『移動先升』 //---------------------------------------- Dictionary <string, SasuEntry> result_komabetuEntry = new Dictionary <string, SasuEntry>(); try { Dictionary <string, IMove> newMoveList = new Dictionary <string, IMove>(); foreach (KeyValuePair <string, SasuEntry> entry in a_moveBetuEntry) { // // ・移動元の駒 // ・移動先の駒 // RO_Star srcKoma = Util_Starlightable.AsKoma(entry.Value.NewMove.LongTimeAgo); RO_Star dstKoma = Util_Starlightable.AsKoma(entry.Value.NewMove.Now); // 成りができる動きなら真。 bool isPromotionable; if (!Util_Sasu269.IsPromotionable(out isPromotionable, srcKoma, dstKoma)) { // エラー goto gt_Next1; } if (isPromotionable) { IMove move = new RO_Starbeam( srcKoma,// 移動元 new RO_Star( dstKoma.Pside, dstKoma.Masu, Util_Komasyurui14.ToNariCase(dstKoma.Komasyurui) //強制的に【成り】に駒の種類を変更 ), // 移動先 PieceType.None //取った駒不明 ); // TODO: 一段目の香車のように、既に駒は成っている場合があります。無い指し手だけ追加するようにします。 string moveStr = ConvMoveStrSfen.ToMoveStrSfen(move);//重複防止用のキー if (!newMoveList.ContainsKey(moveStr)) { newMoveList.Add(moveStr, move); } } gt_Next1: ; } //hubNode.Foreach_ChildNodes((string key, Node<Starbeamable, KyokumenWrapper> nextNode, ref bool toBreak) => //{ //}); // 新しく作った【成り】の指し手を追加します。 foreach (IMove newMove in newMoveList.Values) { // 指す前の駒 RO_Star sasumaenoKoma = Util_Starlightable.AsKoma(newMove.LongTimeAgo); // 指した駒 RO_Star sasitaKoma = Util_Starlightable.AsKoma(newMove.Now); // 指す前の駒を、盤上のマス目で指定 Finger figSasumaenoKoma = Util_Sky_FingersQuery.InMasuNow(src_Sky, sasumaenoKoma.Masu).ToFirst(); string moveStr = ConvMoveStrSfen.ToMoveStrSfen(newMove); if (!result_komabetuEntry.ContainsKey(moveStr)) { // 指し手が既存でない局面だけを追加します。 // 『進める駒』と、『移動先升』 result_komabetuEntry.Add(moveStr, new SasuEntry(newMove, figSasumaenoKoma, sasitaKoma.Masu, true)); } } } catch (Exception ex) { throw new Exception($"Convert04.cs#AddNariMoveでエラー。:{ex.GetType().Name}:{ex.Message}"); } return(result_komabetuEntry); }
/// <summary> /// 棋譜ツリー・ログの書出し /// /// TODO: フォルダーパスが長く成りすぎるのを、なんとかしたい。折り返すとか、~中略~にするとか、rootから始めないとか。 /// </summary> public static void A_Write_KifuTreeLog( KaisetuBoards logF_kiki, KifuTree kifu ) { #if DEBUG int logFileCounter = 0; //---------------------------------------- // 既存の棋譜ツリー・ログを空に。 //---------------------------------------- { string rootFolder = Path.Combine(Util_KifuTreeLogWriter.REPORT_ENVIRONMENT.OutFolder, ConvMoveStrSfen.KIFU_TREE_LOG_ROOT_FOLDER); if (Directory.Exists(rootFolder)) { try { Directory.Delete(rootFolder, true); } catch (IOException) { // ディレクトリーが空でなくて、ディレクトリーを削除できなかったときに // ここにくるが、 // ディレクトリーの中は空っぽにできていたりする。 // // とりあえず続行。 } } } //---------------------------------------- // カレントノードまでの符号を使って、フォルダーパスを作成。 //---------------------------------------- StringBuilder tree_folder = new StringBuilder(); kifu.ForeachHonpu(kifu.CurNode, (int temezumi2, KyokumenWrapper kWrap, Node <IMove, KyokumenWrapper> node, ref bool toBreak) => { tree_folder.Append($"{ConvMoveStrSfen.ToMoveStrSfenForFilename(node.Key)}/"); }); //sb_folder.Append( $"{Conv_MoveStr_Sfen.ToMoveStr_Sfen_ForFilename(kifu.CurNode.Key)}/"); string moveText1 = ConvMoveStrSfen.ToMoveStrSfen(kifu.CurNode.Key); KifuNode kifuNode1 = (KifuNode)kifu.CurNode; // 評価明細のログ出力。 Util_KifuTreeLogWriter.AA_Write_ForeachLeafs_ForDebug( ref logFileCounter, moveText1, kifuNode1, kifu, tree_folder.ToString(), Util_KifuTreeLogWriter.REPORT_ENVIRONMENT ); if (0 < logF_kiki.boards.Count) //ログが残っているなら { bool enableLog = true; // false; // // ログの書き出し // Util_GraphicalLog.WriteHtml5( enableLog, "#評価ログ", $"[{Conv_KaisetuBoards.ToJsonStr(logF_kiki)}]" ); // 書き出した分はクリアーします。 logF_kiki.boards.Clear(); } #endif }
/// <summary> /// 盤1個分のログ。 /// </summary> private static void AAA_Write_Node( IEngineConf engineConf, ref int logFileCounter, string nodePath, KifuNode node, KifuTree kifu, string relFolder, KyokumenPngEnvironment reportEnvironment ) { string fileName = ""; // 出力先 fileName = Conv_Filepath.ToEscape($"_log_{((int)node.Score)}点_{logFileCounter}_{nodePath}.png"); relFolder = Conv_Filepath.ToEscape(relFolder); // // 画像ログ // if (true) { int srcMasu_orMinusOne = -1; int dstMasu_orMinusOne = -1; if (null != node.Key) { srcMasu_orMinusOne = Conv_SyElement.ToMasuNumber(((RO_Star)node.Key.LongTimeAgo).Masu); dstMasu_orMinusOne = Conv_SyElement.ToMasuNumber(((RO_Star)node.Key.Now).Masu); } KyokumenPngArgs_FoodOrDropKoma foodKoma; if (null != node.Key.FoodKomaSyurui) { switch (Util_Komasyurui14.NarazuCaseHandle((PieceType)node.Key.FoodKomaSyurui)) { case PieceType.None: foodKoma = KyokumenPngArgs_FoodOrDropKoma.NONE; break; case PieceType.P: foodKoma = KyokumenPngArgs_FoodOrDropKoma.FU__; break; case PieceType.L: foodKoma = KyokumenPngArgs_FoodOrDropKoma.KYO_; break; case PieceType.N: foodKoma = KyokumenPngArgs_FoodOrDropKoma.KEI_; break; case PieceType.S: foodKoma = KyokumenPngArgs_FoodOrDropKoma.GIN_; break; case PieceType.G: foodKoma = KyokumenPngArgs_FoodOrDropKoma.KIN_; break; case PieceType.R: foodKoma = KyokumenPngArgs_FoodOrDropKoma.HI__; break; case PieceType.B: foodKoma = KyokumenPngArgs_FoodOrDropKoma.KAKU; break; default: foodKoma = KyokumenPngArgs_FoodOrDropKoma.UNKNOWN; break; } } else { foodKoma = KyokumenPngArgs_FoodOrDropKoma.NONE; } // 評価明細に添付 Util_KyokumenPng_Writer.Write1( Conv_KifuNode.ToRO_Kyokumen1(node), srcMasu_orMinusOne, dstMasu_orMinusOne, foodKoma, ConvMoveStrSfen.ToMoveStrSfen(node.Key), relFolder, fileName, reportEnvironment ); logFileCounter++; } // // 評価明細 // { Util_KifuTreeLogWriter.AAAA_Write_HyokaMeisai(engineConf, fileName, node, relFolder, reportEnvironment); } }
/// <summary> /// 『以前の変化カッター』 /// /// 本譜を残して、カレントノードより以前の変化は ツリーから削除します。 /// </summary> public static int IzennoHenkaCutter( KifuTree kifu_mutable ) { int result_removedCount = 0; //---------------------------------------- // 本譜以外の変化を削除します。 //---------------------------------------- if (kifu_mutable.CurNode.IsRoot()) { //---------------------------------------- // ルートノードでは何もできません。 //---------------------------------------- goto gt_EndMethod; } //---------------------------------------- // 本譜の手 //---------------------------------------- string moveStr = ConvMoveStrSfen.ToMoveStrSfen(kifu_mutable.CurNode.Key); //---------------------------------------- // 1手前の分岐点 //---------------------------------------- Node <IMove, KyokumenWrapper> parentNode = kifu_mutable.CurNode.GetParentNode(); //---------------------------------------- // 選ばなかった変化を、ここに入れます。 //---------------------------------------- List <string> removeeList = new List <string>(); //---------------------------------------- // 選んだ変化と、選ばなかった変化の一覧 //---------------------------------------- parentNode.Foreach_ChildNodes((string key1, Node <IMove, KyokumenWrapper> nextNode1, ref bool toBreak1) => { if (key1 == moveStr) { //---------------------------------------- // 本譜の手はスキップ //---------------------------------------- //Logger.Trace($"残すmoveStr=[{moveStr}] key1=[{key1}] ★"); goto gt_Next1; } //else //{ // Logger.Trace($"残すmoveStr=[{moveStr}] key1=[{key1}]"); //} //---------------------------------------- // 選ばなかった変化をピックアップ //---------------------------------------- removeeList.Add(key1); gt_Next1: ; }); //---------------------------------------- // どんどん削除 //---------------------------------------- result_removedCount = removeeList.Count; foreach (string key in removeeList) { parentNode.RemoveChild(key); } gt_EndMethod: return(result_removedCount); }
public string Execute( ref KifuParserA_Result result, Model_Taikyoku model_Taikyoku, out KifuParserA_State nextState, KifuParserA owner, KifuParserA_Genjo genjo ) { // 現局面。 SkyConst src_Sky = model_Taikyoku.Kifu.CurNode.Value.KyokumenConst; // Debug.Assert(!Util_MasuNum.OnKomabukuro((int)((RO_Star_Koma)src_Sky.StarlightIndexOf((Finger)0).Now).Masu), "カレント、駒が駒袋にあった。"); bool isHonshogi = true;//FIXME:暫定 // 現在の手番の開始局面+1 int korekaranoTemezumi = src_Sky.Temezumi + 1; nextState = this; if (0 < genjo.InputLine.Trim().Length) { IMove nextTe = Util_Sky258A.NullObjectMove; string rest; //「6g6f」形式と想定して、1手だけ読込み string str1; string str2; string str3; string str4; string str5; string str6; string str7; string str8; string str9; if (SfenMovesTextConv.ToTokens( genjo.InputLine, out str1, out str2, out str3, out str4, out str5, out rest) && !(str1 == "" && str2 == "" && str3 == "" && str4 == "" && str5 == "") ) { ConvSfenMoveTokens.ToMove( isHonshogi, str1, //123456789 か、 PLNSGKRB str2, //abcdefghi か、 * str3, //123456789 str4, //abcdefghi str5, //+ out nextTe, model_Taikyoku.Kifu, "棋譜パーサーA_SFENパース1" ); } else { //>>>>> 「6g6f」形式ではなかった☆ //「▲6六歩」形式と想定して、1手だけ読込み if (Conv_JsaFugoText.ToTokens( genjo.InputLine, out str1, out str2, out str3, out str4, out str5, out str6, out str7, out str8, out str9, out rest, model_Taikyoku.Kifu)) { if (!(str1 == "" && str2 == "" && str3 == "" && str4 == "" && str5 == "" && str6 == "" && str7 == "" && str8 == "" && str9 == "")) { Conv_JsaFugoTokens.ToMove( str1, //▲△ str2, //123…9、123…9、一二三…九 str3, //123…9、123…9、一二三…九 str4, // “同” str5, //(歩|香|桂|… str6, // 右|左… str7, // 上|引 str8, //成|不成 str9, //打 out nextTe, model_Taikyoku.Kifu ); } } else { //「6g6f」形式でもなかった☆ Logger.Error($"(^△^)「{genjo.InputLine}」vs【{this.GetType().Name}】 : !? 次の一手が読めない☆ inputLine=[{genjo.InputLine}]"); genjo.ToBreak_Abnormal(); goto gt_EndMethod; } } genjo.InputLine = rest; if (null != nextTe) { IttesasuResult ittesasuResult = new IttesasuResultImpl(Fingers.Error_1, Fingers.Error_1, null, PieceType.None, null); // //FIXME: これが悪さをしていないか☆? //FIXME: スピードが必要なので省略。 //Application.DoEvents(); // 時間のかかる処理の間にはこれを挟みます。 // //------------------------------ // ★棋譜読込専用 駒移動 //------------------------------ //Logger.Trace($"一手指し開始 : 残りの符号つ「{genjo.InputLine}」"); // //↓↓将棋エンジンが一手指し(進める) // Util_IttesasuRoutine.Before1( new IttesasuArgImpl( model_Taikyoku.Kifu.CurNode.Value, src_Sky.KaisiPside, nextTe, //FIXME: if文で分けているので、これがヌルなはずはないと思うが。 korekaranoTemezumi //これから作る局面の、手目済み。 ), out ittesasuResult, "KifuParserA_StateA2_SfenMoves#Execute" ); Util_IttesasuRoutine.Before2( ref ittesasuResult ); //---------------------------------------- // 次ノード追加、次ノードをカレントに。 //---------------------------------------- Util_IttesasuRoutine.After3_ChangeCurrent( model_Taikyoku.Kifu, ConvMoveStrSfen.ToMoveStrSfen(ittesasuResult.Get_SyuryoNode_OrNull.Key), ittesasuResult.Get_SyuryoNode_OrNull ); result.Out_newNode_OrNull = ittesasuResult.Get_SyuryoNode_OrNull; //↑↑一手指し //exceptionArea = 1090; //Logger.Trace(Util_Sky307.Json_1Sky( // src_Sky, // "一手指し終了", // "SFENパース2", // src_Sky.Temezumi//読み進めている現在の手目 // )); } else { genjo.ToBreak_Abnormal(); throw new Exception($"\(^o^)/Moveオブジェクトがない☆! inputLine=[{genjo.InputLine}]"); } } else { //Logger.Trace($"(^△^)現局面まで進んだのかだぜ☆?\n{Util_Sky307.Json_1Sky( // src_Sky, // "棋譜パース", // "SFENパース3", // src_Sky.Temezumi//読み進めている現在の手目 // )}"); genjo.ToBreak_Normal();//棋譜パーサーAの、唯一の正常終了のしかた。 } gt_EndMethod: return(genjo.InputLine); }