/// <summary> /// FIXME:未実装 /// 二駒の評価値を表示。 /// </summary> /// <param name="uc_Main"></param> public static void Do_ShowNikomaHyokati(Uc_Main uc_Main) { #if DEBUG || LEARN KyHyokaMeisai_Koumoku komawariMeisai; KyHyokaMeisai_Koumoku ppMeisai; #endif uc_Main.LearningData.DoScoreing_ForLearning( (KifuNode)uc_Main.LearningData.Kifu.CurNode #if DEBUG || LEARN , out komawariMeisai, out ppMeisai #endif ); StringBuilder sb = new StringBuilder(); #if DEBUG || LEARN sb.Append("駒割="); sb.Append(komawariMeisai.UtiwakeValue.ToString()); sb.Append(" Pp="); sb.Append(ppMeisai.UtiwakeValue.ToString()); //sb.Append(" Pp内訳:"); //sb.Append(ppMeisai.Utiwake); #else sb.Append("DEBUG または LEARNモードで実行してください。"); #endif uc_Main.TxtNikomaHyokati.Text = sb.ToString(); }
public static void Do_OpenCsaKifu( ref bool isRequest_ShowGohosyu, ref bool isRequest_ChangeKyokumenPng, string kifuFilepath, Uc_Main uc_Main) { uc_Main.TxtKifuFilepath.Text = kifuFilepath; // 平手初期局面の棋譜ツリーを準備します。 Util_LearnOperation.Setup_KifuTree( ref isRequest_ShowGohosyu, ref isRequest_ChangeKyokumenPng, uc_Main); // 処理が重いので。 Application.DoEvents(); // CSA棋譜を読み込みます。 Util_LearnOperation.Load_CsaKifu(uc_Main); // 合法手を調べます。 uc_Main.LearningData.Aa_Yomi(uc_Main.LearningData.Kifu.CurNode.Key); // ノード情報の表示 Util_LearningView.Aa_ShowNode2(uc_Main.LearningData, uc_Main); //gt_EndMethod: // ; }
/// <summary> /// 初期設定。 /// </summary> public void AtBegin(Uc_Main uc_Main) { var profilePath = System.Configuration.ConfigurationManager.AppSettings["Profile"]; var toml = Toml.ReadFile(Path.Combine(profilePath, "Engine.toml")); // データの読取「道」 if (Michi187Array.Load(this.EngineConf.GetResourceFullPath("Michi187"))) { } // データの読取「配役」 Util_Array_KomahaiyakuEx184.Load(this.EngineConf.GetResourceFullPath("Haiyaku185"), Encoding.UTF8); // データの読取「強制転成表」 ※駒配役を生成した後で。 Array_ForcePromotion.Load(this.EngineConf.GetResourceFullPath("InputForcePromotion"), Encoding.UTF8); #if DEBUG { File.WriteAllText(this.EngineConf.GetResourceFullPath("OutputForcePromotion"), Array_ForcePromotion.LogHtml()); } #endif // データの読取「配役転換表」 Data_KomahaiyakuTransition.Load(this.EngineConf.GetResourceFullPath("InputSyuruiToHaiyaku"), Encoding.UTF8); #if DEBUG { File.WriteAllText(this.EngineConf.GetResourceFullPath("OutputSyuruiToHaiyaku"), Data_KomahaiyakuTransition.Format_LogHtml()); } #endif // ファイルへのパス。 uc_Main.TxtFvFilepath.Text = Path.GetFullPath(this.EngineConf.GetResourceFullPath("Fv00Komawari")); uc_Main.TxtStatus1.Text = "開くボタンで開いてください。"; }
/// <summary> /// 局面PNG画像を更新。 /// </summary> public void ChangeKyokumenPng(Uc_Main uc_Main) { uc_Main.PctKyokumen.Image = null;//掴んでいる画像ファイルを放します。 this.WritePng(); uc_Main.PctKyokumen.ImageLocation = this.EngineConf.GetResourceFullPath("LearningPositionLogPng"); }
/// <summary> /// ノード情報の表示 /// </summary> /// <param name="uc_Main"></param> public static void Aa_ShowNode2(LearningData learningData, Uc_Main uc_Main) { // 手目済み uc_Main.TxtTemezumi.Text = learningData.Kifu.CurNode.Value.KyokumenConst.Temezumi.ToString(); // 総ノード数 uc_Main.TxtAllNodesCount.Text = learningData.Kifu.CountAllNodes().ToString(); // 合法手の数 uc_Main.TxtGohosyuTe.Text = ((KifuNode)learningData.Kifu.CurNode).Count_ChildNodes.ToString(); }
/// <summary> /// 初期局面の評価値を 0 点にするようにFVを調整します。 /// </summary> public static void Do_ZeroStart(ref bool isRequest_ShowGohosyu, Uc_Main uc_Main) { bool isRequestDoEvents = false; Util_StartZero.Adjust_HirateSyokiKyokumen_0ten_AndFvParamRange(ref isRequestDoEvents, uc_Main.LearningData.Fv); //// 合法手一覧を作成 //uc_Main.LearningData.Aa_Yomi(uc_Main.LearningData.Kifu.CurNode.Key); // 局面の合法手表示の更新を要求 isRequest_ShowGohosyu = true; }
///// <summary> ///// FVを0~999(*bairitu)に矯正。 ///// </summary> //public static void Do_FvRange999(ref bool isRequest_ShowGohosyu, Uc_Main uc_Main, IErrorController logTag) //{ // Util_LearnFunctions.FvParamRange_PP(uc_Main.LearningData.Fv); // // 局面の合法手表示の更新を要求します。 // isRequest_ShowGohosyu = true; //} public static void Do_OpenFvCsv(Uc_Main uc_Main) { if ("" != uc_Main.TxtFvFilepath.Text) { uc_Main.OpenFvFileDialog2.InitialDirectory = Path.GetDirectoryName(uc_Main.TxtFvFilepath.Text); uc_Main.OpenFvFileDialog2.FileName = Path.GetFileName(uc_Main.TxtFvFilepath.Text); } else { uc_Main.OpenFvFileDialog2.InitialDirectory = Application.StartupPath; } DialogResult result = uc_Main.OpenFvFileDialog2.ShowDialog(); switch (result) { case DialogResult.OK: uc_Main.TxtFvFilepath.Text = uc_Main.OpenFvFileDialog2.FileName; StringBuilder sb_result = new StringBuilder(); // フィーチャー・ベクターの外部ファイルを開きます。 sb_result.Append(Util_FvLoad.OpenFv(uc_Main.EngineConf, uc_Main.LearningData.Fv, uc_Main.TxtFvFilepath.Text)); uc_Main.TxtStatus1.Text = sb_result.ToString(); // うまくいっていれば、フィーチャー・ベクターのセットアップが終わっているはず。 { // 調整量 uc_Main.TyoseiryoSettings.SetSmallest(uc_Main.LearningData.Fv.TyoseiryoSmallest_NikomaKankeiPp); uc_Main.TyoseiryoSettings.SetLargest(uc_Main.LearningData.Fv.TyoseiryoLargest_NikomaKankeiPp); // // 調整量(初期値) // uc_Main.TxtTyoseiryo.Text = uc_Main.LearningData.Fv.TyoseiryoInit_NikomaKankeiPp.ToString(); // 半径 float paramRange = Util_Inspection.FvParamRange(uc_Main.LearningData.Fv); uc_Main.ChkAutoParamRange.Text = $"評価更新毎-{paramRange}~{paramRange}矯正"; } uc_Main.BtnUpdateKyokumenHyoka.Enabled = true; break; default: break; } //gt_EndMethod: // ; }
/// <summary> /// 指定の指し手の順位調整を行います。 /// /// 全体が調整されてしまうような☆? /// </summary> /// <param name="uc_Main"></param> /// <param name="tyoseiryo"></param> public static void ARankUpSelectedMove(Uc_Main uc_Main, float tyoseiryo) { //---------------------------------------- // 選択したノードを参考に、減点を行う。 //---------------------------------------- foreach (GohosyuListItem item in uc_Main.LstGohosyu.SelectedItems) { string sfenMoveStr = item.Sfen; Logger.Trace($"sfenMoveStr={sfenMoveStr}"); if (uc_Main.LearningData.Kifu.CurNode.HasChildNode(sfenMoveStr)) { Logger.Trace("----------------------------------------"); Logger.Trace("FV 総合点(読込前)1"); Logger.Trace($" PP ={Util_FeatureVectorEdit.GetTotal_PP(uc_Main.LearningData.Fv)}"); Logger.Trace("----------------------------------------"); Node <IMove, KyokumenWrapper> nextNode = uc_Main.LearningData.Kifu.CurNode.GetChildNode(sfenMoveStr); // 盤上の駒、持駒を数えます。 N54List nextNode_n54List = Util_54List.Calc_54List(nextNode.Value.KyokumenConst); float real_tyoseiryo; //実際に調整した量。 Util_FvScoreing.UpdateKyokumenHyoka( nextNode_n54List, nextNode.Value.KyokumenConst, uc_Main.LearningData.Fv, tyoseiryo, out real_tyoseiryo );//相手が有利になる点 Logger.Trace("----------------------------------------"); Logger.Trace("FV 総合点(読込後)6"); Logger.Trace($" PP ={Util_FeatureVectorEdit.GetTotal_PP(uc_Main.LearningData.Fv)}"); Logger.Trace("----------------------------------------"); } } //---------------------------------------- // 点数を付け直すために、ノードを一旦、全削除 //---------------------------------------- uc_Main.LearningData.Kifu.CurNode.Clear_ChildNodes(); //---------------------------------------- // ネクスト・ノードを再作成 //---------------------------------------- // TODO:本譜のネクスト・ノードは? uc_Main.LearningData.Aa_Yomi(uc_Main.LearningData.Kifu.CurNode.Key); }
/// <summary> /// FIXME: 未実装 /// 指し手の順位上げ。 /// </summary> public static void DoRankUpMove( ref bool isRequest_ShowGohosyu, ref bool isRequest_ChangeKyokumenPng, Uc_Main uc_Main) { // 評価値変化量 float chosei_bairitu; float.TryParse(uc_Main.TxtChoseiBairituB.Text, out chosei_bairitu); if (Playerside.P2 == uc_Main.LearningData.Kifu.CurNode.Value.KyokumenConst.KaisiPside) { chosei_bairitu *= -1; //後手はマイナスの方が有利。 } Util_LearnOperation.ARankUpSelectedMove(uc_Main, chosei_bairitu); // 現局面の合法手表示の更新を要求 isRequest_ShowGohosyu = true; // 局面PNG画像更新を要求 isRequest_ChangeKyokumenPng = true; }
/// <summary> /// 局面評価を更新。 /// </summary> public static void Do_UpdateKyokumenHyoka( ref bool isRequest_ShowGohosyu, ref bool isRequest_ChangeKyokumenPng, Uc_Main uc_Main) { int renzokuTe; if (!int.TryParse(uc_Main.TxtRenzokuTe.Text, out renzokuTe)) { // パース失敗時は 1回実行。 renzokuTe = 1; } while (true) //無限ループ { // 棋譜ループ bool isEndKifuread; //---------------------------------------- // 繰り返し、指し手を進めます。 //---------------------------------------- UtilAutoMoveRush.DoMoveRush( out isEndKifuread, ref isRequest_ShowGohosyu, ref isRequest_ChangeKyokumenPng, renzokuTe, uc_Main); if (isEndKifuread) { //棋譜の自動読取の終了 goto gt_EndKifuList; } // 無限ループなので。 Application.DoEvents(); }//棋譜ループ gt_EndKifuList: //棋譜の自動読取の終了 ; }
/// <summary> /// 棋譜読込み。 /// </summary> public void ReadKifu(Uc_Main uc_Main) { if (!File.Exists(uc_Main.TxtKifuFilepath.Text)) { goto gt_EndMethod; } // CSA棋譜テキスト→対訳→データ this.CsaKifu = Util_Csa.ReadFile(uc_Main.TxtKifuFilepath.Text); //---------------------------------------- // 読み用。 //---------------------------------------- this.featureVector_ForYomi = new FeatureVectorImpl(); gt_EndMethod: ; }
/// <summary> /// 棋譜ツリーをセットアップします。 /// </summary> public static void Setup_KifuTree( ref bool isRequest_ShowGohosyu, ref bool isRequest_ChangeKyokumenPng, Uc_Main uc_Main) { { KifuTree kifu_newHirate; Util_FvLoad.CreateKifuTree(out kifu_newHirate); uc_Main.LearningData.Kifu = kifu_newHirate; } EvaluationArgs args; { #if DEBUG KaisetuBoards logF_kiki = new KaisetuBoards();// デバッグ用だが、メソッドはこのオブジェクトを必要としてしまう。 #endif args = new EvaluationArgsImpl( uc_Main.LearningData.Kifu.GetSennititeCounter(), new FeatureVectorImpl(), Util_KifuTreeLogWriter.REPORT_ENVIRONMENT #if DEBUG , logF_kiki #endif ); } // 合法手を数えたい。 uc_Main.LearningData.Aaa_CreateNextNodes_Gohosyu(args); // 現局面の合法手表示の更新を要求 isRequest_ShowGohosyu = true; // 局面PNG画像更新を要求 isRequest_ChangeKyokumenPng = true; }
public const int RENZOKU_KAISU = 3; // 100の前提で作ってあるが、やるほど弱くなるので数回にしておく。 // 60だと 34 ぐらいで終わる。 // 150 だと 400 はすぐカンスト。 // 256意味ない /// <summary> /// 繰り返し、指し手を進めます。 /// </summary> public static void DoMoveRush( out bool out_isEndKifuread, ref bool isRequest_ShowGohosyu, ref bool isRequest_ChangeKyokumenPng, int renzokuTe, Uc_Main uc_Main ) { out_isEndKifuread = false; bool isRequestDoEvents = false; bool isSaved = false; // // N手を連続で自動実行。 // 本譜の手が残っている間。 // for (int pushedButton = 0; pushedButton < renzokuTe && 0 < uc_Main.LstMove.Items.Count; pushedButton++) { // 指し手ループ isSaved = false; //リセット float tyoseiryo; float.TryParse(uc_Main.TxtTyoseiryo.Text, out tyoseiryo); HonpuMoveListItemImpl moveItem = (HonpuMoveListItemImpl)uc_Main.LstMove.Items[0]; string sfenMoveStr = moveItem.Sfen; if (sfenMoveStr == "") { goto gt_EndMoveList; } if (uc_Main.ChkIgnoreThink.Checked) { // 最初の20手は学習しない。 int tesu; if (!int.TryParse(uc_Main.TxtIgnoreLearn.Text, out tesu)) { goto gt_EndTesu; } if (uc_Main.LearningData.Kifu.CurNode.Value.KyokumenConst.Temezumi < tesu + 1) { goto gt_EndLearn; } gt_EndTesu: ; } //---------------------------------------- // FIXME: 暫定:ボタン連打は可能に。 //---------------------------------------- //this.btnUpdateKyokumenHyoka.Enabled = false;//ボタン連打防止。 //---------------------------------------- // 指し手の順位を変える回数 //---------------------------------------- int loopLimit = 1; // 通常1回 if (uc_Main.ChkHyakuretuken.Checked) { loopLimit = UtilAutoMoveRush.RENZOKU_KAISU; } //---------------------------------------- // 指し手の順位を変えるループです。 //---------------------------------------- int pushCount; bool isEndAutoLearn; Util_AutoSortingRush.DoSortMoveRush( out pushCount, out isEndAutoLearn, ref isRequest_ShowGohosyu, ref isRequest_ChangeKyokumenPng, ref isRequestDoEvents, loopLimit, ref tyoseiryo, sfenMoveStr, uc_Main ); if (isEndAutoLearn) { //棋譜の自動読取の終了 out_isEndKifuread = true; goto gt_EndMethod; } // 調整量の自動調整 if (uc_Main.ChkTyoseiryoAuto.Checked) { Util_Tyoseiryo.Up_Bairitu_AtEnd(ref isRequestDoEvents, uc_Main, pushCount, ref tyoseiryo); } if (uc_Main.ChkStartZero.Checked)// 自動で、平手初期局面の点数を 0 点に近づけるよう調整します。 { Util_StartZero.Adjust_HirateSyokiKyokumen_0ten_AndFvParamRange(ref isRequestDoEvents, uc_Main.LearningData.Fv); } if (uc_Main.ChkAutoParamRange.Checked) { //// 自動で -999~999 に矯正。 Util_LearnFunctions.FvParamRange_PP(uc_Main.LearningData.Fv);// 自動で -999~999(*bairitu) に矯正。 // 合法手表示の更新を要求 isRequest_ShowGohosyu = true; } gt_EndLearn: ; //---------------------------------------- // 投了図まで自動実行 //---------------------------------------- if (uc_Main.ChkRenzokuAutoRun.Checked) { // [一手指す]ボタン押下 Util_LearningView.IttesasuByBtnClick( ref isRequest_ShowGohosyu, ref isRequest_ChangeKyokumenPng, uc_Main.LearningData, uc_Main); // 局面PNG画像の更新を要求 //isRequest_ChangeKyokumenPng = true; } else { // 自動ループしないなら、終了。 break; } if (isRequest_ShowGohosyu) { // 合法手一覧を更新 Util_LearningView.Aa_ShowGohosyu2(uc_Main.LearningData, uc_Main); isRequest_ShowGohosyu = false; // 重い処理のあとは。 isRequestDoEvents = true; } if (isRequest_ChangeKyokumenPng) { uc_Main.LearningData.ChangeKyokumenPng(uc_Main); isRequest_ChangeKyokumenPng = false; // 重い処理のあとは。 isRequestDoEvents = true; } //---------------------------------------- // N手で学習終了 //---------------------------------------- if (uc_Main.ChkEndLearnTesu.Checked) { // N手で学習を終了します。 int tesu; if (!int.TryParse(uc_Main.TxtEndLearnTesu.Text, out tesu)) { goto gt_EndTesu; } if (tesu <= uc_Main.LearningData.Kifu.CurNode.Value.KyokumenConst.Temezumi) { // 自動ループしないなら、終了。 break; } gt_EndTesu: ; } // オートセーブ // // 20手間隔で。 // if ( uc_Main.ChkAutosave.Checked && uc_Main.LearningData.Kifu.CurNode.Value.KyokumenConst.Temezumi % 20 == 0 ) { Util_LearnFunctions.Do_Save(uc_Main); isSaved = true; } if (isRequestDoEvents) { Application.DoEvents(); isRequestDoEvents = false; } }//指し手ループ gt_EndMoveList: ; // 終局時は、オートセーブ // ※20手で終局した場合は、20手で保存されたあと、2連続で終局時として保存されることになる。 if (uc_Main.ChkAutosave.Checked) { if (!isSaved) { Util_LearnFunctions.Do_Save(uc_Main); isSaved = true; } } if (isRequestDoEvents) { Application.DoEvents(); isRequestDoEvents = false; } if (uc_Main.ChkAutoKifuNext.Checked) { //---------------------------------------- // 棋譜がなくなるまで、繰り返すなら //---------------------------------------- // 今読んだ棋譜を移す先(成功時) uc_Main.SeikoIdo(); bool isEmptyKifu; uc_Main.Do_NextKifuSet(out isEmptyKifu, ref isRequest_ShowGohosyu, ref isRequest_ChangeKyokumenPng); if (isEmptyKifu) { //棋譜の自動読取の終了 out_isEndKifuread = true; goto gt_EndMethod; } if (isRequest_ShowGohosyu) { // 合法手一覧を更新 Util_LearnFunctions.FvParamRange_PP(uc_Main.LearningData.Fv);// 自動で -999~999(*bairitu) に矯正。 Util_LearningView.Aa_ShowGohosyu2(uc_Main.LearningData, uc_Main); isRequest_ShowGohosyu = false; } if (isRequest_ChangeKyokumenPng) { uc_Main.LearningData.ChangeKyokumenPng(uc_Main); isRequest_ChangeKyokumenPng = false; } } else { //棋譜の自動読取の終了 out_isEndKifuread = true; goto gt_EndMethod; } gt_EndMethod: ; }
/// <summary> /// [一手指す]ボタン。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public static void IttesasuByBtnClick( ref bool isRequestShowGohosyu, ref bool isRequestChangeKyokumenPng, LearningData learningData, Uc_Main ucMain) { #if DEBUG Stopwatch sw1 = new Stopwatch(); sw1.Start(); #endif if (ucMain is null) { throw new ArgumentNullException(nameof(ucMain)); } // if (logTag is null) throw new ArgumentNullException(nameof(logTag)); // // リストの先頭の項目を取得したい。 // if (ucMain.LstMove.Items.Count < 1) { goto gt_EndMethod; } // リストボックスの先頭から指し手をSFEN形式で1つ取得。 HonpuMoveListItemImpl item = (HonpuMoveListItemImpl)ucMain.LstMove.Items[0]; string sfen = item.Sfen; // (2020-12-18 fri)この機能むずかしいからいったん廃止☆(^~^) // logTag.OnAppendLog?.Invoke($"sfen={sfen}\n"); // // 現局面の合法手は、既に読んであるとします。(棋譜ツリーのNextNodesが既に設定されていること) // // // 合法手の一覧は既に作成されているものとします。 // 次の手に進みます。 // IMove nextMove; { if (learningData.Kifu.CurNode.HasChildNode(sfen)) { Node <IMove, KyokumenWrapper> nextNode = learningData.Kifu.CurNode.GetChildNode(sfen); nextMove = nextNode.Key;//次の棋譜ノードのキーが、指し手(きふわらべ式)になっています。 } else { nextMove = null; throw new Exception($@"指し手[{sfen}]はありませんでした。 {learningData.DumpToAllGohosyu(learningData.Kifu.CurNode.Value.KyokumenConst)}"); } } //---------------------------------------- // 一手指したい。 //---------------------------------------- //↓↓一手指し IttesasuResult ittesasuResult; Util_IttesasuRoutine.Before1( new IttesasuArgImpl( learningData.Kifu.CurNode.Value, ((KifuNode)learningData.Kifu.CurNode).Value.KyokumenConst.KaisiPside, nextMove, // FIXME: これがヌルのことがあるのだろうか? learningData.Kifu.CurNode.Value.KyokumenConst.Temezumi + 1 //1手進める ), out ittesasuResult, //this.Kifu,//診断用 "Util_LearningView#Ittesasu_ByBtnClick" ); Debug.Assert(ittesasuResult.Get_SyuryoNode_OrNull != null, "ittesasuResult.Get_SyuryoNode_OrNull がヌル☆?!"); Util_IttesasuRoutine.Before2( ref ittesasuResult ); // //次ノートを追加します。次ノードを、これからのカレントとします。 // //this.Kifu.AssertChildPside(this.Kifu.CurNode.Value.ToKyokumenConst.KaisiPside, ittesasuResult.Get_SyuryoNode_OrNull.Value.ToKyokumenConst.KaisiPside); Util_IttesasuRoutine.After3_ChangeCurrent( learningData.Kifu, ConvMoveStrSfen.ToMoveStrSfen(ittesasuResult.Get_SyuryoNode_OrNull.Key), ittesasuResult.Get_SyuryoNode_OrNull ); // これで、棋譜ツリーに、構造変更があったはず。 //↑↑一手指し //---------------------------------------- // カレント・ノードより古い、以前読んだ手を削除したい。 //---------------------------------------- Logger.Trace($"カレント・ノード={ConvMoveStrSfen.ToMoveStrSfen(learningData.Kifu.CurNode.Key)}"); int result_removedCount = UtilKifuTree282.IzennoHenkaCutter(learningData.Kifu); Logger.Trace($"削除した要素数={result_removedCount}"); ////---------------------------------------- //// 合法手一覧を作成したい。 ////---------------------------------------- learningData.Aa_Yomi(nextMove); // ノード情報の表示 Util_LearningView.Aa_ShowNode2(ucMain.LearningData, ucMain); // 合法手表示の更新を要求します。 isRequestShowGohosyu = true; // 局面PNG画像を更新を要求。 isRequestChangeKyokumenPng = true; // // リストの頭1個を除外します。 // ucMain.LstMove.Items.RemoveAt(0); #if DEBUG sw1.Stop(); Logger.Trace($"一手指すボタン合計 = {sw1.Elapsed}"); Logger.Trace("────────────────────────────────────────"); #endif gt_EndMethod: ; //---------------------------------------- // ボタン表示の回復 //---------------------------------------- if (0 < ucMain.LstMove.Items.Count) { ucMain.BtnUpdateKyokumenHyoka.Enabled = true;//[局面評価更新]ボタン連打防止解除。 } }
/// <summary> /// 合法手リストの表示 /// </summary> /// <param name="uc_Main"></param> public static void Aa_ShowGohosyu2(LearningData learningData, Uc_Main uc_Main) { //---------------------------------------- // フォルダー作成 //---------------------------------------- //this.Kifu.CreateAllFolders($"{Const_Filepath.LOGS}temp", 4); { //---------------------------------------- // 合法手のリストを作成 //---------------------------------------- List <GohosyuListItem> list = new List <GohosyuListItem>(); //uc_Main.LstGohosyu.Items.Clear(); int itemNumber = 0; ((KifuNode)learningData.Kifu.CurNode).Foreach_ChildNodes((string key, Node <IMove, KyokumenWrapper> node, ref bool toBreak) => { #if DEBUG || LEARN KyHyokaMeisai_Koumoku komawariMeisai; KyHyokaMeisai_Koumoku ppMeisai; #endif learningData.DoScoreing_ForLearning( (KifuNode)node #if DEBUG || LEARN , out komawariMeisai, out ppMeisai #endif ); GohosyuListItem item = new GohosyuListItem( itemNumber, key, ConvMoveStrJsa.ToMoveStrJsa(node) #if DEBUG || LEARN , komawariMeisai, ppMeisai #endif ); list.Add(item); itemNumber++; }); //---------------------------------------- // ソート //---------------------------------------- // // 先手は正の数、後手は負の数で、絶対値の高いもの順。 list.Sort((GohosyuListItem a, GohosyuListItem b) => { int result; int aScore = #if DEBUG || LEARN (int)( a.KomawariMeisai.UtiwakeValue + a.PpMeisai.UtiwakeValue); #else 0; #endif int bScore = #if DEBUG || LEARN (int)( b.KomawariMeisai.UtiwakeValue + b.PpMeisai.UtiwakeValue); #else 0; #endif switch (learningData.Kifu.CurNode.Value.KyokumenConst.KaisiPside) { case Playerside.P1: result = bScore - aScore; break; case Playerside.P2: result = aScore - bScore; break; default: result = 0; break; } return(result); }); uc_Main.LstGohosyu.Items.Clear(); uc_Main.LstGohosyu.Items.AddRange(list.ToArray()); //foreach (GohosyuListItem item in list) //{ // uc_Main.LstGohosyu.Items.Add(item); //} } }
public static void Load_CsaKifu(Uc_Main uc_Main) { uc_Main.LearningData.ReadKifu(uc_Main); Util_LearningView.ShowMoveList(uc_Main.LearningData, uc_Main); }
/// <summary> /// 指し手一覧を、リストボックスに表示します。 /// </summary> /// <param name="uc_Main"></param> public static void ShowMoveList( LearningData learningData, Uc_Main uc_Main ) { // // まず、リストを空っぽにします。 // uc_Main.LstMove.Items.Clear(); Playerside firstPside = Playerside.P1; KifuTree kifu1 = new KifuTreeImpl( new KifuNodeImpl( Util_Sky258A.RootMove, new KyokumenWrapper(SkyConst.NewInstance( Util_SkyWriter.New_Hirate(firstPside), 0 //初期局面は 0手済み。 )) //日本の符号読取時 ) ); //kifu1.AssertPside(kifu1.CurNode, "ShowMoveList",logTag); List <CsaKifuMove> moveList = learningData.CsaKifu.MoveList; foreach (CsaKifuMove csaMove in moveList) { // 開始局面 SkyConst kaisi_Sky = kifu1.CurNode.Value.KyokumenConst; // // csaMove を データ指し手 に変換するには? // IMove nextMove; { Playerside pside = UtilCsaMove.ToPside(csaMove); // 元位置 SyElement srcMasu = UtilCsaMove.ToSrcMasu(csaMove); Finger figSrcKoma; if (Masu_Honshogi.IsErrorBasho(srcMasu))// 駒台の "00" かも。 { //駒台の駒。 PieceType utuKomasyurui = Util_Komasyurui14.NarazuCaseHandle(UtilCsaMove.ToKomasyurui(csaMove));// 打つ駒の種類。 Okiba komadai; switch (pside) { case Playerside.P1: komadai = Okiba.Sente_Komadai; break; case Playerside.P2: komadai = Okiba.Gote_Komadai; break; default: komadai = Okiba.Empty; break; } figSrcKoma = Util_Sky_FingersQuery.InOkibaPsideKomasyuruiNow(kaisi_Sky, komadai, pside, utuKomasyurui).ToFirst(); } else { // 盤上の駒。 figSrcKoma = Util_Sky_FingerQuery.InMasuNow(kaisi_Sky, pside, srcMasu); } RO_Star srcKoma = Util_Starlightable.AsKoma(kaisi_Sky.StarlightIndexOf(figSrcKoma).Now); // 先位置 SyElement dstMasu = UtilCsaMove.ToDstMasu(csaMove); Finger figFoodKoma = Util_Sky_FingerQuery.InShogibanMasuNow(kaisi_Sky, pside, dstMasu); PieceType foodKomasyurui; if (figFoodKoma == Fingers.Error_1) { // 駒のない枡 foodKomasyurui = PieceType.None;//取った駒無し。 } else { // 駒のある枡 foodKomasyurui = Util_Starlightable.AsKoma(kaisi_Sky.StarlightIndexOf(figFoodKoma).Now).Komasyurui;//取った駒有り。 } IMoveSource dstKoma = new RO_Star( pside, dstMasu, UtilCsaMove.ToKomasyurui(csaMove) ); nextMove = new RO_Starbeam( srcKoma, // 移動元 dstKoma, // 移動先 foodKomasyurui ////取った駒 ); } { //---------------------------------------- // 一手指したい。 //---------------------------------------- // //↓↓一手指し IttesasuResult ittesasuResult; Util_IttesasuRoutine.Before1( new IttesasuArgImpl( kifu1.CurNode.Value, ((KifuNode)kifu1.CurNode).Value.KyokumenConst.KaisiPside, nextMove, kifu1.CurNode.Value.KyokumenConst.Temezumi + 1//1手進める ), out ittesasuResult, //kifu1,//診断用 "Utli_LearningViews#ShowMoveList" ); Debug.Assert(ittesasuResult.Get_SyuryoNode_OrNull != null, "ittesasuResult.Get_SyuryoNode_OrNull がヌル☆?!"); Util_IttesasuRoutine.Before2( ref ittesasuResult ); // //次ノートを追加します。次ノードを、これからのカレントとします。 // //kifu1.AssertChildPside(kifu1.CurNode.Value.ToKyokumenConst.KaisiPside, ittesasuResult.Get_SyuryoNode_OrNull.Value.ToKyokumenConst.KaisiPside); Util_IttesasuRoutine.After3_ChangeCurrent( kifu1, ConvMoveStrSfen.ToMoveStrSfen(ittesasuResult.Get_SyuryoNode_OrNull.Key),// nextMoveStr, ittesasuResult.Get_SyuryoNode_OrNull ); // これで、棋譜ツリーに、構造変更があったはず。 //↑↑一手指し } string sfen; if (kifu1.CurNode.IsRoot()) { sfen = UtilCsaMove.ToSfen(csaMove, null); } else { sfen = UtilCsaMove.ToSfen(csaMove, kifu1.CurNode.GetParentNode().Value.KyokumenConst); } HonpuMoveListItemImpl listItem = new HonpuMoveListItemImpl(csaMove, sfen); uc_Main.LstMove.Items.Add(listItem); } //---------------------------------------- // ソート //---------------------------------------- //List<MoveListItemImpl> list = new List<MoveListItemImpl>(); //list.Sort((MoveListItemImpl a, MoveListItemImpl b) => //{ // return a - b; //}); }
/// <summary> /// 指し手の順位を変えるループです。 /// </summary> /// <param name="out_pushCount"></param> /// <param name="out_isEndAutoLearn"></param> /// <param name="ref_isRequest_ShowGohosyu"></param> /// <param name="ref_isRequest_ChangeKyokumenPng"></param> /// <param name="ref_isRequestDoEvents"></param> /// <param name="loopLimit"></param> /// <param name="ref_tyoseiryo"></param> /// <param name="sfenMoveStr"></param> /// <param name="uc_Main"></param> /// <param name="logTag"></param> public static void DoSortMoveRush( out int out_pushCount, out bool out_isEndAutoLearn, ref bool ref_isRequest_ShowGohosyu, ref bool ref_isRequest_ChangeKyokumenPng, ref bool ref_isRequestDoEvents, int loopLimit, ref float ref_tyoseiryo, string sfenMoveStr, Uc_Main uc_Main ) { out_isEndAutoLearn = false; out_pushCount = 0; for (; out_pushCount < loopLimit; out_pushCount++) { //指し手順位更新ループ //---------------------------------------- // 強制中断(ループの最初のうちに) //---------------------------------------- // // 「Stop_learning.txt」という名前のファイルが .exe と同じフォルダーに置いてあると // 学習を終了することにします。 // if (uc_Main.StopLearning.IsStop()) { out_isEndAutoLearn = true; goto gt_EndMethod; } // 順位確認 if (0 < uc_Main.LstGohosyu.Items.Count) { GohosyuListItem gohosyuItem = (GohosyuListItem)uc_Main.LstGohosyu.Items[0]; if (sfenMoveStr == gohosyuItem.Sfen) { // 1位なら終了 Logger.Trace($"items.Count=[{uc_Main.LstGohosyu.Items.Count}] sfenMoveStr=[{sfenMoveStr}] gohosyuItem.Sfen=[{gohosyuItem.Sfen}]"); break; } } // 1位ではないのでランクアップ。 Util_LearnFunctions.Do_RankUpHonpu(ref ref_isRequest_ShowGohosyu, uc_Main, sfenMoveStr, ref_tyoseiryo); // 調整量の自動調整 if (uc_Main.ChkTyoseiryoAuto.Checked) { Util_Tyoseiryo.Up_Bairitu_AtStep(ref ref_isRequestDoEvents, uc_Main, out_pushCount, ref ref_tyoseiryo); } if (uc_Main.ChkStartZero.Checked)// 自動で、平手初期局面の点数を 0 点に近づけるよう調整します。 { Util_StartZero.Adjust_HirateSyokiKyokumen_0ten_AndFvParamRange(ref ref_isRequestDoEvents, uc_Main.LearningData.Fv); } // 局面の表示を更新します。 if (ref_isRequest_ShowGohosyu) { // 合法手一覧を更新 Util_LearningView.Aa_ShowGohosyu2(uc_Main.LearningData, uc_Main); // 局面PNG画像の更新は、ここでは行いません。 ref_isRequest_ShowGohosyu = false; ref_isRequestDoEvents = true; } if (ref_isRequestDoEvents) { Application.DoEvents(); ref_isRequestDoEvents = false; } }// 指し手順位更新ループ //---------------------------------------- // 連打終わり //---------------------------------------- gt_EndMethod: ; }
/// <summary> /// FVの保存。 /// </summary> /// <param name="uc_Main"></param> public static void Do_Save(Uc_Main uc_Main) { FeatureVector fv = uc_Main.LearningData.Fv; // ファイルチューザーで指定された、fvフォルダーのパス string fvFolderPath = Path.GetDirectoryName(uc_Main.TxtFvFilepath.Text); // ファイルチューザーで指定された、Dataフォルダーのパス(fvフォルダーの親) string dataFolderPath = Directory.GetParent(fvFolderPath).FullName; //---------------------------------------- // 時間 //---------------------------------------- string ymd; string hms; { DateTime dt = DateTime.Now; // 年月日 { StringBuilder sb = new StringBuilder(); sb.Append(dt.Year); sb.Append("-"); sb.Append(dt.Month); sb.Append("-"); sb.Append(dt.Day); ymd = sb.ToString(); uc_Main.TxtAutosaveYMD.Text = ymd; } // 時分秒 { StringBuilder sb = new StringBuilder(); sb.Append(dt.Hour); sb.Append("-"); sb.Append(dt.Minute); sb.Append("-"); sb.Append(dt.Second); hms = sb.ToString(); uc_Main.TxtAutosaveHMS.Text = hms; } } //---------------------------------------- // バックアップ //---------------------------------------- // // 失敗した場合、バックアップせず続行します // { // バックアップの失敗判定 bool backup_failuer = false; // フォルダーのリネーム try { string srcPath = Path.Combine(dataFolderPath, "fv"); string dstPath = Path.Combine(dataFolderPath, $"fv_{ymd}_{hms}"); Directory.Move(srcPath, dstPath); } catch (IOException) { // フォルダーを、Windowsのファイル・エクスプローラーで開いているなどすると、失敗します。 backup_failuer = true; } if (!backup_failuer) { // fvフォルダーの新規作成 Directory.CreateDirectory(fvFolderPath); } } //---------------------------------------- // -999~999 に調整 //---------------------------------------- Util_LearnFunctions.FvParamRange_PP(uc_Main.LearningData.Fv);// 自動で -999~999(*bairitu) に矯正。 // 駒割 File.WriteAllText(uc_Main.TxtFvFilepath.Text, Format_FeatureVector_Komawari.Format_Text(fv)); // スケール Util_FeatureVectorOutput.Write_Scale(uc_Main.EngineConf, fv, fvFolderPath); // KK Util_FeatureVectorOutput.Write_KK(uc_Main.EngineConf, fv, fvFolderPath); // 1pKP,2pKP Util_FeatureVectorOutput.Write_KP(uc_Main.EngineConf, fv, fvFolderPath); // PP 盤上 Util_FeatureVectorOutput.Write_PP_Banjo(uc_Main.EngineConf, fv, fvFolderPath); // PP 19枚の持駒 Util_FeatureVectorOutput.Write_PP_19Mai(uc_Main.EngineConf, fv, fvFolderPath); // PP 5枚の持駒、3枚の持駒 Util_FeatureVectorOutput.Write_PP_5Mai(uc_Main.EngineConf, fv, fvFolderPath); Util_FeatureVectorOutput.Write_PP_3Mai(uc_Main.EngineConf, fv, fvFolderPath); }
/// <summary> /// 本譜の手をランクアップ。 /// </summary> public static void Do_RankUpHonpu(ref bool ref_isRequestShowGohosyu, Uc_Main uc_Main, string sfenMoveStr, float tyoseiryo) { //---------------------------------------- // 1P は正の数がグッド、2P は負の数がグッド。 //---------------------------------------- float tyoseiryo_bad = -tyoseiryo; //減点に使われる数字です。[局面評価更新]ボタンの場合。 float tyoseiryo_good = 0.0f; //加点に使われる数字です。 float badScore_temp = tyoseiryo_bad; if (uc_Main.LearningData.Kifu.CurNode.Value.KyokumenConst.KaisiPside == Playerside.P2) { tyoseiryo_bad *= -1.0f;//2Pは、負数の方が高得点です。 } // // 合法手一覧 // uc_Main.LearningData.Kifu.CurNode.Foreach_ChildNodes((string key, Node <IMove, KyokumenWrapper> node, ref bool toBreak) => { // 本譜手はまだ計算しない。 if (key == sfenMoveStr) { goto gt_NextLoop1; } // 盤上の駒、持駒を数えます。 N54List childNode_n54List = Util_54List.Calc_54List(node.Value.KyokumenConst); float real_tyoseiryo; //実際に調整した量。 Util_FvScoreing.UpdateKyokumenHyoka( childNode_n54List, node.Value.KyokumenConst, uc_Main.LearningData.Fv, tyoseiryo_bad, out real_tyoseiryo );//相手が有利になる点 tyoseiryo_good += -real_tyoseiryo; gt_NextLoop1: ; }); // // 本譜手 // if (uc_Main.LearningData.Kifu.CurNode.HasChildNode(sfenMoveStr)) { // 盤上の駒、持駒を数えます。 N54List currentNode_n54List = Util_54List.Calc_54List(uc_Main.LearningData.Kifu.CurNode.Value.KyokumenConst); float real_tyoseiryo; //実際に調整した量。 Util_FvScoreing.UpdateKyokumenHyoka( currentNode_n54List, uc_Main.LearningData.Kifu.CurNode.GetChildNode(sfenMoveStr).Value.KyokumenConst, uc_Main.LearningData.Fv, tyoseiryo_good, out real_tyoseiryo );//自分が有利になる点 } else { Debug.Fail($"指し手[{sfenMoveStr}]に対応する次ノードは作成されていませんでした。\n" + uc_Main.LearningData.DumpToAllGohosyu( uc_Main.LearningData.Kifu.CurNode.Value.KyokumenConst)); } ////---------------------------------------- //// 合法手一覧を作成したい。 ////---------------------------------------- //uc_Main.LearningData.Aa_Yomi(uc_Main.LearningData.Kifu.CurNode.Key); // 局面の合法手表示の更新を要求します。 ref_isRequestShowGohosyu = true; }