コード例 #1
0
        public static void Setumei_Discovered(Masu ms_removed, Kyokumen.Sindanyo kys, StringBuilder syuturyoku)
        {
            kys.TryInControl(ms_removed, out Koma[] kmHairetu_control);

            Bitboard bb_relative = new Bitboard();//関連のある飛び利き駒

            // 飛び利きを計算し直す
            foreach (Koma km in kmHairetu_control)
            {
                if (Koma.PieceNum == km)
                {
                    break;
                }

                // 駒の居場所
                Bitboard bb_ibasho = new Bitboard();
                kys.ToSetIbasho(km, bb_ibasho);
                while (bb_ibasho.Ref_PopNTZ(out Masu ms_ibasho))
                {
                    bb_relative.Standup(ms_ibasho);
                }
            }

            Setumei_1Bitboard("関連する飛び利き駒", bb_relative, syuturyoku);
        }
コード例 #2
0
        public static void Assert_Sabun_Komawari(string message, Kyokumen.Sindanyo kys, StringBuilder syuturyoku)
        {
            KomawariHyokatiSabunItiran saikeisan = new KomawariHyokatiSabunItiran();

            saikeisan.Tukurinaosi(kys);
            Hyokati hyokati1 = kys.GetKomawari(OptionalPhase.Black);
            Hyokati hyokati2 = kys.GetKomawari(OptionalPhase.White);
            bool    safe     =
                hyokati1 == saikeisan.Get(OptionalPhase.Black)
                &&
                hyokati2 == saikeisan.Get(OptionalPhase.White)
            ;
            string msg = $@"{message}#河馬 診断 駒割り評価値
P1差分  =[{hyokati1}]
  再計算=[{saikeisan.Get(OptionalPhase.Black)}]
P2差分  =[{hyokati2}]
  再計算=[{saikeisan.Get(OptionalPhase.White)}]
";

            if (!safe)
            {
                syuturyoku.AppendLine(msg);
                {
                    var msg2 = syuturyoku.ToString();
                    syuturyoku.Clear();
                    Logger.Flush(msg2);
                }
            }
            Debug.Assert(safe, msg);
        }
コード例 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static ulong GetTaikyokusyaKey(Option <Phase> optionalPhase, Kyokumen.Sindanyo kys)
        {
            if (Util_ZobristHashing.Dirty)
            {
                Util_ZobristHashing.Tukurinaosi(kys);
            }

            return(Util_ZobristHashing.m_tbTaikyokusya_[OptionalPhase.IndexOf(optionalPhase)]);
        }
コード例 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static ulong GetMotiKey(Kyokumen.Sindanyo kys, MotiKoma mk)
        {
            if (Util_ZobristHashing.Dirty)
            {
                Util_ZobristHashing.Tukurinaosi(kys);
            }

            return(Util_ZobristHashing.m_motiKeys_[(int)mk][kys.CountMotikoma(mk)]);
        }
コード例 #5
0
        /// <summary>
        /// 下側に自分の陣地がある視点の段番号だぜ☆(^▽^)
        /// 例:対局者1でも2でも、トライルールは らいおん が1段目に入ったときだぜ☆(^▽^)
        /// </summary>
        /// <param name="ms"></param>
        /// <returns></returns>
        public static int ToDan_JibunSiten(Option <Phase> optionalPhase, Masu ms, Kyokumen.Sindanyo kys)
        {
            var phase = optionalPhase.Unwrap();

            if (phase == Phase.Black)
            {
                return(Conv_Masu.ToDan_WithoutErrorCheck((int)ms));
            }
            return(Conv_Masu.ToDan_WithoutErrorCheck(kys.MASU_YOSOSU - 1 - (int)ms));
        }
