Пример #1
0
        /// <summary>
        /// 局面ハッシュを再計算するぜ☆(^▽^)
        /// </summary>
        /// <returns></returns>
        public void Tukurinaosi(Kyokumen ky)
        {
            ulong hash = 0;

            // 盤上
            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];
                    Koma       km = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase);

                    ky.Shogiban.ToSet_BBKoma(km, komaBB);
                    while (komaBB.Ref_PopNTZ(out Masu ms))
                    {
                        hash ^= Util_ZobristHashing.GetBanjoKey(ms, km, ky.Sindan);
                    }
                }
            }

            // 持ち駒
            foreach (MotiKoma mk in Conv_MotiKoma.Itiran)
            {
                hash ^= Util_ZobristHashing.GetMotiKey(ky.Sindan, mk);
            }


            // 手番
            hash ^= Util_ZobristHashing.GetTaikyokusyaKey(ky.CurrentOptionalPhase, ky.Sindan);

            Value = hash;
        }
Пример #2
0
        /// <summary>
        /// 駒の利き
        /// </summary>
        /// <param name="bbItiran_kikiZenbu"></param>
        /// <param name="bbItiran_kikiKomabetu"></param>
        /// <param name="syuturyoku"></param>
        public static void HyojiKomanoKiki(Shogiban shogiban, StringBuilder syuturyoku)
        {
            Debug.Assert(shogiban.IsActiveBBKiki(), "");

            // 利き全部
            {
                syuturyoku.AppendLine("利き(全部)");
                Bitboard[] bbHairetu = new Bitboard[Conv_Taikyokusya.AllOptionalPhaseList.Length];
                foreach (var optionalPhase65 in Conv_Taikyokusya.AllOptionalPhaseList)
                {
                    bbHairetu[OptionalPhase.IndexOf(optionalPhase65)] = shogiban.GetBBKikiZenbu(optionalPhase65);
                }
                Setumei_Bitboards(Conv_Taikyokusya.NamaeItiran, bbHairetu, syuturyoku);
            }
            // 駒別
            {
                syuturyoku.AppendLine("利き(駒別)");
                foreach (var optionalPhase74 in Conv_Taikyokusya.AllOptionalPhaseList)// 対局者1、対局者2
                {
                    // 盤上
                    Bitboard[] bbHairetu = new Bitboard[Conv_Komasyurui.Itiran.Length];
                    foreach (Komasyurui ks in Conv_Komasyurui.Itiran)
                    {
                        bbHairetu[(int)ks] = shogiban.GetBBKiki(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase74));
                    }

                    Setumei_Bitboards(Med_Koma.GetKomasyuruiNamaeItiran(optionalPhase74), bbHairetu, syuturyoku);
                }
            }
        }
Пример #3
0
 public static void Setumei_Kiki(Kyokumen ky, Masu attackerMs, StringBuilder syuturyoku)
 {
     var(exists, optionalPhase) = ky.Shogiban.ExistsBBKomaZenbu(attackerMs);
     if (exists)
     {
         ky.Shogiban.ExistsBBKoma(optionalPhase, attackerMs, out Komasyurui ks);
         Util_Information.Setumei_1Bitboard("利き",
                                            Util_Application.Kiki_BB(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase), attackerMs, ky.Shogiban)//利き
                                            , syuturyoku);
     }
 }
