/// <summary> /// 定跡登録 初期化(ゲームセクション内) /// </summary> public static void Init_JosekiToroku(Kyokumen ky) { IsJosekiTraced = false;//毎回リセット☆(^▽^) KyFen_before = null; KyHash_before = 0; OptionalPhaseBeforeMove = Option <Phase> .None; if (Util_Machine.IsEnableBoardSize() && Option_Application.Optionlist.JosekiRec) { StringBuilder fenMojiretu = new StringBuilder(); ky.AppendFenTo(Option_Application.Optionlist.USI, fenMojiretu); KyFen_before = fenMojiretu.ToString(); KyHash_before = ky.KyokumenHash.Value; OptionalPhaseBeforeMove = ky.CurrentOptionalPhase; } }
public static void InLoop_SeisekiKosin(Move ss_after, Kyokumen ky, StringBuilder syuturyoku) { if (Option_Application.Optionlist.SeisekiRec)// 今回指した手全てに、成績を付けたいぜ☆(^~^) { int teme = ky.Konoteme.ScanNantemadeBango(); if (Util_Taikyoku.PNNantedume_Teme[OptionalPhase.IndexOf(ky.CurrentOptionalPhase)] <= teme) { // 何手詰め、何手詰められ の表記が出て以降の成績を記録するぜ☆(^~^) // 一手前の局面と、指したあとの指し手で成績更新☆(^▽^) Conv_Seiseki.ResultToCount(ky.CurrentOptionalPhase, Util_Application.Result(ky), out int kati, out int hikiwake, out int make); StringBuilder kyMojiretu = new StringBuilder(); ky.AppendFenTo(Option_Application.Optionlist.USI, kyMojiretu); Option_Application.Seiseki.AddMove( kyMojiretu.ToString(), ky.KyokumenHash.Value, ky.CurrentOptionalPhase, ss_after, Util_Application.VERSION, kati, hikiwake, make ); syuturyoku.Append("|"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } else { syuturyoku.Append("."); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } }//成績の記録☆ }
/// <summary> /// 対局終了 /// </summary> public static void DoTejun5_SyuryoTaikyoku1(IPlaying playing, Kyokumen ky, StringBuilder syuturyoku) { // 表示(コンソール・ゲーム用) { playing.Result(ky, syuturyoku, CommandMode.NingenYoConsoleGame); syuturyoku.AppendLine("終わったぜ☆(^▽^)"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } Util_Application.Begin_SeisekiKosin(syuturyoku); // 決着から初期局面まで、逆順で戻しながら棋譜を記録するぜ☆(^▽^) Med_Kyokumen.TukuruKifu(Option_Application.Optionlist.USI, ky, syuturyoku); // 棋譜の初期局面を更新☆ { StringBuilder kyFen_temp = new StringBuilder(); ky.AppendFenTo(Option_Application.Optionlist.USI, kyFen_temp); Option_Application.Kifu.SyokiKyokumenFen = kyFen_temp.ToString(); } Util_Application.End_SeisekiKosin(syuturyoku); string kigoComment = ""; // TODO: 成績は保存しないにしても、棋譜は欲しいときもあるぜ☆(^~^) // 棋譜を作ろうぜ☆ syuturyoku.AppendLine($@"{kigoComment}感想戦を行う場合は kansosen と打てだぜ☆(^▽^) そのあと kifu 1 とか打て☆(^▽^) {kigoComment}終わるときは hirate な☆(^▽^)"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); // 保存していないものを保存だぜ☆(^▽^) Util_Application.FlushAll1(syuturyoku); // 初期局面に戻すぜ☆(^▽^) Util_Taikyoku.Clear(); Util_Application.ResetHirate(Option_Application.Optionlist.USI, ky, syuturyoku); if (Option_Application.Optionlist.RandomStart) { playing.Ky(Option_Application.Optionlist.USI, "ky mazeru", ky, syuturyoku); } if (Option_Application.Optionlist.RandomStartTaikyokusya) { playing.Taikyokusya_cmd("taikyokusya mazeru", ky, syuturyoku); } if (Util_Machine.IsRenzokuTaikyokuStop()) { // 連続対局を止めるぜ☆(^▽^) Option_Application.Optionlist.RenzokuTaikyoku = false; syuturyoku.AppendLine($"{Logger.RenzokuTaikyokuStopFile }> done"); } if (!Option_Application.Optionlist.RenzokuTaikyoku) { // ゲームモードを解除するぜ☆(^~^) if (GameMode.Game == Util_Application.GameMode)// 感想戦での発動防止☆ { Util_Application.GameMode = GameMode.Karappo; } } else { // 連続対局中☆(^~^) if (Option_Application.Optionlist.RenzokuRandomRule && // 連続対局中、ルールをランダムに変える設定で 0 == Option_Application.Random.Next(2) && // ランダムに Util_Application.IsTimeOver_RenzokuRandomRule() // 変更間隔が空いているとき ) { // ルールを変えるぜ☆(^▽^) string commandline_2 = $"set SagareruHiyoko {!Option_Application.Optionlist.SagareruHiyoko}"; syuturyoku.AppendLine($"RenzokuRandomRule> {commandline_2}"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); // 表示してから実行しようぜ☆(^~^) Util_Application.Set(commandline_2, ky, syuturyoku); Util_Application.Restart_RenzokuRandomRuleTimeSpan();// 変更間隔の再調整だぜ☆(^▽^) } } if (Option_Application.Optionlist.RandomCharacter) { // コンピューター対局者の性格は ころころ変えるぜ☆(^▽^) for (int iPhase = 0; iPhase < Conv_Taikyokusya.AllOptionalPhaseList.Length; iPhase++) { Option_Application.Optionlist.PNChar[iPhase] = AbstractConvMoveCharacter.Items[Option_Application.Random.Next(AbstractConvMoveCharacter.Items.Length)]; } } // コマンドの誤発動防止 Util_Commandline.CommentCommandline(); }
/// <summary> /// 定跡局面の中で、評価値が一番高い指し手を返すぜ☆(^▽^) /// </summary> /// <param name="ky"></param> /// <returns>なければ投了☆</returns> public Move GetMove(bool isSfen, Kyokumen ky, out Hyokati out_bestHyokati, StringBuilder syuturyoku #if DEBUG , out string fen_forTest #endif ) { Move bestMove = Move.Toryo; out_bestHyokati = Hyokati.TumeTesu_GohosyuNasi; int bestFukasa = 0; #if DEBUG fen_forTest = ""; #endif //Util_Machine.Assert_KyokumenSeigosei_SabunKosin("ゲット指し手 #鯨",true); ulong hash = ky.KyokumenHash.Value; if (this.KyItems.ContainsKey(hash)) { JosekiKyokumen josekyKy = this.KyItems[hash]; // 整合性の確認用だぜ☆(^~^) #if DEBUG fen_forTest = josekyKy.Fen; #endif foreach (KeyValuePair <Move, JosekiMove> entry in josekyKy.SsItems) { if (out_bestHyokati < entry.Value.Hyokati)// 評価値が高い指し手を選ぶぜ☆(^▽^) { bestMove = entry.Key; out_bestHyokati = entry.Value.Hyokati; bestFukasa = entry.Value.Fukasa; } else if (out_bestHyokati == entry.Value.Hyokati && //評価値が同じ場合は、 bestFukasa < entry.Value.Fukasa //深く読んでいる指し手を選ぶぜ☆(^▽^) ) { bestMove = entry.Key; out_bestHyokati = entry.Value.Hyokati; bestFukasa = entry.Value.Fukasa; } } } #if DEBUG // 指し手の整合性をチェックしておきたいぜ☆(^▽^) { Kyokumen ky_forAssert = new Kyokumen(); int caret = 0; StringBuilder sindan1 = new StringBuilder(); ky.AppendFenTo(Option_Application.Optionlist.USI, sindan1); //if (!ky2.ParseFen(sindan1.ToString(), ref caret, false, syuturyoku)) if (!ky_forAssert.ParsePositionvalue(isSfen, sindan1.ToString(), ref caret, true, false, out string moves, syuturyoku))// ビットボードを更新したいので、適用する { syuturyoku.AppendLine("取得: パースに失敗だぜ☆(^~^)! #鰯"); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); throw new Exception(msg); } if (!ky_forAssert.CanDoMove(bestMove, out MoveMatigaiRiyu riyu)) { StringBuilder sindan2 = new StringBuilder(); sindan2.Append("取得: 指せない指し手を定跡から取り出そうとしたぜ☆(^~^)!:"); // sindan2.Append("理由:"); ConvMove.SetumeiLine(riyu,sindan2); sindan2.Append("指し手:"); ConvMove.SetumeiLine(isSfen, bestMove, sindan2); sindan2.Append("定跡局面 ("); ky_forAssert.AppendFenTo(Option_Application.Optionlist.USI, sindan2); sindan2.AppendLine(")"); Util_Information.Setumei_Lines_Kyokumen(ky_forAssert, sindan2); //str2.AppendLine("以下、定跡メモリのダンプ"); //str2.AppendLine("┌──────────┐"); //str2.Append(this.ToString()); //str2.AppendLine("└──────────┘"); syuturyoku.AppendLine(sindan2.ToString()); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); throw new Exception(sindan2.ToString()); } } #endif return(bestMove); }