コード例 #6
0
        public static Move TryFenMove2(
            bool isSfen,
            Kyokumen.Sindanyo kys,
            string str1,
            string str2,
            string str3,
            string str4,
            string str5
            )
        {
            int dstSuji = FenSuji_Int(isSfen, str3); // 至筋
            int dstDan  = FenDan_Int(isSfen, str4);  // 至段

            // 取った駒を調べるぜ☆(^▽^)
            Masu dstMs = Conv_Masu.ToMasu(dstSuji, dstDan);


            //------------------------------
            // 5
            //------------------------------
            bool natta = false;

            if ("+" == str5)
            {
                // 成りました
                natta = true;
            }


            //------------------------------
            // 結果
            //------------------------------
            if ("*" == str2)
            {
                // 駒台から打ったぜ☆
                return(ConvMove.ToMove01cUtta(
                           dstMs,
                           Med_Parser.Moji_MotikomaSyurui(isSfen, str1)//打った駒
                           ));
            }
            else
            {
                // 盤上の駒を動かしたぜ☆
                if (natta)
                {
                    return(ConvMove.ToMove01bNariSasi(Med_Parser.FenSujiDan_Masu(isSfen, str1, str2), dstMs, kys));
                }
                else
                {
                    return(ConvMove.ToMove01aNarazuSasi(Med_Parser.FenSujiDan_Masu(isSfen, str1, str2), dstMs, kys));
                }
            }
        }
