Esempio n. 1
0
        /// <summary>
        /// 読み筋を返すぜ☆(^~^)
        /// </summary>
        /// <param name="sentoNantemade">初期局面からのリンクリストなので、どの「図はn手まで」戻すか☆</param>
        /// <returns></returns>
        public void ScanYomisuji(bool isSfen, int sentoNantemade, StringBuilder syuturyoku)
        {
            // 先頭(投了、初期局面、図は0手まで)まで戻るぜ☆
            Nanteme nanteme = this;

            for (; null != nanteme.Ittemae; nanteme = nanteme.Ittemae)
            {
            }

            // 先頭から今までの読み筋をつなげるぜ☆(^▽^)
            int zuhaNantemade = 0; // 図はn手まで

            for (;
                 null != nanteme;// 一番最後まで回すぜ☆(^▽^)
                 nanteme = nanteme.Ittego)
            {
                if (sentoNantemade <= zuhaNantemade)
                {
                    // 「図はn手まで」の数字
                    syuturyoku.Append($"({zuhaNantemade})");
                    ConvMove.AppendFenTo(isSfen, nanteme.Move, syuturyoku);
                    syuturyoku.Append(" ");

                    // おまけ
                    syuturyoku.Append($"{AbstractConvMoveType.Setumei(nanteme.MoveType)} ");
                }
                zuhaNantemade++;
            }
        }
Esempio n. 2
0
        public static void Rnd(Kyokumen ky, StringBuilder syuturyoku)
        {
            int fukasa = 0;

            AbstractUtilMoveGen.GenerateMove01(fukasa, ky, MoveType.N21_All, true, syuturyoku);//グローバル変数に指し手がセットされるぜ☆(^▽^)
            if (AbstractUtilMoveGen.MoveList[fukasa].SslistCount < 1)
            {
                Nanteme nanteme = new Nanteme();
                ky.DoMove(Option_Application.Optionlist.USI, Move.Toryo, MoveType.N00_Karappo, ref nanteme, ky.CurrentOptionalPhase, syuturyoku);
            }
            else
            {
                Move    ss      = AbstractUtilMoveGen.MoveList[fukasa].ListMove[Option_Application.Random.Next(AbstractUtilMoveGen.MoveList[fukasa].SslistCount)];
                Nanteme nanteme = new Nanteme();
                ky.DoMove(Option_Application.Optionlist.USI, ss, MoveType.N00_Karappo, ref nanteme, ky.CurrentOptionalPhase, syuturyoku);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// 千日手の判定だぜ☆(^~^)反復した回数を返すぜ☆
        /// 千日手になったら数えるのを止めるぜ☆
        /// </summary>
        /// <returns></returns>
        public int GetSennititeCount()
        {
            ulong expected = this.SennititeHash;
            int   count    = 1;// 同じ局面が出た回数☆

            for (Nanteme nanteme = this.Ittemae; null != nanteme; nanteme = nanteme.Ittemae)
            {
                if (nanteme.SennititeHash == expected)
                {
                    count++;
                    if (Const_Game.SENNITITE_COUNT <= count)// 千日手だぜ☆(^~^)数えるのを止めるぜ☆
                    {
                        break;
                    }
                }
            }
            return(count);
        }
Esempio n. 4
0
        /// <summary>
        /// 何手目かを数えるぜ☆(^~^)
        /// </summary>
        /// <returns></returns>
        public int ScanNantemadeBango()
        {
            int nantemeBango = 0;

            // 先頭には投了(初期局面)が入っているぜ☆(^▽^)
            // 先頭の一手前はヌルだぜ☆

            // 先頭の投了(初期局面)まで戻るぜ☆
            Nanteme nanteme = this;

            for (; null != nanteme.Ittemae; nanteme = nanteme.Ittemae)
            {
                nantemeBango++;
            }
            // 初期局面は 0 手目と表示される計算だぜ☆(^▽^)

            return(nantemeBango);
        }
Esempio n. 5
0
        /// <summary>
        /// 指定の手目まで進めるぜ☆(^~^)
        /// </summary>
        /// <param name="temeMade"></param>
        /// <param name="ky"></param>
        /// <param name="syuturyoku"></param>
        public void GoToTememade(bool isSfen, int temeMade, Kyokumen ky, StringBuilder syuturyoku)
        {
            // 棋譜を元に、局面データを再現するぜ☆
            ky.Clear();
            int caret = 0;

            ky.ParsePositionvalue(isSfen, SyokiKyokumenFen, ref caret,
                                  true//適用
                                  , false, out string moves, syuturyoku
                                  );
            // 指定の手目まで進めるぜ☆(^~^)
            foreach (Move ss in SsList)
            {
                if (temeMade < 1)
                {
                    break;
                }
                Nanteme nanteme = new Nanteme();
                ky.DoMove(isSfen, ss, MoveType.N00_Karappo, ref nanteme, ky.CurrentOptionalPhase, syuturyoku);
                temeMade--;
            }
        }
Esempio n. 6
0
        /// <summary>
        /// 終局図まで進めるぜ☆(^~^)
        /// </summary>
        /// <param name="ky"></param>
        /// <param name="syuturyoku"></param>
        public void GoToFinish(bool isSfen, Kyokumen ky, StringBuilder syuturyoku)
        {
            ky.Clear();

            int caret = 0;

            ky.ParsePositionvalue(isSfen, SyokiKyokumenFen, ref caret,
                                  true//適用
                                  , false, out string moves, syuturyoku
                                  );

            // 棋譜を元に、局面データを再現するぜ☆
            foreach (Move ss in SsList)
            {
                Nanteme nanteme = new Nanteme();
                ky.DoMove(isSfen, ss, MoveType.N00_Karappo, ref nanteme, ky.CurrentOptionalPhase, syuturyoku);

#if DEBUG
                //Util_Commands.Ky(isSfen, "ky", ky, syuturyoku);
                ////Logger.Flush(syuturyoku);
                //Logger.Flush_USI(syuturyoku);
#endif
            }
        }
Esempio n. 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//自分の手番なら 足すぜ☆
                    );
            }
        }
Esempio n. 8
0
 /// <summary>
 /// 前の手目から引き継ぎたいものをここでコピーするぜ☆(^▽^)
 /// </summary>
 /// <param name="nanteme"></param>
 public void CopyPropertyFrom(Nanteme nanteme)
 {
 }