Пример #4
0
        /// <summary>
        /// 一手詰めの局面かどうか調べるぜ☆(^▽^)
        ///
        /// 自分が一手詰めを掛けられるから、この指し手は作らないでおこう、といった使い方がされるぜ☆(^▽^)
        ///
        /// FIXME: 持ち駒の打ちにも使えないか☆(^~^)?
        /// </summary>
        /// <param name="fukasa"></param>
        /// <param name="ky"></param>
        /// <param name="jibun"></param>
        /// <param name="ms_src">持ち駒の場合、エラー値</param>
        /// <param name="mks">持ち駒の場合、持駒の種類</param>
        /// <param name="ms_t1"></param>
        /// <param name="jibunHioute"></param>
        /// <returns></returns>
        public static bool Ittedume_MotiKoma(int fukasa, Kyokumen ky, MotiKoma mk, Masu ms_t1, HiouteJoho jibunHioute, HiouteJoho aiteHioute)
        {
            if (!Conv_MotiKoma.IsOk(mk))
            {
                throw new Exception("持ち駒じゃないじゃないか☆(^▽^)www");
            }

            // A B  C
            // ┌──┬──┬──┐
            //1│  │▽ら│  │
            // ├──┼──┼──┤
            //2│▲き│  │▲き│
            // ├──┼──┼──┤
            //3│  │▲に│▲ら│
            // ├──┼──┼──┤
            //4│▲ぞ│▲ひ│▲ぞ│
            // └──┴──┴──┘

            // 盤上の駒を動かすのか、駒台の駒を打つのかによって、利き の形が異なるぜ☆(^~^)
            Bitboard bb_kiki_t1 = ky.Shogiban.GetKomanoUgokikata(Med_Koma.MotiKomaToKoma(mk), ms_t1);

            if (!ky.Shogiban.GetBBKoma(aiteHioute.KmRaion).IsIntersect( // 相手らいおんの場所☆
                    bb_kiki_t1))                                        // 相手らいおん が、動かした駒の、利きの中に居ないんだったら、一手詰め にはならないぜ☆(^~^)
            {
                // FIXME: ステイルメイトは考えてないぜ☆(>_<)
                return(false);
            }

            Koma km_t1 = Med_Koma.MotiKomaToKoma(mk);//t0も同じ

            // FIXME: ↓駒移動後の、利きを取る必要がある
            Bitboard bb_jibunKikiNew = new Bitboard();

            {
                // 打による、重ね利きの数を差分更新するぜ☆(^▽^)
                //, ky.BB_KikiZenbu
                ky.Shogiban.N100_FuyasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan);// 移動先の駒の利きを増やすぜ☆(^▽^)

                // こっちの利きを作り直し
                bb_jibunKikiNew = ky.Shogiban.ToBitboard_KikisuZenbuPositiveNumber(Med_Koma.MotiKomaToPhase(mk), ky.Sindan);

                // 打による、重ね利きの数の差分更新を元に戻すぜ☆(^▽^)
                // , ky.BB_KikiZenbu
                ky.Shogiban.N100_HerasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan);// 移動先の駒の利きを減らすぜ☆(^▽^)
            }

            // 相手らいおんが逃げようとしていて。
            return(aiteHioute.FriendRaion8KinboBB.Clone()                                // 相手らいおんの8近傍
                   .Sitdown(ky.Shogiban.GetBBKomaZenbu(aiteHioute.CurrentOptionalPhase)) // 相手の駒がない升
                   .Sitdown(bb_jibunKikiNew)                                             // こっちの利きがない升
                   .IsEmpty());                                                          // 相手らいおん が逃げれる升がない場合、詰み☆
        }
Пример #5
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);
                }
            }
        }
Пример #6
0
        public static void Kiki(bool isSfen, string commandline, Kyokumen ky, out Masu out_ms, out Bitboard out_kikiBB)
        {
            //KomanoUgokikata komanoUgokikata,

            // うしろに続く文字は☆(^▽^)
            int caret = 0;

            Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret, "kiki ");
            string line = commandline.Substring(caret).TrimEnd();

            if (line.Length == 2)// kiki b3
            {
                out_kikiBB = null;

                // 升を返すぜ☆
                if (!Med_Parser.TryParseMs(isSfen, commandline, ky, ref caret, out out_ms))
                {
                    throw new Exception("パースエラー102");
                }
            }
            else// kiki b3 R 1
            {
                out_ms = ky.MASU_ERROR;

                // 盤面表示を返すぜ☆
                string moji1 = "";
                string moji2 = "";
                string moji3 = "";
                string moji4 = "";
                Match  m     = Itiran_FenParser.GetKikiCommandPattern(Option_Application.Optionlist.USI).Match(commandline, caret);
                if (m.Success)
                {
                    Util_String.SkipMatch(commandline, ref caret, m);

                    moji1 = m.Groups[1].Value;
                    moji2 = m.Groups[2].Value;
                    moji3 = m.Groups[3].Value;
                    moji4 = m.Groups[4].Value;

                    if (!Med_Parser.TryTaikyokusya(Option_Application.Optionlist.USI, moji4, out Option <Phase> phase))
                    {
                        throw new Exception($"対局者のパースエラー moji4=[{ moji4 }]");
                    }
                    out_kikiBB = Util_Application.Kiki_BB(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Med_Parser.Moji_Komasyurui(Option_Application.Optionlist.USI, moji3), phase), Med_Parser.FenSujiDan_Masu(Option_Application.Optionlist.USI, moji1, moji2), ky.Shogiban);// komanoUgokikata
                }
                else
                {
                    out_kikiBB = null;
                }
            }
        }
