/// <summary> /// 棋譜ツリーのカレントを変更します。 /// </summary> /// <param name="kifu_mutable"></param> /// <param name="nextMoveStr"></param> /// <param name="edit_childNode_Ref"></param> public static void After3_ChangeCurrent( KifuTree kifu_mutable, string nextMoveStr, Node <IMove, KyokumenWrapper> edit_childNode_Ref ) { if (!((KifuNode)kifu_mutable.CurNode).HasTuginoitte(nextMoveStr)) { //---------------------------------------- // 次ノード追加(なければ) //---------------------------------------- kifu_mutable.GetSennititeCounter().CountUp_New(Conv_Sky.ToKyokumenHash(edit_childNode_Ref.Value.KyokumenConst), "After3_ChangeCurrent(次の一手なし)"); ((KifuNode)kifu_mutable.CurNode).PutTuginoitte_New(edit_childNode_Ref);//次ノートを追加します。 } else { //---------------------------------------- // 次ノード上書き(あれば) //---------------------------------------- kifu_mutable.GetSennititeCounter().CountUp_New(Conv_Sky.ToKyokumenHash(edit_childNode_Ref.Value.KyokumenConst), "After3_ChangeCurrent(次の一手あり)"); ((KifuNode)kifu_mutable.CurNode).PutTuginoitte_Override(edit_childNode_Ref);//次ノートを上書きします。 } Node <IMove, KyokumenWrapper> temp = kifu_mutable.CurNode; kifu_mutable.SetCurNode(edit_childNode_Ref);//次ノードを、これからのカレントとします。 edit_childNode_Ref.SetParentNode(temp); }
/// <summary> /// ************************************************************************************************************************ /// 手番が替わったときの挙動を、ここに書きます。 /// ************************************************************************************************************************ /// </summary> public void OnChangedTurn(KifuTree kifu) { if (!this.ShogiEngineProcessWrapper.IsLive_ShogiEngine()) { goto gt_EndMethod; } // FIXME: Playerside pside = kifu.CurNode.Value.KyokumenConst.KaisiPside; switch (pside) { case Playerside.P2: // 仮に、コンピューターが後手番とします。 //------------------------------------------------------------ // とりあえず、コンピューターが後手ということにしておきます。 //------------------------------------------------------------ // 例:「position startpos moves 7g7f」 this.ShogiEngineProcessWrapper.Send_Position(Util_KirokuGakari.ToSfen_PositionCommand(kifu)); this.ShogiEngineProcessWrapper.Send_Go(); break; default: break; } gt_EndMethod: ; }
public GameViewModel() { // // 駒なし // this.guiSky = Util_Sky.New_Komabukuro();// 描画モデル作成時 this.GuiTesumi = 0; this.GuiPside = Playerside.P1; // // // this.kifu = new KifuTreeImpl( new KifuNodeImpl( Util_Sky.NullObjectMove, new KyokumenWrapper(new SkyConst(this.guiSky)), Playerside.P2 ) ); this.Init(); }
/// <summary> /// 手番が替わったときの挙動を、ここに書きます。 /// </summary> public void ChangeTurn99(KifuTree kifu) { if (!this.ShogiEngineManInterface.IsLive()) { goto gt_EndMethod; } // FIXME: switch (kifu.CountPside(KifuNarabe_KifuWrapper.CountCurTesumi1(kifu))) { case Playerside.P2: // 仮に、コンピューターが後手番とします。 //------------------------------------------------------------ // とりあえず、コンピューターが後手ということにしておきます。 //------------------------------------------------------------ // 例:「position startpos moves 7g7f」 this.ShogiEngineManInterface.Position(KirokuGakari.ToSfen_PositionString(kifu)); this.ShogiEngineManInterface.Go(); break; default: break; } gt_EndMethod: ; }
/// <summary> /// 一手指します。または、一手戻します。 /// </summary> /// <param name="move"></param> /// <param name="kifu"></param> /// <param name="isMakimodosi"></param> /// <param name="figMovedKoma"></param> /// <param name="figFoodKoma">取られた駒</param> /// <param name="out_newNode_OrNull"></param> /// <param name="memberName"></param> /// <param name="sourceFilePath"></param> /// <param name="sourceLineNumber"></param> public static void Ittesasi( ShootingStarlightable move, KifuTree kifu, bool isMakimodosi, out Finger figMovedKoma, out Finger figFoodKoma, out Node <ShootingStarlightable, KyokumenWrapper> out_newNode_OrNull , [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0 ) { out_newNode_OrNull = null; figFoodKoma = Fingers.Error_1; KifuIO.Kifusasi25( out figMovedKoma, move, kifu, isMakimodosi ); if (Fingers.Error_1 == figMovedKoma) { goto gt_EndMethod; } PieceType syurui2 = KifuIO.Kifusasi30_Naru(move, isMakimodosi); Starlight dst = KifuIO.Kifusasi35_NextMasu(syurui2, move, kifu, isMakimodosi); KifuIO.Kifusasi52_WhenKifuRead( dst, syurui2, ref figMovedKoma, out figFoodKoma, move, kifu, isMakimodosi, out out_newNode_OrNull ); gt_EndMethod: if (isMakimodosi) { Node <ShootingStarlightable, KyokumenWrapper> removedLeaf = kifu.PopCurrentNode(); } Logger.Trace("一手指しが終わったぜ☆ ノードが追加されているんじゃないか☆? "); }
/// <summary> /// 盤1個分のログ。 /// </summary> private void Log_Board( IEngineConf engineConf, string nodePath, KifuNode node, KifuTree kifu, string logDirectory, ReportEnvironment reportEnvironment ) { // 出力先 string basename = $"#{((int)node.KyHyoka.Total())}点_{KyHyokaWriterImpl.logFileCounter}_{nodePath}.log.png"; // TODO // // 画像ログ // if (true) { //SFEN文字列と、出力ファイル名を指定することで、局面の画像ログを出力します。 KyokumenPngWriterImpl.Write1( engineConf, node.ToRO_Kyokumen1(), Path.Combine(logDirectory, basename), reportEnvironment ); KyHyokaWriterImpl.logFileCounter++; } // // スコア明細 // { KyHyokaListWriterImpl.Write(basename, node, logDirectory, reportEnvironment); } }
/* * /// <summary> * /// 取った駒を差替えます。 * /// * /// 棋譜読取時用です。マウス操作時は、流れが異なるので使えません。 * /// </summary> * public static void AppendChildB_Swap( * Komasyurui14 tottaSyurui, * SkyConst src_Sky, * KifuTree kifu282, * out Node<ShootingStarlightable, KyokumenWrapper> out_swapedNode, * string hint, * IErrorController logTag * ) * { * out_swapedNode = null; * * if (kifu282.CurNode.IsRoot()) * { * // ルート・ノードなら * goto gt_EndMethod; * // 子要素をスワップするためには親要素が必要だが、ルートには親ノードがないので、このあとの操作はできません。 * } * * if (null == src_Sky) * { * throw new Exception("ノードを追加しようとしましたが、指定されたnewSkyがヌルです。"); * } * * // 現手番 * Playerside genTebanside = ((KifuNode)kifu282.CurNode).Tebanside; * // 現ノード削除。元のキーは退避。 * ShootingStarlightable motoKey = (ShootingStarlightable)kifu282.PopCurrentNode().Key; * * // 元のキーの、取った駒の種類だけを差替えます。 * RO_ShootingStarlight swapedMove = Util_Sky258A.BuildMove(motoKey.LongTimeAgo, motoKey.Now, tottaSyurui); * * // キーを差替えたノード * out_swapedNode = new KifuNodeImpl(swapedMove, new KyokumenWrapper(src_Sky), genTebanside); * * System.Diagnostics.Debug.Assert(!kifu282.CurNode.ContainsKey_ChildNodes(Util_Sky278.TranslateMove_StarlightToText(out_swapedNode.Key))); * * * // さきほど カレントノードを削除したので、 * // 今、カレントノードは、1つ前のノードになっています。 * // ここに、差替えたノードを追加します。 * kifu282.CurNode.Add_ChildNode(Util_Sky278.TranslateMove_StarlightToText(out_swapedNode.Key), out_swapedNode); * out_swapedNode.ParentNode = kifu282.CurNode; * * Logger.Trace($"リンクトリストの、最終ノードは差し替えられた hint=[{hint}] item=[{Util_Sky278.TranslateMove_StarlightToText(swapedMove)}]"); * // memberName=[{memberName}"] sourceFilePath=[{sourceFilePath}] sourceLineNumber=[{sourceLineNumber}] * * gt_EndMethod: * ; * } */ /// <summary> /// [ここから採譜]機能 /// </summary> public static void SetStartpos_KokokaraSaifu(KifuTree kifu, Playerside pside) { //------------------------------------------------------------ // 棋譜を空に //------------------------------------------------------------ kifu.Clear(); kifu.SetProperty(Word_KifuTree.PropName_Startpos, Conv_KifuNode.ToSfenstring((KifuNode)kifu.CurNode, pside)); }
public static void After3_ChangeCurrent( KifuTree kifu_mutable ) { //------------------------------------------------------------ // 取った駒を戻す //------------------------------------------------------------ Node <IMove, KyokumenWrapper> removedLeaf = kifu_mutable.PopCurrentNode(); }
/// <summary> /// 読む。 /// /// 棋譜ツリーを作成します。 /// </summary> /// <param name="kifu">この棋譜ツリーの現局面に、次局面をぶら下げて行きます。</param> /// <param name="enableLog"></param> /// <param name="isHonshogi"></param> /// <param name="logTag"></param> /// <returns></returns> public void WAA_Yomu_Start( KifuTree kifu, bool isHonshogi, Mode_Tansaku mode_Tansaku, float alphabeta_otherBranchDecidedValue, EvaluationArgs args ) { }
/// <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> /// 棋譜ツリーの、ノードに格納されている、局面評価明細を、出力していきます。 /// </summary> public void Write_ForeachLeafs( IEngineConf engine, string nodePath, KifuNode node, KifuTree kifu, PlayerInfo playerInfo, string relFolder, ReportEnvironment reportEnvironment ) { // 次ノードの有無 if (0 < node.Count_NextNodes) { // 先に奥の枝から。 node.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) => { double score = ((KifuNode)nextNode).KyHyoka.Total(); this.Write_ForeachLeafs( engine, nodePath + " " + Util_Sky.ToSfenMoveTextForFilename(nextNode.Key), (KifuNode)nextNode, kifu, playerInfo, relFolder + ((int)score).ToString() + "点_" + Util_Sky.ToSfenMoveText(nextNode.Key) + "/", //relFolder + ((int)((KifuNode)nextNode).KyHyoka.Total()).ToString() + "点_" + Util_Sky.ToSfenMoveText(nextNode.Key) + "/", reportEnvironment ); }); } // このノード // // 盤1個分のログの準備 // this.Log_Board( engine, nodePath, node, kifu, relFolder, 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> /// 盤1個分のログ。 /// </summary> private void Log_Board( string nodePath, KifuNode node, KifuTree kifu, ReportEnvironment reportEnvironment, GraphicalLog_File logF_kiki ) { // // HTMLログ // if (logF_kiki.boards.Count < 30)//出力件数制限 { GraphicalLog_Board logBrd_move1 = new GraphicalLog_Board(); List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus; Util_MovableMove.LA_Get_KomaBETUSusumeruMasus( out komaBETUSusumeruMasus, new MmGenjo_MovableMasuImpl( true, //本将棋 node.Value.ToKyokumenConst, //現在の局面 kifu.CountPside(node), false ), new MmLogGenjoImpl( false, //ログなし logBrd_move1, 0, //読みの深さ 0, //現在の手済み node.Key ) ); logBrd_move1.moveOrNull = ((KifuNode)node).Key; logBrd_move1.NounaiYomiDeep = int.MinValue; logBrd_move1.Tesumi = int.MinValue; logBrd_move1.Score = (int)node.KyHyoka.Total(); logF_kiki.boards.Add(logBrd_move1); } }
/// <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, "カレントノードがヌル。"); }
/// <summary> /// 棋譜データを元に、符号リスト2(*1)を出力します。 /// /// *1…「position startpos moves 7g7f 3c3d 2g2f」といった書き方。 /// /// </summary> /// <param name="fugoList"></param> public static string ToSfen_PositionString(KifuTree kifu) { StringBuilder sb = new StringBuilder(); sb.Append("position "); sb.Append(kifu.GetProperty(KifuTreeImpl.PropName_Startpos)); sb.Append(" moves "); int count = 0; kifu.ForeachHonpu(kifu.CurNode, (int tesumi, KyokumenWrapper kWrap, Node <ShootingStarlightable, KyokumenWrapper> node6, ref bool toBreak) => { if (0 == tesumi) { goto gt_EndLoop; } sb.Append(Util_Sky.ToSfenMoveText(node6.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> /// 棋譜ツリーを、平手初期局面 で準備します。 /// </summary> public static void CreateKifuTree(out KifuTree kifu) { // 初期局面では、Player 1 の手番とします。 Playerside firstPside = Playerside.P1; // 棋譜 kifu = new KifuTreeImpl( new KifuNodeImpl( Util_Sky258A.RootMove, new KyokumenWrapper(SkyConst.NewInstance( Util_SkyWriter.New_Hirate(firstPside), 0//初期局面なので、0手目済み。 )) ) ); kifu.SetProperty(Word_KifuTree.PropName_Startpos, "startpos");// 平手 Debug.Assert(!Conv_MasuHandle.OnKomabukuro( Conv_SyElement.ToMasuNumber(((RO_Star)kifu.CurNode.Value.KyokumenConst.StarlightIndexOf((Finger)0).Now).Masu) ), "駒が駒袋にあった。"); }
/// <summary> /// たった1つの指し手(ベストムーブ)を選びます。 /// </summary> /// <param name="kifu">ツリー構造になっている棋譜</param> /// <param name="logTag">ログ</param> /// <returns></returns> public ShootingStarlightable ChoiceBestMove( KifuTree kifu, bool enableLog, bool isHonshogi) { ShootingStarlightable bestMove = null; // これから調べる局面(next=現局面) Playerside pside_yomiNext = kifu.CountPside(kifu.CurNode); { // 次のノードをリストにします。 List <Node <ShootingStarlightable, KyokumenWrapper> > nextNodes = Converter04.NextNodes_ToList(kifu.CurNode); // 次のノードをシャッフルします。 List <Node <ShootingStarlightable, KyokumenWrapper> > nextNodes_shuffled = Converter04.NextNodes_ToList(kifu.CurNode); LarabeShuffle <Node <ShootingStarlightable, KyokumenWrapper> > .Shuffle_FisherYates(ref nextNodes_shuffled); // シャッフルした最初の指し手を選びます。 if (0 < nextNodes_shuffled.Count) { bestMove = nextNodes_shuffled[0].Key; } // ③ランダムに1手選ぶ //bestMove = Program.SikouEngine.ErabuRoutine.ChoiceMove_fromNextNodes_Random(kifu, node_yomiNext); } if (null == bestMove) { // 投了 bestMove = Util_Sky.NullObjectMove; } // TODO: できれば、合法手のリストから さらに相手番の合法手のリストを伸ばして、 // 1手先、2手先……の局面を ツリー構造(GameViewModel.Kifu)に蓄えたあと、 // 末端の局面に評価値を付けて、ミニマックス原理を使って最善手を絞り込みたい☆ return(bestMove); }
/// <summary> /// 同点決勝。 /// /// 評価値が同点のノード(指し手)の中で、ランダムに1つ選びます。 /// </summary> /// <param name="kifu">ツリー構造になっている棋譜</param> /// <returns></returns> public KifuNode ChoiceNode_DoutenKessyou( KifuTree kifu, bool isHonshogi) { KifuNode bestKifuNode = null; { // 次のノードをリストにします。 //List<KifuNode> nextNodes = Util_Converter280.NextNodes_ToList(kifu.CurNode); // 次のノードをシャッフル済みリストにします。 List <KifuNode> nextNodes_shuffled = Conv_NextNodes.ToList(kifu.CurNode); LarabeShuffle <KifuNode> .Shuffle_FisherYates(ref nextNodes_shuffled); // シャッフルした最初のノードを選びます。 if (0 < nextNodes_shuffled.Count) { bestKifuNode = nextNodes_shuffled[0]; } } return(bestKifuNode); }
/// <summary> /// 将棋盤上での検索 /// </summary> /// <param name="srcAll">候補マス</param> /// <param name="komas"></param> /// <returns></returns> public static bool Hit_JfugoParser( Playerside pside, PieceType syurui, SySet <SyElement> srcAll, KifuTree kifu, out Finger foundKoma) { SkyConst src_Sky = kifu.CurNode.Value.ToKyokumenConst; bool hit = false; foundKoma = Fingers.Error_1; foreach (Basho masu1 in srcAll.Elements)//筋・段。(先後、種類は入っていません) { foreach (Finger koma1 in Finger_Honshogi.Items_KomaOnly) { RO_Star_Koma koma2 = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(koma1).Now); if (pside == koma2.Pside && Okiba.ShogiBan == Util_Masu.GetOkiba(koma2.Masu) && KomaSyurui14Array.Matches(syurui, Haiyaku184Array.Syurui(koma2.Haiyaku)) && masu1 == koma2.Masu ) { // 候補マスにいた //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hit = true; foundKoma = koma1; break; } } } return(hit); }
public void SetKifu(KifuTree kifu) { this.kifu = kifu; }
public Model_TaikyokuImpl(KifuTree kifu) { this.kifu = kifu; }
/// <summary> /// 棋譜ツリーの、ノードのネクストノードに、点数を付けていきます。 /// </summary> public void Tensuduke_ForeachLeafs( string nodePath, KifuNode node, KifuTree kifu, Kokoro kokoro, PlayerInfo playerInfo, ReportEnvironment reportEnvironment,//MinimaxEngineImpl.REPORT_ENVIRONMENT GraphicalLog_File logF_kiki ) { // 次ノードの有無 if (node.Count_NextNodes < 1) { // 次ノードが無ければ、このノードが、葉です。 // 点数を付けます。 // 局面スコア node.KyHyoka.Clear(); // 妄想と、指定のノードを比較し、点数付けします。 foreach (Tenonagare nagare in kokoro.TenonagareItems) { node.KyHyoka.Add( nagare.Name.ToString(), this.hyokaEngineImpl.LetHandan(nagare, node, playerInfo) ); } #if DEBUG // // 盤1個分のログの準備 // this.Log_Board( nodePath, node, kifu, reportEnvironment, logF_kiki ); #endif } else { node.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) => { this.Tensuduke_ForeachLeafs( nodePath + " " + Util_Sky.ToSfenMoveText(nextNode.Key), (KifuNode)nextNode, kifu, kokoro, playerInfo, reportEnvironment, logF_kiki ); }); // このノードが、自分の手番かどうか。 bool jibun = playerInfo.Playerside == kifu.CountPside(node); if (jibun) { // 自分のノードの場合、次ノードの中で一番点数の高いもの。 double maxScore = double.MinValue; node.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) => { double score = ((KifuNode)nextNode).KyHyoka.Total(); if (maxScore < score) { maxScore = score; } }); node.SetBranchKyHyoka(new KyHyokaImpl(maxScore)); } else { // 相手のノードの場合、次ノードの中で一番点数の低いもの。 double minScore = double.MaxValue; node.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) => { double score = ((KifuNode)nextNode).KyHyoka.Total(); if (score < minScore) { minScore = score; } }); node.SetBranchKyHyoka(new KyHyokaImpl(minScore)); } } }
/// <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> /// 次の1手データを作ります(*1) /// /// *1…符号1「▲68銀上」を元に、「7968」を作ります。 /// /// <[再生]、[コマ送り]で呼び出されます> /// </summary> /// <returns></returns> public static void ExecuteJfugo_FromTextSub( string strPside, //▲△ string strSuji, //123…9、123…9、一二三…九 string strDan, //123…9、123…9、一二三…九 string strDou, // “同” string strSrcSyurui, //(歩|香|桂|… string strMigiHidari, // 右|左… string strAgaruHiku, // 上|引 string strNariNarazu, //成|不成 string strDaHyoji, //打 out ShootingStarlightable move, KifuTree kifu ) { Node <ShootingStarlightable, KyokumenWrapper> siteiNode = kifu.CurNode; SkyConst src_Sky = siteiNode.Value.ToKyokumenConst; //------------------------------ // 符号確定 //------------------------------ MigiHidari migiHidari = Converter04.Str_ToMigiHidari(strMigiHidari); AgaruHiku agaruHiku = Converter04.Str_ToAgaruHiku(strAgaruHiku); // 上|引 NariNarazu nariNarazu = Converter04.Nari_ToBool(strNariNarazu); //成 DaHyoji daHyoji = Converter04.Str_ToDaHyoji(strDaHyoji); //打 PieceType srcSyurui = Converter04.Str_ToSyurui(strSrcSyurui); //------------------------------ // //------------------------------ Playerside pside = Converter04.Pside_ToEnum(strPside); SyElement dstMasu; if ("同" == strDou) { // 1手前の筋、段を求めるのに使います。 RO_Star_Koma koma = Util_Koma.AsKoma(siteiNode.Key.Now); dstMasu = koma.Masu; } else { dstMasu = Util_Masu.OkibaSujiDanToMasu( Okiba.ShogiBan, ConverterKnSh.Suji_ToInt(strSuji), ConverterKnSh.Suji_ToInt(strDan) ); } // TODO: 駒台にあるかもしれない。 Okiba srcOkiba1 = Okiba.ShogiBan; //Okiba.FUMEI_FUGO_YOMI_CHOKUGO;// Okiba.SHOGIBAN; if (DaHyoji.Visible == daHyoji) { if (Playerside.P2 == pside) { srcOkiba1 = Okiba.Gote_Komadai; } else { srcOkiba1 = Okiba.Sente_Komadai; } } // SyElement dst1 = dstMasu; Finger foundKoma = Fingers.Error_1; //---------- // 駒台の駒を(明示的に)打つなら //---------- bool utsu = false;//駒台の駒を打つなら真 if (DaHyoji.Visible == daHyoji) { utsu = true; goto gt_EndShogiban; } if (PieceType.P == srcSyurui) { //************************************************************ // 歩 //************************************************************ //---------- // 候補マス //---------- //┌─┬─┬─┐ //│ │ │ │ //├─┼─┼─┤ //│ │至│ │ //├─┼─┼─┤ //│ │E│ │ //└─┴─┴─┘ bool isE = true; SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } } else if (PieceType.R == srcSyurui) { #region 飛 //************************************************************ // 飛 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ // │ │ │ │ │ │ │ │ │A7│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A6│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A5│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A4│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A3│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A2│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A1│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A0│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │G7│G6│G5│G4│G3│G2│G1│G0│至│C0│C1│C2│C3│C4│C5│C6│C7│ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E0│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E1│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E2│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E3│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E4│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E5│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E6│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E7│ │ │ │ │ │ │ │ │ // └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ bool isA = true; bool isC = true; bool isE = true; bool isG = true; switch (agaruHiku) { case AgaruHiku.Yoru: isA = false; isE = false; break; case AgaruHiku.Agaru: isA = false; isC = false; isG = false; break; case AgaruHiku.Hiku: isC = false; isE = false; isG = false; break; } switch (migiHidari) { case MigiHidari.Migi: isA = false; isE = false; isG = false; break; case MigiHidari.Hidari: isA = false; isC = false; isE = false; break; case MigiHidari.Sugu: isA = false; isC = false; isG = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻上(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻射(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻引(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻滑(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.B == srcSyurui) { #region 角 //************************************************************ // 角 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ // │H7│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │B7│ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │H6│ │ │ │ │ │ │ │ │ │ │ │ │ │B6│ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │H5│ │ │ │ │ │ │ │ │ │ │ │B5│ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │H4│ │ │ │ │ │ │ │ │ │B4│ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │H3│ │ │ │ │ │ │ │B3│ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │H2│ │ │ │ │ │B2│ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │H1│ │ │ │B1│ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │H0│ │B0│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │至│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │F0│ │D0│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │F1│ │ │ │D1│ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │F2│ │ │ │ │ │D2│ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │F3│ │ │ │ │ │ │ │D3│ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │F4│ │ │ │ │ │ │ │ │ │D4│ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │F5│ │ │ │ │ │ │ │ │ │ │ │D5│ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │F6│ │ │ │ │ │ │ │ │ │ │ │ │ │D6│ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │F7│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │D7│ // └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ bool isB = true; bool isD = true; bool isF = true; bool isH = true; switch (agaruHiku) { case AgaruHiku.Yoru: isB = false; isD = false; isF = false; isH = false; break; case AgaruHiku.Agaru: isB = false; isH = false; break; case AgaruHiku.Hiku: isB = false; isH = false; break; } switch (migiHidari) { case MigiHidari.Migi: isF = false; isH = false; break; case MigiHidari.Hidari: isB = false; isD = false; break; case MigiHidari.Sugu: isD = false; isF = false; break; } SySet_Default <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isB) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻昇(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻沈(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻降(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻浮(pside, dst1)); } //---------- // 候補マスB //---------- if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.L == srcSyurui) { #region 香 //************************************************************ // 香 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┐ // │ │至│ │ // ├─┼─┼─┤ // │ │E0│ │ // ├─┼─┼─┤ // │ │E1│ │ // ├─┼─┼─┤ // │ │E2│ │ // ├─┼─┼─┤ // │ │E3│ │ // ├─┼─┼─┤ // │ │E4│ │ // ├─┼─┼─┤ // │ │E5│ │ // ├─┼─┼─┤ // │ │E6│ │ // ├─┼─┼─┤ // │ │E7│ │ // └─┴─┴─┘ bool isE = true; SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isE) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻引(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.N == srcSyurui) { #region 桂 //************************************************************ // 桂 //************************************************************ //---------- // 候補マス //---------- //┌─┐ ┌─┐ //│ │ │ │ //├─┼─┼─┤ //│ │ │ │ //├─┼─┼─┤ //│ │至│ │先手から見た図 //├─┼─┼─┤ //│ │ │ │ //├─┼─┼─┤ //│J│ │I│ //└─┘ └─┘ bool isI = true; bool isJ = true; switch (agaruHiku) { case AgaruHiku.Yoru: isI = false; isJ = false; break; case AgaruHiku.Agaru: break; case AgaruHiku.Hiku: isI = false; isJ = false; break; } switch (migiHidari) { case MigiHidari.Migi: isJ = false; break; case MigiHidari.Hidari: isI = false; break; case MigiHidari.Sugu: isI = false; isJ = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isI) { srcAll.AddSupersets(KomanoKidou.SrcKeimatobi_戻跳(pside, dst1)); } if (isJ) { srcAll.AddSupersets(KomanoKidou.SrcKeimatobi_戻駆(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.S == srcSyurui) { #region 銀 //************************************************************ // 銀 //************************************************************ //---------- // 候補マス //---------- //┌─┬─┬─┐ //│H│ │B│ //├─┼─┼─┤ //│ │至│ │先手から見た図 //├─┼─┼─┤ //│F│E│D│ //└─┴─┴─┘ bool isB = true; bool isD = true; bool isE = true; bool isF = true; bool isH = true; switch (agaruHiku) { case AgaruHiku.Yoru: isB = false; isD = false; isE = false; isF = false; isH = false; break; case AgaruHiku.Agaru: isB = false; isH = false; break; case AgaruHiku.Hiku: isD = false; isE = false; isF = false; break; } switch (migiHidari) { case MigiHidari.Migi: isE = false; isF = false; isH = false; break; case MigiHidari.Hidari: isB = false; isD = false; isE = false; break; case MigiHidari.Sugu: isB = false; isD = false; isF = false; isH = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isB) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻昇(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻降(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻浮(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if ( PieceType.G == srcSyurui || PieceType.PP == srcSyurui || PieceType.PL == srcSyurui || PieceType.PN == srcSyurui || PieceType.PS == srcSyurui ) { #region △金、△と金、△成香、△成桂、△成銀 //************************************************************ // △金、△と金、△成香、△成桂、△成銀 //************************************************************ //---------- // 候補マス //---------- //┌─┬─┬─┐ //│ │A│ │ //├─┼─┼─┤ //│G│至│C│先手から見た図 //├─┼─┼─┤ //│F│E│D│ //└─┴─┴─┘ bool isA = true; bool isC = true; bool isD = true; bool isE = true; bool isF = true; bool isG = true; switch (agaruHiku) { case AgaruHiku.Yoru: isA = false; isD = false; isE = false; isF = false; break; case AgaruHiku.Agaru: isA = false; isC = false; isG = false; break; case AgaruHiku.Hiku: isC = false; isD = false; isE = false; isF = false; isG = false; break; } switch (migiHidari) { case MigiHidari.Migi: isA = false; isE = false; isF = false; isG = false; break; case MigiHidari.Hidari: isA = false; isC = false; isD = false; isE = false; break; case MigiHidari.Sugu: isA = false; isC = false; isD = false; isF = false; isG = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻上(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻射(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻降(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻滑(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.K == srcSyurui) { #region 王 //************************************************************ // 王 //************************************************************ //---------- // 候補マス //---------- //┌─┬─┬─┐ //│H│A│B│ //├─┼─┼─┤ //│G│至│C│先手から見た図 //├─┼─┼─┤ //│F│E│D│ //└─┴─┴─┘ bool isA = true; bool isB = true; bool isC = true; bool isD = true; bool isE = true; bool isF = true; bool isG = true; bool isH = true; SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻上(pside, dst1)); } if (isB) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻昇(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻射(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻降(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻滑(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻浮(pside, dst1)); } // 王は1つです。 if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.PR == srcSyurui) { #region 竜 //************************************************************ // 竜 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ // │ │ │ │ │ │ │ │ │A7│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A6│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A5│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A4│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A3│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A2│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A1│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │H│A0│B│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │G7│G6│G5│G4│G3│G2│G1│G0│至│C0│C1│C2│C3│C4│C5│C6│C7│ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │F│E0│D│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E1│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E2│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E3│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E4│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E5│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E6│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E7│ │ │ │ │ │ │ │ │ // └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ bool isA = true; bool isB = true; bool isC = true; bool isD = true; bool isE = true; bool isF = true; bool isG = true; bool isH = true; switch (agaruHiku) { case AgaruHiku.Yoru: isA = false; isB = false; isD = false; isE = false; isF = false; isH = false; break; case AgaruHiku.Agaru: isA = false; isB = false; isC = false; isG = false; isH = false; break; case AgaruHiku.Hiku: isC = false; isD = false; isE = false; isF = false; isG = false; break; } switch (migiHidari) { case MigiHidari.Migi: isA = false; isE = false; isF = false; isG = false; isH = false; break; case MigiHidari.Hidari: isA = false; isB = false; isC = false; isD = false; isE = false; break; case MigiHidari.Sugu: isA = false; isB = false; isC = false; isD = false; isF = false; isG = false; isH = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻上(pside, dst1)); } if (isB) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻昇(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻射(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻降(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻滑(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻浮(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.PB == srcSyurui) { #region 馬 //************************************************************ // 馬 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ // │H7│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │B7│ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │H6│ │ │ │ │ │ │ │ │ │ │ │ │ │B6│ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │H5│ │ │ │ │ │ │ │ │ │ │ │B5│ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │H4│ │ │ │ │ │ │ │ │ │B4│ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │H3│ │ │ │ │ │ │ │B3│ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │H2│ │ │ │ │ │B2│ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │H1│ │ │ │B1│ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │H0│A│B0│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │G│至│C│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │F0│E│D0│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │F1│ │ │ │D1│ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │F2│ │ │ │ │ │D2│ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │F3│ │ │ │ │ │ │ │D3│ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │F4│ │ │ │ │ │ │ │ │ │D4│ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │F5│ │ │ │ │ │ │ │ │ │ │ │D5│ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │F6│ │ │ │ │ │ │ │ │ │ │ │ │ │D6│ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │F7│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │D7│ // └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ bool isA = true; bool isB = true; bool isC = true; bool isD = true; bool isE = true; bool isF = true; bool isG = true; bool isH = true; switch (agaruHiku) { case AgaruHiku.Yoru: isA = false; isB = false; isD = false; isE = false; isF = false; isH = false; break; case AgaruHiku.Agaru: isA = false; isB = false; isC = false; isG = false; isH = false; break; case AgaruHiku.Hiku: isC = false; isD = false; isE = false; isF = false; isG = false; break; } switch (migiHidari) { case MigiHidari.Migi: isA = false; isE = false; isF = false; isG = false; isH = false; break; case MigiHidari.Hidari: isA = false; isB = false; isC = false; isD = false; isE = false; break; case MigiHidari.Sugu: isA = false; isB = false; isC = false; isD = false; isF = false; isG = false; isH = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻上(pside, dst1)); } if (isB) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻昇(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻射(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻降(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻滑(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻浮(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else { #region エラー //************************************************************ // エラー //************************************************************ #endregion } gt_EndShogiban: if (Fingers.Error_1 == foundKoma && utsu) { // 駒台の駒を(明示的に)打ちます。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fingers komas = Util_Sky.Fingers_ByOkibaPsideSyuruiNow( siteiNode.Value.ToKyokumenConst, srcOkiba1, pside, srcSyurui); if (0 < komas.Count) { switch (pside) { case Playerside.P2: srcOkiba1 = Okiba.Gote_Komadai; break; case Playerside.P1: srcOkiba1 = Okiba.Sente_Komadai; break; default: srcOkiba1 = Okiba.Empty; break; } foundKoma = komas[0]; goto gt_EndSyurui; } } gt_EndSyurui: int srcMasuHandle1; if (Fingers.Error_1 != foundKoma) { // 将棋盤の上に駒がありました。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(foundKoma).Now); srcMasuHandle1 = Util_Masu.AsMasuNumber(koma.Masu); } else { // (符号に書かれていませんが)「打」のとき。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch (pside) { case Playerside.P2: srcOkiba1 = Okiba.Gote_Komadai; break; case Playerside.P1: srcOkiba1 = Okiba.Sente_Komadai; break; default: srcOkiba1 = Okiba.Empty; break; } Debug.Assert(0 < siteiNode.Value.ToKyokumenConst.Count, "星の光が 1個未満。"); // 駒台から、該当する駒を探します。 Fingers daiKomaFgs = Util_Sky.Fingers_ByOkibaPsideSyuruiNow( siteiNode.Value.ToKyokumenConst, srcOkiba1, pside, srcSyurui);//(2014-10-04 12:46)変更 Debug.Assert(0 < daiKomaFgs.Count, "フィンガーズが 1個未満。 srcOkiba1=[" + srcOkiba1 + "] pside=[" + pside + "] srcSyurui=[" + srcSyurui + "]"); // 1個はヒットするはず Finger hitKoma = daiKomaFgs[0];//▲![コマ送り]ボタンを連打すると、エラーになります。 RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(hitKoma).Now); srcMasuHandle1 = Util_Masu.AsMasuNumber(koma.Masu); } PieceType dstSyurui; if (NariNarazu.Nari == nariNarazu) { // 成ります dstSyurui = KomaSyurui14Array.NariCaseHandle[(int)srcSyurui]; } else { // そのままです。 dstSyurui = srcSyurui; } // 1手を、データにします。 move = new RO_ShootingStarlight( //foundKoma,//TODO: new RO_Star_Koma( pside, Util_Masu.HandleToMasu(srcMasuHandle1), srcSyurui ), new RO_Star_Koma( pside, dstMasu,//符号は将棋盤の升目です。 dstSyurui ), PieceType.None // 符号からは、取った駒の種類は分からないんだぜ☆ だがバグではない☆ あとで調べる☆ ); }
/// <summary> /// 符号1「7g7f」を元に、move を作ります。 /// /// <[再生]、[コマ送り]で呼び出されます> /// </summary> /// <returns></returns> public static void ExecuteSfenMoves_FromTextSub( bool isHonshogi, string str1, //123456789 か、 PLNSGKRB string str2, //abcdefghi か、 * string str3, //123456789 string str4, //abcdefghi string strNari, //+ out ShootingStarlightable move, KifuTree kifu, string hint, int tesumi_yomiGenTeban//読み進めている現在の手目済 ) { move = Util_Sky.NullObjectMove; SkyConst src_Sky = kifu.NodeAt(tesumi_yomiGenTeban).Value.ToKyokumenConst; Debug.Assert(!Util_MasuNum.OnKomabukuro(Util_Masu.AsMasuNumber(((RO_Star_Koma)src_Sky.StarlightIndexOf((Finger)0).Now).Masu)), "[" + tesumi_yomiGenTeban + "]手目、駒が駒袋にあった。"); try { PieceType uttaSyurui; // 打った駒の種類 int srcSuji = Util_Koma.CTRL_NOTHING_PROPERTY_SUJI; int srcDan = Util_Koma.CTRL_NOTHING_PROPERTY_DAN; if ("*" == str2) { //>>>>>>>>>> 「打」でした。 Converter04.SfenUttaSyurui(str1, out uttaSyurui); } else { //>>>>>>>>>> 指しました。 uttaSyurui = PieceType.None;//打った駒はない☆ //------------------------------ // 1 //------------------------------ if (!int.TryParse(str1, out srcSuji)) { } //------------------------------ // 2 //------------------------------ srcDan = Converter04.Alphabet_ToInt(str2); } //------------------------------ // 3 //------------------------------ int suji; if (!int.TryParse(str3, out suji)) { } //------------------------------ // 4 //------------------------------ int dan; dan = Converter04.Alphabet_ToInt(str4); Finger koma; if ("*" == str2) { //>>>>> 「打」でした。 Node <ShootingStarlightable, KyokumenWrapper> siteiNode = kifu.CurNode; // 駒台から、打った種類の駒を取得 koma = Util_Sky.FingerNow_BySyuruiIgnoreCase( siteiNode.Value.ToKyokumenConst, Converter04.Pside_ToKomadai(kifu.CountPside(kifu.CurNode)),//Okiba.Sente_Komadai,//FIXME: uttaSyurui); if (Fingers.Error_1 == koma) { throw new Exception($"TuginoItte_Sfen#GetData_FromTextSub:駒台から種類[{uttaSyurui}]の駒を掴もうとしましたが、エラーでした。"); } //// FIXME: 打のとき、srcSuji、srcDan が Int.Min } else { //>>>>> 打ではないとき koma = Util_Sky.Fingers_AtMasuNow( src_Sky, Util_Masu.OkibaSujiDanToMasu(Okiba.ShogiBan, srcSuji, srcDan) ).ToFirst(); if (Fingers.Error_1 == koma) { // // エラーの理由: // 0手目、平手局面を想定していたが、駒がすべて駒袋に入っているときなど // var sky2 = Util_Sky.Json_1Sky(src_Sky, "エラー駒になったとき", $"{hint}_SF解3", tesumi_yomiGenTeban); throw new Exception($@"TuginoItte_Sfen#GetData_FromTextSub:SFEN解析中の失敗: 将棋盤から [{srcSuji}]筋、[{srcDan}]段 にある駒を掴もうとしましたが、駒がありませんでした。 isHonshogi=[{isHonshogi}] str1=[{str1}] str2=[{str2}] str3=[{str3}] str4=[{str4}] strNari=[{strNari}] hint=[{hint}] tesumi_yomiGenTeban=[{tesumi_yomiGenTeban}] 局面=sfen {Util_SfenStartposWriter.CreateSfenstring(new StartposExporter(src_Sky), true)} {sky2}"); } } PieceType dstSyurui; PieceType srcSyurui; Okiba srcOkiba; SyElement srcMasu; if ("*" == str2) { //>>>>> 打った駒の場合 dstSyurui = uttaSyurui; srcSyurui = uttaSyurui; switch (kifu.CountPside(kifu.CurNode)) { case Playerside.P2: srcOkiba = Okiba.Gote_Komadai; break; case Playerside.P1: srcOkiba = Okiba.Sente_Komadai; break; default: srcOkiba = Okiba.Empty; break; } int lastTesumi = kifu.CountTesumi(kifu.CurNode); Node <ShootingStarlightable, KyokumenWrapper> siteiNode = kifu.NodeAt(lastTesumi); Finger srcKoma = Util_Sky.FingerNow_BySyuruiIgnoreCase(siteiNode.Value.ToKyokumenConst, srcOkiba, srcSyurui); RO_Star_Koma dstKoma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(srcKoma).Now); srcMasu = dstKoma.Masu; } else { //>>>>> 盤上の駒を指した場合 RO_Star_Koma dstKoma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(koma).Now); dstSyurui = Haiyaku184Array.Syurui(dstKoma.Haiyaku); srcSyurui = dstSyurui; //駒は「元・種類」を記憶していませんので、「現・種類」を指定します。 srcOkiba = Okiba.ShogiBan; srcMasu = Util_Masu.OkibaSujiDanToMasu(srcOkiba, srcSuji, srcDan); } //------------------------------ // 5 //------------------------------ if ("+" == strNari) { // 成りました dstSyurui = KomaSyurui14Array.NariCaseHandle[(int)dstSyurui]; } //------------------------------ // 結果 //------------------------------ // 棋譜 move = new RO_ShootingStarlight( //koma,//TODO: new RO_Star_Koma( kifu.CountPside(kifu.CurNode), srcMasu,//FIXME:升ハンドルにしたい srcSyurui ), new RO_Star_Koma( kifu.CountPside(kifu.CurNode), Util_Masu.OkibaSujiDanToMasu(Okiba.ShogiBan, suji, dan),//符号は将棋盤の升目です。 FIXME:升ハンドルにしたい dstSyurui ), PieceType.None//符号からは、取った駒は分からない ); } catch (Exception ex) { //>>>>> エラーが起こりました。 // どうにもできないので 経路と情報を付け足して 更に外側に投げます。 throw new Exception($"{ex.GetType().Name}:{ex.Message} in TuginoItte_Sfen.GetData_FromTextSub(A) str1=「{str1}」 str2=「{str2}」 str3=「{str3}」 str4=「{str4}」 strNari=「{strNari}」 "); } }
/// <summary> /// 棋譜データを元に、符号リスト1(*1)を出力します。 /// /// *1…「▲2六歩△8四歩▲7六歩」といった書き方。 /// /// </summary> /// <param name="fugoList"></param> public static string ToJapaneseKifuText( KifuTree kifu ) { StringBuilder sb = new StringBuilder(); sb.Append("position "); sb.Append(kifu.GetProperty(KifuTreeImpl.PropName_Startpos)); sb.Append(" moves "); // 採譜用に、新しい対局を用意します。 KifuTree saifuKifu; { saifuKifu = new KifuTreeImpl( new KifuNodeImpl( Util_Sky.NullObjectMove, new KyokumenWrapper(new SkyConst(Util_Sky.New_Hirate())), //日本の符号読取時 Playerside.P2 ) ); saifuKifu.Clear();// 棋譜を空っぽにします。 saifuKifu.SetProperty(KifuTreeImpl.PropName_FirstPside, Playerside.P1); saifuKifu.SetProperty(KifuTreeImpl.PropName_Startpos, "startpos");//平手の初期局面 // FIXME:平手とは限らないのでは? } kifu.ForeachHonpu(kifu.CurNode, (int tesumi, KyokumenWrapper kWrap, Node <ShootingStarlightable, KyokumenWrapper> node6, ref bool toBreak) => { if (0 == tesumi) { goto gt_EndLoop; } FugoJ fugo; //------------------------------ // 符号の追加(記録係) //------------------------------ KyokumenWrapper saifu_kWrap = saifuKifu.CurNode.Value; KifuNode newNode = new KifuNodeImpl( node6.Key, new KyokumenWrapper(saifu_kWrap.ToKyokumenConst), KifuNodeImpl.GetReverseTebanside(((KifuNode)saifuKifu.CurNode).Tebanside) ); // TODO: ↓? ((KifuNode)saifuKifu.CurNode).AppendChildA_New(newNode); saifuKifu.CurNode = newNode; RO_Star_Koma koma = Util_Koma.AsKoma(((ShootingStarlightable)node6.Key).LongTimeAgo); fugo = JFugoCreator15Array.ItemMethods[(int)Haiyaku184Array.Syurui(koma.Haiyaku)](node6.Key, saifu_kWrap);//「▲2二角成」なら、馬(dst)ではなくて角(src)。 sb.Append(fugo.ToText_UseDou(node6)); gt_EndLoop: ; }); return(sb.ToString()); }
/// <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()); }
public static Node <ShootingStarlightable, KyokumenWrapper> CurNode(KifuTree kifu) { return(kifu.CurNode); }
/// <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> /// コンピューターの棋譜用 /// </summary> /// <param name="kifu"></param> /// <returns></returns> public static int CountCurTesumi1(KifuTree kifu) { return(kifu.CountTesumi(kifu.CurNode)); }