Пример #1
0
        /// <summary>
        /// 調整量を、54要素リストの要素に均等に分配できる数にします。
        /// </summary>
        /// <param name="value">調整量</param>
        /// <param name="n40t14List">パラメーターの数を調べるのに利用。</param>
        /// <returns></returns>
        public static float Average_54x54Parameters(float value, N54List n54List)
        {
            float kizami;//刻んだ数。

            // 表を三角形に使うので、正方形から1辺分(対角ライン)を引き、2で割る。
            float nikomaKankeiPatternSu = (n54List.P54Next * (n54List.P54Next - 1)) / 2; //二駒関係のP×Pのパターン数。

            kizami = value * 1.0f / nikomaKankeiPatternSu;

            return(kizami);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <summary>
        /// 指定した局面の評価を、加点(減点)します。
        /// </summary>
        public static void UpdateKyokumenHyoka(
            N54List n54List,
            SkyConst src_Sky,
            FeatureVector fv_mutable,
            float tyoseiryo,
            out float out_real_tyoseiryo//実際に調整した量。
            )
        {
            //
            // 盤上の駒数と、持駒の先後の種類数
            //
            //int banjoKomaKazu_motiSyuruiKazu = 0;

            // 増 or 減
            {
                // 調整量を刻みます。
                float kizami_up = Util_Tyoseiryo.Average_54x54Parameters(tyoseiryo, n54List);

                int changedCells;
                Util_FvScoreing.Fill54x54_Add(out changedCells, kizami_up, src_Sky, fv_mutable, n54List);
                out_real_tyoseiryo = changedCells * kizami_up;
            }

            // 持ち駒の BAD値を矯正 FIXME: 持ち駒を打つのが悪手なのは、だいたい合っているのでは?
            //if(false)
            //{
            //    float sum_bad = Util_FvScoreing.Spoil_MotiBad(src_Sky.KaisiPside, fv_mutable, n54List);

            //    // 盤上の三駒関係に、均等に BAD値 を配分。
            //    Util_FvScoreing.Fill54x54_Add_ToBanjo(
            //        sum_bad / (float)n54List.P40Next,//平均にする
            //        src_Sky,
            //        fv_mutable,
            //        n54List,
            //        logTag
            //        );
            //}
        }
Пример #4
0
        /// <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:
            ;
        }