Пример #7
0
 public static void AppendLine_Data_Countboard(Option <Phase> optionalPhase, Shogiban sg, int ms_hidariHasi, StringBuilder syuturyoku)
 {
     for (int iKs = 0; iKs < Conv_Komasyurui.Itiran.Length; iKs++)
     {
         syuturyoku.Append("│");
         for (int iMs_offset = 0; iMs_offset < Option_Application.Optionlist.BanYokoHaba; iMs_offset++)
         {
             int kikisuKomabetu = sg.CountKikisuKomabetu(Med_Koma.KomasyuruiAndTaikyokusyaToKoma((Komasyurui)iKs, optionalPhase), (Masu)(ms_hidariHasi + iMs_offset));
             syuturyoku.Append(0 < kikisuKomabetu ? string.Format(" {0,2} ", kikisuKomabetu) : "  ");
             syuturyoku.Append("│");
         }
     }
     syuturyoku.AppendLine();
 }
Пример #8
0
        /// <summary>
        /// 手番の駒 の8近傍を調べて、利きに飛び込んでいたら真顔で真だぜ☆(^▽^)
        /// </summary>
        /// <param name="ky"></param>
        /// <param name="attackerMs">相手の攻撃駒の居場所</param>
        /// <param name="targetMs">狙っている升</param>
        /// <returns></returns>
        public static bool InKiki(Kyokumen ky, Masu attackerMs, Masu targetMs)
        {
            var optionalOpponent = Conv_Taikyokusya.Reverse(ky.CurrentOptionalPhase);

            if (ky.Shogiban.ExistsBBKomaZenbu(optionalOpponent, attackerMs))                                                                      // 指定の場所に相手の駒があることを確認
            {
                if (ky.Shogiban.ExistsBBKoma(optionalOpponent, attackerMs, out Komasyurui ks))                                                    // 攻撃側の駒の種類
                {
                    return(ky.Shogiban.GetKomanoUgokikata(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalOpponent), attackerMs).IsIntersect( //相手の攻撃駒の利き
                               targetMs                                                                                                           //調べる升
                               ));
                }
            }
            return(false);
        }
Пример #9
0
 /// <summary>
 /// 駒の動き☆
 /// </summary>
 /// <param name="komanoUgokikata"></param>
 /// <param name="syuturyoku"></param>
 public static void HyojiKomanoUgoki(Shogiban shogiban, int masuYososu, StringBuilder syuturyoku)
 {
     // KomanoUgokikata komanoUgokikata
     for (int ms = 0; ms < masuYososu; ms++)
     {
         syuturyoku.AppendLine($"ます{ms}");
         foreach (var optionalPhase in Conv_Taikyokusya.AllOptionalPhaseList)
         {
             // 盤上
             Bitboard[] bbHairetu = new Bitboard[Conv_Komasyurui.Itiran.Length];
             foreach (Komasyurui ks in Conv_Komasyurui.Itiran)
             {
                 bbHairetu[(int)ks] = shogiban.GetKomanoUgokikata(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase), (Masu)ms);
             }
             Util_Information.Setumei_Bitboards(Med_Koma.GetKomasyuruiNamaeItiran(optionalPhase), bbHairetu, syuturyoku);
             syuturyoku.AppendLine();
         }
     }
 }
Пример #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>
        /// 指定の升にいる駒を除く、味方全部の利き☆
        ///
        /// 盤上の駒を指す場合、自分自身が動いてしまうので利きが変わってしまうので、
        /// 全部の利きを合成したBBが使えないので、代わりにこの関数を使うんだぜ☆(^~^)
        /// </summary>
        /// <param name="ky"></param>
        /// <param name="ms_nozoku">除きたい駒がいる升</param>
        /// <returns></returns>
        public static Bitboard CreateKikiZenbuBB_1KomaNozoku(Kyokumen ky, Option <Phase> phase, Masu ms_nozoku)
        {
            Bitboard kikiZenbuBB = new Bitboard();

            // 味方の駒(変数使いまわし)
            Bitboard mikataBB = new Bitboard();

            foreach (Komasyurui ks in Conv_Komasyurui.Itiran)
            {
                Koma km = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, phase);
                ky.Shogiban.ToSet_BBKoma(km, mikataBB);
                while (mikataBB.Ref_PopNTZ(out Masu ms))
                {
                    if (ms_nozoku != ms)//この駒を除く
                    {
                        ky.Shogiban.ToStandup_KomanoUgokikata(km, ms, kikiZenbuBB);
                    }
                }
            }
            return(kikiZenbuBB);
        }