コード例 #7
0
        public static void Assert_Sabun_Kiki(string message, Kyokumen.Sindanyo kys)
        {
            // 駒の利き☆
            bool safe = true;

            // 再計算 Recalculate
            Shogiban saikeisan = new Shogiban(kys);

            saikeisan.Tukurinaosi_1_Clear_KikiKomabetu();
            saikeisan.Tukurinaosi_2_Input_KikiKomabetu(kys);

            foreach (var optionalPhase in Conv_Taikyokusya.AllOptionalPhaseList) // 対局者1、対局者2
            {
                int iKm = 0;                                                     //どの駒でエラーがあったか
                foreach (Koma km in Conv_Koma.ItiranTai[OptionalPhase.IndexOf(optionalPhase)])
                {
                    if (!kys.EqualsKiki(km, saikeisan))//現行版と、再計算版の比較
                    {
                        safe = false;
                        break;
                    }
                    iKm++;
                }

                // ダイアログボックスに収まるように分けるぜ☆
                if (!safe)
                {
                    StringBuilder sindan1 = new StringBuilder();

                    //// 参考:駒の居場所
                    //{
                    //    sindan1.Append(message);
                    //    sindan1.AppendLine("参考:駒の居場所");
                    //    Util_Information.HyojiKomanoIbasho(ky.BB_KomaZenbu, ky.BB_Koma, sindan1);
                    //    sindan1.AppendLine($"Util_Tansaku.TansakuTyakusyuEdas=[{Util_Tansaku.TansakuTyakusyuEdas}]");
                    //}

                    sindan1.Append(message); sindan1.Append("【エラー】"); Conv_Taikyokusya.Setumei_Name(optionalPhase, sindan1); sindan1.AppendLine();
                    sindan1.AppendLine($"iKm=[{iKm}]");

                    sindan1.AppendLine("利き:(再計算)");
                    Util_Information.Setumei_Bitboards(Med_Koma.GetKomasyuruiNamaeItiran(optionalPhase), saikeisan.WhereBBKiki(optionalPhase), sindan1);

                    kys.Setumei_GenkoKiki(optionalPhase, sindan1); // 利き:(現行)

                    var msg = sindan1.ToString();
                    sindan1.Clear();
                    Logger.Flush(msg);
                    Debug.Assert(safe, msg);
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// moves 以降の符号を指定しろだぜ☆(^~^)
        /// </summary>
        /// <param name="moves"></param>
        public void AddMoves(bool isSfen, string moves, Kyokumen.Sindanyo kys)
        {
            string[] fugoItiran = moves.Split(' ');

            foreach (string fugo in fugoItiran)
            {
                int caret = 0;
                if (!Med_Parser.TryFenMove(isSfen, fugo, ref caret, kys, out Move move))
                {
                    throw new System.Exception($"指し手のパースエラー fugo=[{ fugo }]");
                }
                SsList.Add(move);
            }
        }
コード例 #9
0
        /// <summary>
        /// 手番と、
        /// 駒の種類と、その升、
        /// この3つを指定すると、利きを表にして返すぜ☆(^▽^)
        /// </summary>
        /// <param name="tai"></param>
        /// <param name="targetMs"></param>
        /// <param name="ks"></param>
        /// <param name="attackerMs"></param>
        /// <returns></returns>
        public static bool[] Kiki(Koma km, Masu attackerMs, Kyokumen.Sindanyo kys, Shogiban shogiban)//KomanoUgokikata komanoUgokikata
        {
            bool[] kiki = new bool[kys.MASU_YOSOSU];

            // 盤上
            for (int iDan = 0; iDan < Option_Application.Optionlist.BanTateHaba; iDan++)
            {
                for (int iSuji = 0; iSuji < Option_Application.Optionlist.BanYokoHaba; iSuji++)
                {
                    kiki[iDan * Option_Application.Optionlist.BanYokoHaba + iSuji] = Util_HiouteCase.IsLegalMove(km, (Masu)(iDan * Option_Application.Optionlist.BanYokoHaba + iSuji), attackerMs, shogiban);
                }
            }

            return(kiki);
        }
コード例 #10
0
        /// <summary>
        /// 局面に点数を付けるぜ☆(^▽^)
        ///
        /// どちらの対局者でも、自分に有利と思っていれば正の数の方向に点数が付くぜ☆(^▽^)
        /// </summary>
        /// <param name="ky_base"></param>
        /// <returns></returns>
        public void Tukurinaosi(Kyokumen.Sindanyo kys)
        {
            Hyokati[] hyokati = new Hyokati[] { Hyokati.Hyokati_Rei, Hyokati.Hyokati_Rei
                                                , Hyokati.Hyokati_Rei // 空白は手番なしで ここに入れるぜ☆(^~^)
            };

            // 盤上
            Bitboard komaBB = new Bitboard();

            for (int iTai = 0; iTai < Conv_Taikyokusya.AllOptionalPhaseList.Length; iTai++)
            {
                var optionalPhase = Conv_Taikyokusya.AllOptionalPhaseList[iTai];
                for (int iKs = 0; iKs < Conv_Komasyurui.Itiran.Length; iKs++)
                {
                    Komasyurui ks = Conv_Komasyurui.Itiran[iKs];

                    kys.ToSetIbasho(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase), komaBB);
                    while (komaBB.Ref_PopNTZ(out Masu ms_jissai))
                    {
                        hyokati[iTai] += Conv_Koma.BanjoKomaHyokatiNumber[(int)Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase)];
                    }
                }
            }

            // 持ち駒
            foreach (MotiKoma mk in Conv_MotiKoma.Itiran)
            {
                var            optionalPhase = Med_Koma.MotiKomaToPhase(mk);
                var            phaseIndex    = OptionalPhase.IndexOf(optionalPhase);
                MotiKomasyurui mks           = Med_Koma.MotiKomaToMotiKomasyrui(mk);
                Hyokati        komaHyokati   = Conv_Hyokati.KomaHyokati[(int)Med_Koma.MotiKomasyuruiAndPhaseToKoma(mks, optionalPhase)];

                hyokati[phaseIndex] += (int)komaHyokati * kys.CountMotikoma(mk);
            }

            // 手番 - 相手番
            Hyokati hyokatiP1 = hyokati[(int)Phase.Black];

            hyokati[(int)Phase.Black] -= hyokati[(int)Phase.White];
            hyokati[(int)Phase.White] -= hyokatiP1;
            KomawariHyokati_Sabun      = hyokati;
        }
コード例 #11
0
        /// <summary>
        /// 盤上の駒を指したぜ☆(^▽^)(打つ以外の指し手☆)
        ///
        /// 指し手に、取った駒を記録するのは止めるぜ☆(^~^)局面データの方に入れておこう☆(^▽^)
        /// </summary>
        /// <param name="ms_src"></param>
        /// <param name="ms_dst"></param>
        /// <param name="natta"></param>
        /// <returns></returns>
        public static Move ToMove01aNarazuSasi(Masu ms_src, Masu ms_dst, Kyokumen.Sindanyo kys)
        {
            Debug.Assert(kys.IsBanjoOrError(ms_src), $"ms_src=[{ms_src}] kys.MASUS=[{kys.MASU_YOSOSU}]");
            Debug.Assert(kys.IsBanjo(ms_dst), "盤外に指したぜ☆?");

            // バリュー
            int v = 0;

            // 筋と段☆(^▽^)盤外なら 0 だぜ☆(^▽^)
            SetSrcMasu_WithoutErrorCheck(ref v, ms_src);

            // 「打」のときは何もしないぜ☆(^▽^)

            SetDstMasu_WithoutErrorCheck(ref v, ms_dst);

            // 打った駒なし

            // 成らない☆(^▽^)

            return((Move)v);
        }
コード例 #12
0
        /// <summary>
        /// 現局面の盤上、駒台に置いてある駒を 駒の種類別に数え、
        /// 片方の対局者の駒台に全部乗れるよう、拡張する。
        /// </summary>
        public static void Tukurinaosi(Kyokumen.Sindanyo kys)
        {
            // 盤上
            m_banjoKeys_ = new ulong[kys.MASU_YOSOSU, Conv_Koma.Itiran.Length];
            for (int iMs = 0; iMs < kys.MASU_YOSOSU; iMs++)
            {
                foreach (Komasyurui ks in Conv_Komasyurui.Itiran)
                {
                    // 対局者1
                    m_banjoKeys_[iMs, (int)Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, OptionalPhase.Black)] = (ulong)(Option_Application.Random.NextDouble() * ulong.MaxValue);
                    // 対局者2
                    m_banjoKeys_[iMs, (int)Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, OptionalPhase.White)] = (ulong)(Option_Application.Random.NextDouble() * ulong.MaxValue);
                }
            }

            // 持ち駒
            {
                m_motiKeys_ = new ulong[Conv_MotiKoma.Itiran.Length][];

                int[] counts = kys.CountMotikomaHashSize();
                foreach (MotiKoma mk in Conv_MotiKoma.Itiran)
                {
                    MotiKomasyurui mks = Med_Koma.MotiKomaToMotiKomasyrui(mk);
                    m_motiKeys_[(int)mk] = new ulong[counts[(int)mks]];
                    for (int iCount = 0; iCount < counts[(int)mks]; iCount++)
                    {
                        m_motiKeys_[(int)mk][iCount] = (ulong)(Option_Application.Random.NextDouble() * ulong.MaxValue);
                    }
                }
            }

            // 手番
            m_tbTaikyokusya_ = new ulong[Conv_Taikyokusya.AllOptionalPhaseList.Length];
            foreach (var optionalPhase78 in Conv_Taikyokusya.AllOptionalPhaseList)
            {
                m_tbTaikyokusya_[OptionalPhase.IndexOf(optionalPhase78)] = (ulong)(Option_Application.Random.NextDouble() * ulong.MaxValue);
            }

            Dirty = false;
        }
