/// <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> /// 54駒のリスト。 /// /// 盤上の40駒リスト。 /// 駒台の14駒リスト。 /// </summary> public static N54List Calc_54List(SkyConst src_Sky) { N54List result_n54List = new N54ListImpl(); //---------------------------------------- // インナー・メソッド用 集計変数 //---------------------------------------- int p54Next = 0; int[] p54List = new int[54]; src_Sky.Foreach_Starlights((Finger finger, IMoveHalf light, ref bool toBreak) => { RO_Star koma = Util_Starlightable.AsKoma(light.Now); //---------------------------------------- // まず、p を調べます。 //---------------------------------------- if (Conv_SyElement.ToOkiba(koma.Masu) == Okiba.ShogiBan) { int pIndex = FeatureVectorImpl.CHOSA_KOMOKU_ERROR;// 調査項目P1 //---------------------------------------- // 盤上の駒 //---------------------------------------- Conv_FvKoumoku525.ToPIndex_FromBanjo_PsideKomasyuruiMasu(koma.Pside, koma.Komasyurui, koma.Masu, out pIndex); if (FeatureVectorImpl.CHOSA_KOMOKU_ERROR == pIndex) { // p1 がエラーでは、処理は続けられない。 Util_54List.Panic1(koma); goto gt_NextLoop_player1; } //---------------------------------------- // 盤上の駒だぜ☆! //---------------------------------------- p54List[p54Next] = pIndex; p54Next++; } else if ( Conv_SyElement.ToOkiba(koma.Masu) == Okiba.Sente_Komadai || Conv_SyElement.ToOkiba(koma.Masu) == Okiba.Gote_Komadai) { int pIndex = FeatureVectorImpl.CHOSA_KOMOKU_ERROR;// 調査項目P1 //---------------------------------------- // 持ち駒 //---------------------------------------- PieceType motiKomasyurui = koma.ToNarazuCase();//例:駒台に馬はない。角の数を数える。 // 駒の枚数 int maisu = Util_Sky_FingersQuery.InOkibaKomasyuruiNow(src_Sky, Conv_Playerside.ToKomadai(koma.Pside), motiKomasyurui).Items.Count; Conv_FvKoumoku525.ToPIndex_FromMoti_PsideKomasyuruiMaisu(koma.Pside, motiKomasyurui, maisu, out pIndex); if (FeatureVectorImpl.CHOSA_KOMOKU_ERROR == pIndex) { // p1 がエラーでは、処理は続けられない。 Util_54List.Panic1(koma); goto gt_NextLoop_player1; } //---------------------------------------- // 駒台の駒だぜ☆! //---------------------------------------- p54List[p54Next] = pIndex; p54Next++; } gt_NextLoop_player1: ; }); result_n54List.SetP54List_Unsorted(p54List); result_n54List.SetP54Next(p54Next); return(result_n54List); }
/// <summary> /// 平手初期局面が -100点~+100点 に収まるように調整します。 /// /// 7回だけ調整します。 /// /// [0]回目: 順位を 64 ずらす。 /// [1]回目: 順位を 32 ずらす。 /// [2]回目: 順位を 16 ずらす。 /// [3]回目: 順位を 8 ずらす。 /// [4]回目: 順位を 4 ずらす。 /// [5]回目: 順位を 2 ずらす。 /// [6]回目: 順位を 1 ずらす。 /// /// これで、1方向に最長で(順位換算で) 130 ほどずれます。 /// /// </summary> public static void Adjust_HirateSyokiKyokumen_0ten_AndFvParamRange( ref bool ref_isRequestDoEvents, FeatureVector fv) { if (null == Util_StartZero.src_Sky_hirateSyokikyokumen) { // 平手初期局面 Util_StartZero.src_Sky_hirateSyokikyokumen = SkyConst.NewInstance( Util_SkyWriter.New_Hirate(Playerside.P1), 0 // 初期局面は 0手目済み ); } if (null == Util_StartZero.n54List_hirateSyokikyokumen) { //---------------------------------------- // 40枚の駒、または14種類の持駒。多くても54要素。 //---------------------------------------- Util_StartZero.n54List_hirateSyokikyokumen = Util_54List.Calc_54List(Util_StartZero.src_Sky_hirateSyokikyokumen); } Hyokakansu_NikomaKankeiPp kansu = new Hyokakansu_NikomaKankeiPp(); //-------------------------------------------------------------------------------- // Check //-------------------------------------------------------------------------------- // // 平手初期局面の点数を調べます。 // float score; #if DEBUG || LEARN KyHyokaMeisai_Koumoku meisaiKoumoku_orNull; #endif kansu.Evaluate( out score, #if DEBUG || LEARN out meisaiKoumoku_orNull, #endif Util_StartZero.src_Sky_hirateSyokikyokumen, fv ); if (-100 <= score && score <= 100) { // 目標達成。 goto gt_Goal; } for (int iCount = 0; iCount < 7; iCount++)//最大で7回調整します。 { // 初期局面の評価値が、-100~100 よりも振れていれば、0 になるように調整します。 //-------------------------------------------------------------------------------- // 点数を、順位に変換します。 //-------------------------------------------------------------------------------- Util_Ranking.Perform_Ranking(fv); // // 調整量 // int chosei_offset = Util_StartZero.tyoseiryo[iCount];// 調整量を、調整します。どんどん幅が広くなっていきます。 if (-100 <= score && score <= 100) { // 目標達成。 goto gt_Goal; } else if (100 < score)// ±0か、マイナスに転じさせたい。 { chosei_offset *= -1; } int changedCells; Util_FvScoreing.Fill54x54_Add(out changedCells, chosei_offset, src_Sky_hirateSyokikyokumen, fv, Util_StartZero.n54List_hirateSyokikyokumen); // 順位を、点数に変換します。 Util_Zooming.ZoomTo_FvParamRange(fv); // フォームの更新を要求します。 ref_isRequestDoEvents = true; //-------------------------------------------------------------------------------- // Check //-------------------------------------------------------------------------------- // // 平手初期局面の点数を調べます。 // kansu.Evaluate( out score, #if DEBUG || LEARN out meisaiKoumoku_orNull, #endif Util_StartZero.src_Sky_hirateSyokikyokumen, fv ); if (-100 <= score && score <= 100) { // 目標達成。 goto gt_Goal; } // 目標を達成していないなら、ループを繰り返します。 } gt_Goal: ; }
/// <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; }