Пример #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>
        /// <returns></returns>
        public bool IsNigemitiWoAkeru(Kyokumen ky, Komasyurui ks_aite, Masu ms_t0, Masu ms_t1)
        {
            if (NigemitiWoFusaideiruAiteNoKomaBB.IsOff(ms_t0))
            {
                // 逃げ道を塞いでいる駒ではないのなら、スルーするぜ☆(^▽^)
                return(false);
            }

            // 手番らいおん の8近傍 のどこかに、重ね利きの数 0 が出来ていれば、
            // 逃げ道を開けると判定するぜ☆(^▽^)
            bool akeru = false;
            Koma km_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks_aite, CurrentOptionalPhase);
            Koma km_t1 = km_t0;// FIXME: 成りを考慮していない

            // 重ね利きの数を差分更新するぜ☆(^▽^)
            ky.Shogiban.N100_HerasuKiki(km_t0, ky.Sindan.CloneKomanoUgoki(km_t0, ms_t0), ky.Sindan);
            ky.Shogiban.N100_FuyasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan);

            Bitboard nigemitiBB = new Bitboard();

            nigemitiBB.Set(FriendRaion8KinboBB);
            nigemitiBB.Sitdown(FriendKomaBB);
            while (nigemitiBB.Ref_PopNTZ(out Masu ms_nigemiti))
            {
                if (0 == ky.Shogiban.CountKikisuZenbu(Conv_Taikyokusya.Reverse(CurrentOptionalPhase), ms_nigemiti)) // 相手番の利きが無くなったか☆(^▽^)
                {
                    akeru = true;                                                                                   // (^▽^)逃げ道が開いたぜ☆!
                    goto gt_EndLoop;
                }
            }
gt_EndLoop:
            ;

            // 重ね利きの数の差分更新を、元に戻すぜ☆(^▽^)
            ky.Shogiban.N100_HerasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan);
            ky.Shogiban.N100_FuyasuKiki(km_t0, ky.Sindan.CloneKomanoUgoki(km_t0, ms_t0), ky.Sindan);

            return(akeru);
        }
Пример #14
0
        /// <summary>
        /// 駒の居場所
        /// </summary>
        /// <param name="syuturyoku"></param>
        public static void HyojiKomanoIbasho(Shogiban shogiban, StringBuilder syuturyoku)
        {
            //IbasyoKomabetuBitboardItiran bb_koma,
            //  KomaZenbuIbasyoBitboardItiran bb_komaZenbu
            syuturyoku.AppendLine("駒の居場所");

            // 駒全部☆
            {
                Setumei_Bitboards(new string[] { "対局者1", "対局者2" },
                                  new Bitboard[] {
                    shogiban.GetBBKomaZenbu(OptionalPhase.Black),
                    shogiban.GetBBKomaZenbu(OptionalPhase.White)
                }, syuturyoku);
                syuturyoku.AppendLine();
            }

            foreach (var optionalPhase81 in Conv_Taikyokusya.AllOptionalPhaseList)// 対局者1、対局者2
            {
                // 見出し
                foreach (Koma km in Conv_Koma.ItiranTai[OptionalPhase.IndexOf(optionalPhase81)])
                {
                    syuturyoku.Append(FormatBanWidthZenkaku(Conv_Koma.GetName(km)));
                }
                syuturyoku.AppendLine();

                // 盤
                Bitboard[] bbHairetu = new Bitboard[Conv_Komasyurui.Itiran.Length];
                int        i         = 0;
                foreach (Komasyurui ks in Conv_Komasyurui.Itiran)
                {
                    bbHairetu[i] = shogiban.GetBBKoma(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase81));
                    i++;
                }
                Setumei_Bitboards(bbHairetu, syuturyoku);
            }
        }