コード例 #13
0
        /// <summary>
        /// 盤上の駒を指したぜ☆(^▽^)(打つ以外の指し手☆)
        ///
        /// 指し手に、取った駒を記録するのは止めるぜ☆(^~^)局面データの方に入れておこう☆(^▽^)
        /// </summary>
        /// <param name="ms_src"></param>
        /// <param name="ms_dst"></param>
        /// <param name="natta"></param>
        /// <returns></returns>
        public static Move ToMove01bNariSasi(Masu ms_src, Masu ms_dst, Kyokumen.Sindanyo kys)
        {
            Debug.Assert(kys.IsBanjoOrError(ms_src), "");
            Debug.Assert(kys.IsBanjo(ms_dst), "盤外に指したぜ☆?");

            // バリュー
            int v = 0;

            // 筋と段☆(^▽^)盤外なら 0 だぜ☆(^▽^)
            SetSrcMasu_WithoutErrorCheck(ref v, ms_src);

            // 「打」のときは何もしないぜ☆(^▽^)

            SetDstMasu_WithoutErrorCheck(ref v, ms_dst);

            // 打った駒なし

            // 成った☆(^▽^)
            v |= 1 << MoveShift.Natta;

            return((Move)v);
        }
コード例 #14
0
        public static bool MoveCmd(string commandline, Kyokumen.Sindanyo kys, out Move out_sasite)
        {
            // うしろに続く文字は☆(^▽^)
            int caret = 0;

            Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret, "move ");
            string line = commandline.Substring(caret).Trim();

            // move 912 といった数字かどうか☆(^~^)
            if (int.TryParse(line, out int ssSuji))
            {
                out_sasite = (Move)ssSuji;
                return(true);
            }

            // 数字でなければ、 move B2B3 といった文字列か☆(^~^)
            if (Med_Parser.TryFenMove(Option_Application.Optionlist.USI, commandline, ref caret, kys, out out_sasite))
            {
                return(true);
            }

            out_sasite = Move.Toryo;
            return(false);
        }
