Example #1
0
        /// <summary>
        /// 二駒関係を読込むぜ☆(^▽^)
        /// </summary>
        public static void Load_Nikoma(StringBuilder syuturyoku)
        {
            if (IsEnableBoardSize())
            {
                syuturyoku.Append("二駒関係ファイル読込中");
                {
                    var msg = syuturyoku.ToString();
                    syuturyoku.Clear();
                    Logger.Flush(msg);
                }

                // ファイル名☆(^▽^)
                string file = $"_auto_nikoma{(Option_Application.Optionlist.SagareruHiyoko ? Logger.LocalRuleSagareruHiyoko : Logger.LocalRuleHonshogi)}.txt";

                syuturyoku.Append(".");
                {
                    var msg = syuturyoku.ToString();
                    syuturyoku.Clear();
                    Logger.Flush(msg);
                }

                if (File.Exists(file))//定跡ファイルがある場合のみ、定跡を使うぜ☆(^▽^)
                {
                    Util_NikomaKankei.Parse(System.IO.File.ReadAllText(file));
                }

                syuturyoku.AppendLine("☆");
                {
                    var msg = syuturyoku.ToString();
                    syuturyoku.Clear();
                    Logger.Flush(msg);
                }
            }
        }
Example #2
0
        /// <summary>
        /// 二駒関係を書き出すぜ☆(^▽^)
        /// </summary>
        public static void Flush_Nikoma(StringBuilder syuturyoku)
        {
            if (IsEnableBoardSize() && Util_NikomaKankei.Edited)
            {
                syuturyoku.Append("二駒関係ファイル書出中");
                {
                    var msg = syuturyoku.ToString();
                    syuturyoku.Clear();
                    Logger.Flush(msg);
                }

                // 容量がでかくなったので、複数のファイルに分割して保存するぜ☆(^▽^)

                // 残すべきファイル名☆(^▽^)
                string file = $"_auto_nikoma{(Option_Application.Optionlist.SagareruHiyoko ? Logger.LocalRuleSagareruHiyoko : Logger.LocalRuleHonshogi)}.txt";
                if (!File.Exists(file))
                {
                    // ファイルが無ければ作成します。
                    FileStream fs = File.Create(file);
                    fs.Close(); // File.Create したあとは、必ず Close() しないと、ロックがかかったままになる☆(^▽^)
                }

                syuturyoku.Append(".");
                {
                    var msg = syuturyoku.ToString();
                    syuturyoku.Clear();
                    Logger.Flush(msg);
                }

                // 定跡の文字列化☆
                StringBuilder nikomaMojiretu = new StringBuilder();
                Util_NikomaKankei.ToString(nikomaMojiretu);

                syuturyoku.Append(".");
                {
                    var msg = syuturyoku.ToString();
                    syuturyoku.Clear();
                    Logger.Flush(msg);
                }

                // 上書き☆
                System.IO.File.WriteAllText(file, nikomaMojiretu.ToString());

                syuturyoku.AppendLine("☆");
                {
                    var msg = syuturyoku.ToString();
                    syuturyoku.Clear();
                    Logger.Flush(msg);
                }
                Util_NikomaKankei.Edited = false;
            }
        }
Example #3
0
        /// <summary>
        /// 評価値の計算し直し。
        ///
        /// 多対多の項目の組み合わせを全部加算。
        /// </summary>
        /// <param name="ky"></param>
        /// <returns>手番の視点で返す</returns>
        public void KeisanSinaosi(Kyokumen ky)
        {
            // 駒の位置(評価関数の項目番号)をリストに入れておくぜ☆
            Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1);

            // 評価値
            int hyokati = 0;

            for (int iGyoIndex = 0; iGyoIndex < Util_NikomaKankei.KoumokuBangoHairetu1.Nagasa; iGyoIndex++)
            {
                for (int iRetuIndex = 0; iRetuIndex < Util_NikomaKankei.KoumokuBangoHairetu1.Nagasa; iRetuIndex++)
                {
                    if (Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex] <= Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex])// 組み合わせを反対から見ただけの同じものを弾くぜ☆(^~^)
                    {
                        continue;
                    }

                    // 差分更新と比較するので、差分更新用☆(^~^)
                    //hyokati += Util_NikomaKankei.GetHyokaNumber_SabunKosinYou(Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex], Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex]);
                    // (^▽^)関数(小さい数字,大きい数字)だぜ☆ そうでなければ逆立ちさせるぜ☆(^▽^)www
                    if (Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex] < Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex])
                    {
                        hyokati += Util_NikomaKankei.GetHyokaNumber_SabunKosinYou(Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex], Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex]);
                    }
                    else if (Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex] < Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex])
                    {
                        // 逆立ち☆(^▽^)www
                        hyokati += Util_NikomaKankei.GetHyokaNumber_SabunKosinYou(Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex], Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex]);
                    }
                }
            }

            if (hyokati < Util_NikomaKankei.SAISYO_HYOKATI_SABUNKOSINYOU)
            {
                hyokati = Util_NikomaKankei.SAISYO_HYOKATI_SABUNKOSINYOU;
            }
            else if (Util_NikomaKankei.SAIDAI_HYOKATI_SABUNKOSINYOU < hyokati)
            {
                hyokati = Util_NikomaKankei.SAIDAI_HYOKATI_SABUNKOSINYOU;
            }

            var(exists, phase) = ky.CurrentOptionalPhase.Match;
            if (exists)
            {
                if (phase == Phase.White)
                {
                    hyokati = -hyokati; // 対局者2視点に変えるぜ☆(^▽^)
                }
            }
            Hyokati = (Hyokati)hyokati;
        }