Пример #15
0
        //private static Option<T> Option<T>(T white)
        //{
        //    throw new NotImplementedException();
        //}

        /// <summary>
        /// 将棋盤をコンソールへ出力するぜ☆(^▽^)
        /// コンソールでゲームするのに向いた表示☆
        /// </summary>
        /// <returns></returns>
        public static void Setumei_NingenGameYo(Kyokumen ky, StringBuilder syuturyoku)
        {
            // 1行目
            {
                // 千日手
                int sennitite = ky.Konoteme.GetSennititeCount();
                if (Const_Game.SENNITITE_COUNT == sennitite)
                {
                    Conv_Taikyokusya.Setumei_Name(Conv_Taikyokusya.Reverse(ky.CurrentOptionalPhase), syuturyoku);
                    syuturyoku.Append("の着手にて 千日手");
                    syuturyoku.AppendLine();
                }
                else if (1 < sennitite)
                {
                    syuturyoku.Append("同一局面反復 ");
                    syuturyoku.Append(sennitite.ToString());
                    syuturyoku.AppendLine(" 回目");
                }
                else
                {
                    syuturyoku.AppendLine();
                }
            }

            // 2行目
            {
                // 何手目
                syuturyoku.Append("図は");
                syuturyoku.Append(string.Format("{0,3}", ky.Konoteme.ScanNantemadeBango()));
                syuturyoku.Append("手まで ");

                // 手番
                Conv_Taikyokusya.Setumei_Name(ky.CurrentOptionalPhase, syuturyoku);
                syuturyoku.Append("の番");

                // #仲ルール
                if (Option_Application.Optionlist.SagareruHiyoko)
                {
                    syuturyoku.Append(" #仲");
                }

                syuturyoku.AppendLine();
            }

            // 3行目 後手の持ち駒の数
            {
                foreach (MotiKomasyurui mks in Conv_MotiKomasyurui.Itiran)
                {
                    MotiKoma mk = Med_Koma.MotiKomasyuruiAndPhaseToMotiKoma(mks, OptionalPhase.White);
                    if (ky.MotiKomas.HasMotiKoma(mk))
                    {
                        syuturyoku.Append(Conv_MotiKomasyurui.GetHyojiName(mks)); syuturyoku.Append(ky.MotiKomas.Get(mk).ToString());
                    }
                }
                syuturyoku.AppendLine();
            }

            // 4行目
            {
                syuturyoku.Append("  ");
                AppendLine_SujiFugo_Kyokumen(syuturyoku);
                //syuturyoku.AppendLine("   A   B   C  ");
            }

            // 5行目~13行目
            // 盤上
            {
                // 5行目
                syuturyoku.Append("  ");
                Util_Information.AppendLine_Top_Kyokumen(1, syuturyoku); // ┌──┬──┬──┐

                for (int dan = 0; dan < Option_Application.Optionlist.BanTateHaba; dan++)
                {
                    // 6,8,10,12行目
                    syuturyoku.Append(Conv_Kihon.ToZenkakuInteger(dan + 1));
                    AppendLine_Data_Kyokumen(ky, dan, syuturyoku);

                    if (dan + 1 < Option_Application.Optionlist.BanTateHaba)
                    {
                        // 7,9,11行目
                        syuturyoku.Append("  ");
                        AppendLine_Middle(1, syuturyoku);//├──┼──┼──┤
                    }
                }

                // 13行目
                syuturyoku.Append("  ");
                AppendLine_Bottom(1, syuturyoku);//└──┴──┴──┘
            }

            // 14行目
            {
                // 先手の持ち駒の数
                foreach (MotiKomasyurui mks in Conv_MotiKomasyurui.Itiran)
                {
                    MotiKoma mk = Med_Koma.MotiKomasyuruiAndPhaseToMotiKoma(mks, OptionalPhase.Black);
                    if (ky.MotiKomas.HasMotiKoma(mk))
                    {
                        syuturyoku.Append(Conv_MotiKomasyurui.GetHyojiName(mks)); syuturyoku.Append(ky.MotiKomas.Get(mk).ToString());
                    }
                }
                syuturyoku.AppendLine();
            }
        }