コード例 #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ms">どの(0~80)升に</param>
        /// <param name="km">先後付きの駒</param>
        /// <returns></returns>
        public static ulong GetBanjoKey(Masu ms, Koma km, Kyokumen.Sindanyo kys)
        {
            var optionalPiece = OptionalPiece.From(km);

            Debug.Assert(Conv_Koma.IsOk(optionalPiece), "");

            if (Dirty)
            {
                Tukurinaosi(kys);
            }

            if (!Conv_Koma.IsOk(optionalPiece))
            {
                throw new Exception("エラー☆(>_<) 盤上の駒じゃないぜ☆");
            }
            else if (kys.IsBanjo(ms))
            {
                return(m_banjoKeys_[(int)ms, (int)km]);
            }
            else
            {
                throw new Exception("エラー☆(>_<) 盤上のどこに置いてある駒なんだぜ☆");
            }
        }
コード例 #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="commandline">B4B3、または toryo といった文字列を含む行☆</param>
        /// <param name="caret">文字カーソルの位置</param>
        /// <param name="ky">取られた駒を調べるために使う☆</param>
        /// <param name="out_sasite"></param>
        /// <returns></returns>
        public static bool TryFenMove(
            bool isSfen,
            string commandline,
            ref int caret,
            Kyokumen.Sindanyo kys,
            out Move out_sasite
            )
        {
            if ('n' == commandline[caret])
            {
                if (caret == commandline.IndexOf("none", caret))//定跡ファイルの応手が無いときに利用☆
                {
                    Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret, "none");

                    out_sasite = Move.Toryo;
                    return(true);
                }
            }
            else
            //if ('t' == commandline[caret])
            //{
            if (caret == commandline.IndexOf(Itiran_FenParser.GetToryo(isSfen), caret))
            {
                Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret, Itiran_FenParser.GetToryo(isSfen));

                out_sasite = Move.Toryo;
                return(true);
            }
            //}

            // 「toryo」でも「none」でもなければ、「B4B3」形式と想定して、1手だけ読込み
            // テキスト形式の符号「A4A3 C1C2 …」の最初の1要素を、切り取ってトークンに分解します。

            Match m = Itiran_FenParser.GetMovePattern(isSfen).Match(commandline, caret);

            if (!m.Success)
            {
                //// 「B4B3」形式ではなかった☆(^△^)!? 次の一手が読めない☆
                //string msg = $"指し手のパースに失敗だぜ☆(^~^)! commandline=[{ commandline }] caret=[{ caret }] m.Groups.Count=[{ m.Groups.Count }]";
                //Util_Machine.AppendLine(msg);
                //Logger.Flush();
                //throw new Exception(msg);

                out_sasite = Move.Toryo;
                return(false);
            }

            // m.Groups[1].Value : ABCabc か、 ZKH
            // m.Groups[2].Value : 1234   か、 *
            // m.Groups[3].Value : ABCabc
            // m.Groups[4].Value : 1234
            // m.Groups[5].Value : +

            // カーソルを進めるぜ☆(^~^)
            Util_String.SkipMatch(commandline, ref caret, m);

            // 符号1「B4B3」を元に、move を作ります。
            out_sasite = TryFenMove2(
                isSfen,
                kys,
                m.Groups[1].Value,
                m.Groups[2].Value,
                m.Groups[3].Value,
                m.Groups[4].Value,
                m.Groups[5].Value
                );
            Debug.Assert((int)out_sasite != -1, "");

            return(true);
        }