Пример #5
0
        ///// <summary>
        ///// 2駒関係の54要素で、持ち駒に関係する箇所のうち、
        ///// バッドな点が入っているものは 全て吸い取って 0 点にします。
        ///// 吸い取った バッド点 を返却します。
        ///// </summary>
        //public static float Spoil_MotiBad( Playerside selfPside, FeatureVector fv_mutable, N54List n54List, IErrorController logTag)
        //{
        //    float result_sum = 0;

        //    //----------------------------------------
        //    // [PP] 駒台の各駒1 × 盤上の各駒2
        //    //----------------------------------------
        //    for (int iNext1 = 0; iNext1 < n54List.P14Next; iNext1++)// p1 を回す。
        //    {
        //        int p1 = n54List.P14List[iNext1];


        //        for (int iNext2 = 0; iNext2 < n54List.P40Next; iNext2++)// p2 を回す。
        //        {
        //            int p2 = n54List.P40List[iNext2];

        //            //----------------------------------------
        //            // よし、2駒関係だぜ☆!
        //            //----------------------------------------
        //            if (
        //                // プレイヤー1で、piece1 がPlayer1駒で、その点が後手寄りのとき。
        //                (Playerside.P1 == selfPside && p1 < Const_NikomaKankeiP_ParamIx.PLAYER2 && fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] < 0.0f)
        //                // または、
        //                ||
        //                // プレイヤー2で、piece1 がPlayer2駒で、その点が先手寄りのとき。
        //                (Playerside.P2 == selfPside && Const_NikomaKankeiP_ParamIx.PLAYER2 <= p1 && 0.0f < fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] )
        //                )
        //            {

        //                result_sum += fv_mutable.NikomaKankeiPp_ForMemory[p1, p2];
        //                fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] = 0;
        //            }
        //        }
        //    }

        //    //----------------------------------------
        //    // [PP] 盤上の各駒1 × 駒台の各駒2
        //    //----------------------------------------
        //    for (int iNext1 = 0; iNext1 < n54List.P40Next; iNext1++)// p1 を回す。
        //    {
        //        int p1 = n54List.P40List[iNext1];


        //        for (int iNext2 = 0; iNext2 < n54List.P14Next; iNext2++)// p2 を回す。
        //        {
        //            int p2 = n54List.P14List[iNext2];

        //            //----------------------------------------
        //            // よし、2駒関係だぜ☆!
        //            //----------------------------------------
        //            if (
        //                // プレイヤー1で、piece2 がPlayer1駒で、その点が後手寄りのとき。
        //                (Playerside.P1 == selfPside && p2 < Const_NikomaKankeiP_ParamIx.PLAYER2 && fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] < 0.0f)
        //                // または、
        //                ||
        //                // プレイヤー2で、piece2 がPlayer2駒で、その点が先手寄りのとき。
        //                (Playerside.P2 == selfPside && Const_NikomaKankeiP_ParamIx.PLAYER2 <= p2 && 0.0f < fv_mutable.NikomaKankeiPp_ForMemory[p1, p2])
        //                )
        //            {

        //                result_sum += fv_mutable.NikomaKankeiPp_ForMemory[p1, p2];
        //                fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] = 0.0f;
        //            }
        //        }
        //    }

        //    //----------------------------------------
        //    // [PP] 駒台の各駒1 × 駒台の各駒2
        //    //----------------------------------------
        //    //
        //    // FIXME: 持駒と、持駒の比較は、とりあえずパス。

        //    return result_sum;
        //}

        ///// <summary>
        ///// 2駒関係の54要素で表される箇所のうち、盤上の2駒に関する評価値に加算します。
        ///// </summary>
        //public static void Fill54x54_Add_ToBanjo(float offset, SkyConst src_Sky, FeatureVector fv_mutable, N54List n54List, IErrorController logTag)
        //{
        //    //----------------------------------------
        //    // [PP] 盤上の各駒1 × 盤上の各駒2
        //    //----------------------------------------
        //    for (int iNext1 = 0; iNext1 < n54List.P40Next; iNext1++)// p1 を回す。
        //    {
        //        int p1 = n54List.P40List[iNext1];


        //        for (int iNext2 = 0; iNext2 < n54List.P40Next; iNext2++)// p2 を回す。
        //        {
        //            int p2 = n54List.P40List[iNext2];

        //            //----------------------------------------
        //            // よし、2駒関係だぜ☆!
        //            //----------------------------------------
        //            fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] += offset;
        //        }
        //    }
        //}

        /// <summary>
        /// 2駒関係の54要素で表される箇所全ての評価値に加算します。
        /// </summary>
        public static void Fill54x54_Add(out int changedCells, float offset, SkyConst src_Sky, FeatureVector fv_mutable,
                                         N54List n54List)
        {
            changedCells = 0;

            //
            //
            // 例えば、[1P1三歩、2P2一桂]という組み合わせと、[2P2一桂、1P1三歩]という組み合わせは、同じだが欄が2つある。
            // そこで、表の半分を省きたい。
            // しかし、表を三角形にするためには、要素は昇順にソートされている必要がある。
            // 合法手1つごとにソートしていては、本末転倒。
            // そこで、表は正方形に読み、内容は三角形の部分にだけ入っているということにする。
            //
            //
            // 例えば、[1P1三歩、1P1三歩]という組み合わせもある。これは、自分自身の絶対位置の評価として試しに、残しておいてみる☆
            //
            //

            for (int iA = 0; iA < n54List.P54Next; iA++)// p1 を回す。
            {
                int p1 = n54List.P54List_unsorted[iA];

                for (int iB = 0; iB < n54List.P54Next; iB++)// p2 を回す。
                {
                    int p2 = n54List.P54List_unsorted[iB];

                    if (p1 <= p2) // 「p2 < p1」という組み合わせは同じ意味なので省く。「p1==p2」は省かない。
                    {
                        //----------------------------------------
                        // よし、組み合わせだぜ☆!
                        //----------------------------------------
                        fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] += offset;
                        changedCells++;//実際に調整した量。
                    }
                    else
                    {
                        //----------------------------------------
                        // 使っていない方の三角形だぜ☆!
                        //----------------------------------------
                        fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] = 0;
                    }
                }
            }


            ////----------------------------------------
            //// [PP] 盤上の各駒1 × 盤上の各駒2
            ////----------------------------------------
            //for (int iNext1 = 0; iNext1 < n54List.P40Next; iNext1++)// p1 を回す。
            //{
            //    int p1 = n54List.P40List[iNext1];


            //    for (int iNext2 = 0; iNext2 < n54List.P40Next; iNext2++)// p2 を回す。
            //    {
            //        int p2 = n54List.P40List[iNext2];

            //        fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] += offset;
            //        changedCells++;//実際に調整した量。

            //    }
            //}

            ////----------------------------------------
            //// [PP] 駒台の各駒1 × 盤上の各駒2
            ////----------------------------------------
            ////
            //// ※注 「盤上の各駒1 × 駒台の各駒2」の組み合わせは 同じ意味なので省く。
            ////
            //for (int iNext1 = 0; iNext1 < n54List.P14Next; iNext1++)// p1 を回す。
            //{
            //    int p1 = n54List.P14List[iNext1];


            //    for (int iNext2 = 0; iNext2 < n54List.P40Next; iNext2++)// p2 を回す。
            //    {
            //        int p2 = n54List.P40List[iNext2];

            //        //----------------------------------------
            //        // よし、2駒関係だぜ☆!
            //        //----------------------------------------
            //        fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] += offset;
            //        changedCells++;//実際に調整した量。
            //    }
            //}

            //////----------------------------------------
            ////// [PP] 盤上の各駒1 × 駒台の各駒2
            //////----------------------------------------
            ////for (int iNext1 = 0; iNext1 < n54List.P40Next; iNext1++)// p1 を回す。
            ////{
            ////    int p1 = n54List.P40List[iNext1];


            ////    for (int iNext2 = 0; iNext2 < n54List.P14Next; iNext2++)// p2 を回す。
            ////    {
            ////        int p2 = n54List.P14List[iNext2];

            ////        //----------------------------------------
            ////        // よし、2駒関係だぜ☆!
            ////        //----------------------------------------
            ////        fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] += offset;
            ////        changedCells++;//実際に調整した量。
            ////    }
            ////}

            ////----------------------------------------
            //// [PP] 駒台の各駒1 × 駒台の各駒2
            ////----------------------------------------
            //for (int iNext1 = 0; iNext1 < n54List.P14Next; iNext1++)// p1 を回す。
            //{
            //    int p1 = n54List.P14List[iNext1];


            //    for (int iNext2 = 0; iNext2 < n54List.P14Next; iNext2++)// p2 を回す。
            //    {
            //        int p2 = n54List.P14List[iNext2];

            //        if (p1 <= p2) // 「p2 < p1」という組み合わせは同じ意味なので省く。「p1==p2」は省かない。
            //        {
            //            //----------------------------------------
            //            // よし、組み合わせだぜ☆!
            //            //----------------------------------------
            //            fv_mutable.NikomaKankeiPp_ForMemory[p1, p2] += offset;
            //            changedCells++;//実際に調整した量。
            //        }
            //    }
            //}
        }
Пример #6
0
        /// <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;
        }