Пример #16
0
        /// <summary>
        /// 一手詰めの局面かどうか調べるぜ☆(^▽^)
        ///
        /// 盤上の駒を動かすのか、駒台の駒を打つのかによって、利き の形が異なるぜ☆(^~^)
        ///
        /// 自分が一手詰めを掛けられるから、この指し手は作らないでおこう、といった使い方がされるぜ☆(^▽^)
        ///
        /// FIXME: 成りを考慮してない
        /// </summary>
        /// <param name="ky"></param>
        /// <param name="jibun"></param>
        /// <param name="ms_t0">移動元。持ち駒の場合、エラー値</param>
        /// <param name="ms_t1">移動先</param>
        /// <param name="jibunHioute"></param>
        /// <returns></returns>
        public static bool Ittedume_BanjoKoma(Kyokumen ky, Option <Phase> phase, Masu ms_t0, Masu ms_t1, HiouteJoho jibunHioute, HiouteJoho aiteHioute)
        {
            Debug.Assert(ky.Sindan.IsBanjo(ms_t1), "升エラー");

            var optionalOpponent = Conv_Taikyokusya.Reverse(phase);

            // 動かす駒
            if (!ky.Shogiban.ExistsBBKoma(phase, ms_t0, out Komasyurui ks_t0))
            {
                StringBuilder reigai1 = new StringBuilder();
                reigai1.AppendLine($"盤上の駒じゃないじゃないか☆(^▽^)www phase=[{ phase }] ms_src=[{ ms_t0 }] ks_jibun=[{ ks_t0 }]");
                Util_Information.HyojiKomanoIbasho(ky.Shogiban, reigai1);
                var msg = reigai1.ToString();
                Logger.Flush(msg);
                throw new Exception(msg);
            }
            Koma km_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks_t0, phase);
            Koma km_t1 = km_t0; // FIXME: 成りを考慮していないぜ☆(>_<)

            // A B  C
            // ┌──┬──┬──┐
            //1│  │▽ら│  │
            // ├──┼──┼──┤
            //2│▲き│  │▲き│
            // ├──┼──┼──┤
            //3│  │▲に│▲ら│
            // ├──┼──┼──┤
            //4│▲ぞ│▲ひ│▲ぞ│
            // └──┴──┴──┘

            // 動かしたばかりの駒を 取り返されるようでは、一手詰めは成功しないぜ☆(^~^)(ステイルメイト除く)
            if (1 < ky.Shogiban.CountKikisuZenbu(optionalOpponent, ms_t1))
            {
                // 移動先升は、相手らいおん の利きも 1つ あるはず。
                // 移動先升に 相手の利きが2つあれば、駒を取り返される☆
                return(false);
            }

            if (!ky.Shogiban.GetBBKoma(aiteHioute.KmRaion).IsIntersect( // 相手のらいおん
                    ky.Shogiban.GetKomanoUgokikata(km_t0, ms_t1)        // 移動先での駒の利き
                    ))                                                  // 相手らいおん が、移動先での駒の利きの中に居ないんだったら、一手詰め にはならないぜ☆(^~^)
            {
                // FIXME: ステイルメイトは考えてないぜ☆(>_<)
                return(false);
            }

            Bitboard bb_idogoKikiNew = new Bitboard();// 移動後の、利き

            {
                // 盤上の重ね利きの数を差分更新するぜ☆(^▽^)
                {
                    ky.Shogiban.N100_HerasuKiki(km_t0, ky.Sindan.CloneKomanoUgoki(km_t0, ms_t0), ky.Sindan); // 移動元の駒の利きを消すぜ☆(^▽^)
                    ky.Shogiban.N100_FuyasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan); // 移動先の駒の利きを増やすぜ☆(^▽^)
                }

                // 移動後の利きを作り直し
                bb_idogoKikiNew = ky.Shogiban.ToBitboard_KikisuZenbuPositiveNumber(phase, ky.Sindan);

                // 盤上の重ね利きの数の差分更新を元に戻すぜ☆(^▽^)
                {
                    //ky.BB_KikiZenbu
                    ky.Shogiban.N100_HerasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan); // 移動先の駒の利きを減らすぜ☆(^▽^)
                    ky.Shogiban.N100_FuyasuKiki(km_t0, ky.Sindan.CloneKomanoUgoki(km_t0, ms_t0), ky.Sindan); // 移動元の駒の利きを増やすぜ☆(^▽^)
                }
            }

            return
                (aiteHioute.FriendRaion8KinboBB.Clone()                 // 相手らいおん が逃げれる、相手らいおんの周りの空白
                 .Sitdown(ky.Shogiban.GetBBKomaZenbu(optionalOpponent)) // 相手の駒がない升
                 .Sitdown(bb_idogoKikiNew)                              // こっちの利きがない升
                 .IsEmpty());                                           // がない場合、詰み☆

            ;
        }
Пример #17
0
        /// <summary>
        /// トライしていれば真☆
        /// </summary>
        /// <returns></returns>
        public static bool IsTried(Kyokumen ky, Option <Phase> phase)
        {
            switch (phase.Unwrap())
            {
            case Phase.Black: return(ky.BB_DanArray[0].IsIntersect(ky.Shogiban.GetBBKoma(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, phase))));

            case Phase.White: return(ky.BB_DanArray[Option_Application.Optionlist.BanTateHaba - 1].IsIntersect(ky.Shogiban.GetBBKoma(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, phase))));

            default: throw new Exception("未定義の手番");
            }
        }