Example #4
0
 /// <summary>
 /// 反映するぜ☆(^▽^)
 /// </summary>
 /// <param name="ky"></param>
 /// <param name="mk"></param>
 /// <param name="ninsyo"></param>
 public void HaneiMotiKoma(Kyokumen ky, MotiKoma mk)
 {
     if (DebugOptions.EvaluationHand)
     {
         // 駒の位置(評価関数の項目番号)☆ 持ち駒が 0 枚で、-1 の場合もあり☆
         int koumokuNo = Util_NikomaKankei.GetKoumokuBango_MotiKoma(ky, mk);
         if (-1 != koumokuNo)
         {
             Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1);
             Increase(
                 Util_NikomaKankei.Kazoeru_NikomaKankeiHyokati_ItiTaiTa_SabunKosinYou(ky, koumokuNo, Util_NikomaKankei.KoumokuBangoHairetu1
                                                                                      )
                 );
         }
     }
 }
Example #5
0
        /// <summary>
        /// 差分更新は、対局者1 の視点の盤で行えなんだぜ☆(^▽^)
        /// </summary>
        /// <param name="ky"></param>
        /// <param name="km"></param>
        /// <param name="ms"></param>
        /// <param name="fueta"></param>
        public void FuyasuBanjoKoma(Kyokumen ky, Koma km, Masu ms)
        {
            if (DebugOptions.AddPiecesOnBoard)
            {
                var optionalPiece = OptionalPiece.From(km);

                Debug.Assert(Conv_Koma.IsOk(optionalPiece), "");//空白とか禁止☆(^~^)!

                Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1);

                Increase(
                    Util_NikomaKankei.Kazoeru_NikomaKankeiHyokati_ItiTaiTa_SabunKosinYou(ky,
                                                                                         Util_NikomaKankei.GetKoumokuBango_Banjo(ky, km, ms),// 駒の位置(評価関数の項目番号)をリストに入れておくぜ☆
                                                                                         Util_NikomaKankei.KoumokuBangoHairetu1
                                                                                         ));
            }
        }
Example #6
0
        public void KesuMotiKoma(Kyokumen ky, MotiKoma mk)
        {
            if (DebugOptions.ReduceHand)
            {
                // 駒の位置(評価関数の項目番号)☆ 持ち駒が 0 枚で、-1 の場合もあり☆
                int koumokuNo = Util_NikomaKankei.GetKoumokuBango_MotiKoma(ky, mk);
                // Debug.Assert(koumokuNo != -1, $"mk=[{mk}]");

                // 減点するぜ☆(^▽^)
                if (-1 != koumokuNo)
                {
                    Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1);

                    Increase((Hyokati)(
                                 -(int)Util_NikomaKankei.Kazoeru_NikomaKankeiHyokati_ItiTaiTa_SabunKosinYou(ky, koumokuNo, Util_NikomaKankei.KoumokuBangoHairetu1)//評価値
                                 ));
                }
            }
        }
Example #7
0
        /// <summary>
        /// 評価値を更新するぜ☆(^▽^)
        /// </summary>
        /// <param name="erandaSasite">実際に選んだ指し手☆</param>
        /// <param name="erandaHyokati">実際に選んだ手の評価値☆</param>
        public static void Update(Move erandaSasite, Hyokati erandaHyokati, Kyokumen ky, StringBuilder syuturyoku)
        {
            JosekiKyokumen joKy_orNull = Option_Application.Joseki.GetKyokumen(Util_KikaiGakusyu.KaisiKyHash);

            if (null == joKy_orNull)// この局面の定跡データが入っていなければ、そもそも 学習できないぜ☆(^▽^)
            {
                return;
            }


            // 成績表を見て、現局面で最も勝率の高い指し手を、教師とするぜ☆(^~^)

            Move kyosiSs = Option_Application.Seiseki.GetSasite_Winest(ky, out float kyosiSyoritu_notUse);

            Hyokati kyosiHyokati;                                         // 教師の手の評価値☆

            if (Util_KikaiGakusyu.FirstAndHappaFens.ContainsKey(kyosiSs)) // 教師の手はあるはずだろ☆(^~^)?
            {
                // まず、一手指すぜ☆
                Nanteme nanteme = new Nanteme();
                ky.DoMove(Option_Application.Optionlist.USI, kyosiSs, MoveType.N00_Karappo, ref nanteme, ky.CurrentOptionalPhase, syuturyoku);

                // 評価値を調べようぜ☆(^▽^)
                Hyokati komawariHyokati = ky.Komawari.Get(ky.CurrentOptionalPhase);
                Hyokati nikomaHyokati   = ky.Nikoma.Get(true);
                kyosiHyokati = (int)komawariHyokati + nikomaHyokati;


                // 一手戻そうぜ☆(^▽^)
                ky.UndoMove(Option_Application.Optionlist.USI, kyosiSs, syuturyoku);
            }
            else
            {
                return;
            }
            // 教師の手の評価値が、一番高いとは限らないぜ☆(^~^)

            if (!Conv_Hyokati.InHyokati(kyosiHyokati))
            {
                // 教師の評価値が、メートの数字などになっている場合は、学習はできないぜ☆(>_<)
                return;
            }



            Kyokumen happaKy = new Kyokumen();
            int      caret_temp2;
            double   sumSigmoidY = 0.0d;// 積分☆


            // 深さが異なるので、自分の局面、相手の局面 の数も異なり、
            // 足す局面と、引く局面の数が合わなくなるぜ☆(^~^)
            // ↓
            // せっかく 1P、2P の評価値を持っているのだから、
            // 1P から引いた分は 2P に足す、ということでどうか☆(^~^)?


            // では、今回の合法手を全て見ていくぜ☆(^~^)
            foreach (KeyValuePair <Move, List <string> > entry in Util_KikaiGakusyu.FirstAndHappaFens)
            {
                if (entry.Key == kyosiSs)
                {
                    // 教師の手は、今回はスルーするぜ☆(^▽^)
                    continue;
                }
                // さて、教師以外の手だが……☆(^~^)

                HyokatiUtiwake sonotanoTe_hyokatiUtiwake;

                // まず、一手指すぜ☆
                Nanteme nanteme = new Nanteme();
                ky.DoMove(Option_Application.Optionlist.USI, entry.Key, MoveType.N00_Karappo, ref nanteme, ky.CurrentOptionalPhase, syuturyoku);

                // 評価値を調べようぜ☆(^▽^)
                ky.Hyoka(out sonotanoTe_hyokatiUtiwake, HyokaRiyu.Yososu, true// ランダムな局面で学習したりもするし☆(^~^)
                         );

                // 一手戻そうぜ☆(^▽^)
                ky.UndoMove(Option_Application.Optionlist.USI, entry.Key, syuturyoku);

                if (!Conv_Hyokati.InHyokati(sonotanoTe_hyokatiUtiwake.EdaBest))
                {
                    // その他の手の評価値が、メートの数字などになっている場合は、学習はできないぜ☆(>_<)
                    continue;
                }

                // 教師の手と、それ以外の手の 評価値の差を、
                // シグモイドの x に当てはめて、y を求めるぜ☆
                double sigmoidY = Option_Application.Optionlist.NikomaGakusyuKeisu * Util_Sigmoid.Sigmoid(erandaHyokati - kyosiHyokati);
                // 教師の手(=一番評価値が高い手)より 評価値が上回っている手は、
                // すると、 0.5 < y < 1 となるな☆
                // 下回っていれば、
                // 0 < y < 0.5 となるな☆

                var(exists1, phase1) = Util_Tansaku.StartingPhase.Match;
                var(exists2, phase2) = happaKy.CurrentOptionalPhase.Match;

                // この点数を、葉 から かき集めるぜ☆www(^▽^)
                foreach (string happaFen in entry.Value)
                {
                    caret_temp2 = 0;
                    happaKy.ParsePositionvalue(Option_Application.Optionlist.USI, happaFen, ref caret_temp2, false, false, out string moves, syuturyoku);

                    // この局面の2駒関係を、シグモイドの y 点分、下げるぜ☆
                    sumSigmoidY += Util_NikomaKankei.DecrementParamerter_KikaiGakusyu(
                        happaKy,
                        (exists1 && exists2 && phase1 == phase2) ? -sigmoidY : sigmoidY//自分の手番なら 引く☆
                        );
                }
            }

            // 下げてかき集めた シグモイドの y の量を、
            // 教師の指し手の葉に 山分けするぜ☆(^▽^)
            double yamawake = sumSigmoidY / (double)Util_KikaiGakusyu.FirstAndHappaFens[kyosiSs].Count;

            foreach (string happaFen in Util_KikaiGakusyu.FirstAndHappaFens[kyosiSs])// 教師の手はあるはずだろ☆(^~^)?
            {
                caret_temp2 = 0;
                happaKy.ParsePositionvalue(Option_Application.Optionlist.USI, happaFen, ref caret_temp2, false, false, out string moves, syuturyoku);

                var(exists1, phase1) = Util_Tansaku.StartingPhase.Match;
                var(exists2, phase2) = happaKy.CurrentOptionalPhase.Match;

                // 各葉に 山分けだぜ☆(^~^)
                Util_NikomaKankei.IncrementParamerter_KikaiGakusyu(
                    happaKy,
                    (exists1 && exists2 && phase1 == phase2) ? -yamawake : yamawake//自分の手番なら 足すぜ☆
                    );
            }
        }