Exemplo n.º 1
0
        /// <summary>
        /// この左上
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="tb"></param>
        /// <returns></returns>
        static void TasuKonoHidariue(Piece km, Masu ms)
        {
            switch (Med_Koma.KomaToTaikyokusya(km))
            {
            case Taikyokusya.T1:
                if (!BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_UeHajiDan(ms) && !BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_HidariHajiSuji(ms))
                {
                    Masu ms_tmp = ms - PureSettei.banYokoHaba - 1;
                    if (Conv_Masu.IsBanjo(ms_tmp))
                    {
                        BitboardsOmatome.KomanoUgokikataYk00.StandupElement(km, ms, ms_tmp);
                    }
                }
                break;

            case Taikyokusya.T2:
                if (!BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_SitaHajiDan(ms) && !BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_MigiHajiSuji(ms))
                {
                    Masu ms_tmp = ms + PureSettei.banYokoHaba + 1;
                    if (Conv_Masu.IsBanjo(ms_tmp))
                    {
                        BitboardsOmatome.KomanoUgokikataYk00.StandupElement(km, ms, ms_tmp);
                    }
                }
                break;

            default: break;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 桂馬跳び左
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="tb"></param>
        /// <returns></returns>
        static void TasuKeimatobiHidari(Piece km, Masu ms)
        {
            Taikyokusya tai = Med_Koma.KomaToTaikyokusya(km);

            if (!BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_UsagigaHidariniToberu(tai, ms))
            {
                switch (tai)
                {
                case Taikyokusya.T1:
                {
                    Masu ms_tmp = ms - 2 * PureSettei.banYokoHaba - 1;
                    if (Conv_Masu.IsBanjo(ms_tmp))
                    {
                        BitboardsOmatome.KomanoUgokikataYk00.StandupElement(km, ms, ms_tmp);
                    }
                }
                break;

                case Taikyokusya.T2:
                {
                    Masu ms_tmp = ms + 2 * PureSettei.banYokoHaba + 1;
                    if (Conv_Masu.IsBanjo(ms_tmp))
                    {
                        BitboardsOmatome.KomanoUgokikataYk00.StandupElement(km, ms, ms_tmp);
                    }
                }
                break;

                default: break;
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 2017-04-19 作成
        ///
        /// パースに失敗してもエラーではない。
        /// </summary>
        /// <param name="line"></param>
        /// <param name="caret"></param>
        /// <param name="out_ms"></param>
        /// <returns></returns>
        public static bool MatchMasu
            (string line, ref int caret, out Masu out_ms
#if DEBUG
            , IDebugMojiretu dbg_reigai
#endif
            )
        {
            Match m = Itiran_FenParser.GetMasuPattern(PureSettei.fenSyurui).Match(line, caret);

            if (m.Success)
            {
                // キャレットを進める
                Util_String.SkipMatch(line, ref caret, m);

                int suji = LisInt.FenSuji_Int(PureSettei.fenSyurui, m.Groups[1].Value);
                int dan  = LisInt.FenDan_Int(PureSettei.fenSyurui, m.Groups[2].Value);

                // 升を返す
                out_ms = Conv_Masu.ToMasu(suji, dan);

                return(true);
            }
            else
            {
                // 該当なし(エラーではない)
                out_ms = Conv_Masu.masu_error;
                return(false);
            }
        }
Exemplo n.º 4
0
 /// <summary>
 /// 対人表示用☆(^~^)
 /// </summary>
 /// <param name="ms"></param>
 /// <returns></returns>
 public static int ToDan_WithError(Masu ms)
 {
     if (Conv_Masu.IsBanjo(ms))
     {
         return(((int)ms) / PureSettei.banYokoHaba + 1);
     }
     return(Conv_Masu.ERROR_DAN);
 }
Exemplo n.º 5
0
 /// <summary>
 /// 対人表示用☆(^~^)
 /// </summary>
 /// <param name="ms"></param>
 /// <returns></returns>
 public static int ToSuji_WithError(Masu ms)
 {
     if (Conv_Masu.IsBanjo(ms))
     {
         return(((int)ms) % PureSettei.banYokoHaba + 1);
     }
     return(Conv_Masu.ERROR_SUJI);
 }
Exemplo n.º 6
0
        public static void BunkaiMoveUmv()
        {
            PureMemory.umv_ss = PureMemory.kifu_moveArray[PureMemory.kifu_endTeme];

            // 駒がないところを指していることがないか?
            PureMemory.umv_ms_t1 = AbstractConvMove.GetDstMasu_WithoutErrorCheck((int)PureMemory.umv_ss);
            PureMemory.umv_km_t1 = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(PureMemory.umv_ms_t1);
            PureMemory.umv_ks_t1 = Med_Koma.KomaToKomasyurui(PureMemory.umv_km_t1);// 成っているかもしれない☆
            Debug.Assert(Conv_Masu.IsBanjoOrError(PureMemory.umv_ms_t1), "error Undo-Begin-6");
            Debug.Assert(Conv_Koma.IsOk(PureMemory.umv_km_t1), "error Undo-Begin-7");


            if (!AbstractConvMove.IsUtta(PureMemory.umv_ss))                                                  // 指す
            {
                PureMemory.umv_ms_t0 = AbstractConvMove.GetSrcMasu_WithoutErrorCheck((int)PureMemory.umv_ss); // 戻し先。
                Debug.Assert(Conv_Masu.IsBanjo(PureMemory.umv_ms_t0), "error Undo-Begin-21 #金魚 戻し先が盤上でない?");

                PureMemory.umv_mk_t0 = Motigoma.Yososu;
                if (AbstractConvMove.IsNatta(PureMemory.umv_ss))                               // 成っていたとき
                {
                    PureMemory.umv_ks_t0 = Conv_Komasyurui.ToNarazuCase(PureMemory.umv_ks_t1); // 成る前
                }
                else
                {
                    PureMemory.umv_ks_t0 = PureMemory.umv_ks_t1;// 成る前、あるいは、成っていない、あるいは もともと にわとり☆
                }
                PureMemory.umv_km_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(PureMemory.umv_ks_t0, PureMemory.kifu_teban);
                Debug.Assert(Conv_Koma.IsOk(PureMemory.umv_km_t0), "error Undo-Begin-9 #羊");
                Debug.Assert(Conv_Masu.IsBanjoOrError(PureMemory.umv_ms_t0), "error Undo-Begin-8 #颪");
            }
            else// 打つ
            {
                PureMemory.umv_ms_t0 = Conv_Masu.masu_error;
                PureMemory.umv_km_t0 = Piece.Yososu;
                PureMemory.umv_ks_t0 = Komasyurui.Yososu;
                PureMemory.umv_mk_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToMotiKoma(PureMemory.umv_ks_t1, PureMemory.kifu_teban);
            }


            PureMemory.umv_ks_c = PureMemory.kifu_toraretaKsAr[PureMemory.kifu_endTeme];

            if (Komasyurui.Yososu != PureMemory.umv_ks_c)
            {
                PureMemory.umv_km_c = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(PureMemory.umv_ks_c, PureMemory.kifu_aiteban);
                PureMemory.umv_mk_c = Med_Koma.BanjoKomaToMotiKoma(PureMemory.umv_km_c);
                Debug.Assert(Conv_Koma.IsOk(PureMemory.umv_km_c), "error Undo-Begin-10 #竜巻");
            }
            else
            {
                PureMemory.umv_km_c = Piece.Yososu;
                PureMemory.umv_mk_c = Motigoma.Yososu;
            }
        }
Exemplo n.º 7
0
        public static Move TryFenMove2(
            FenSyurui f,
            string str1,
            string str2,
            string str3,
            string str4,
            string str5
            )
        {
            int dstSuji = LisInt.FenSuji_Int(f, str3); // 至筋
            int dstDan  = LisInt.FenDan_Int(f, str4);  // 至段

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


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

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


            //------------------------------
            // 結果
            //------------------------------
            if ("*" == str2)
            {
                // 駒台から打ったぜ☆
                return(AbstractConvMove.ToMove01cUtta(
                           dstMs,
                           Med_Parser.MojiToMotikomaSyurui(f, str1)//打った駒
                           ));
            }
            else
            {
                // 盤上の駒を動かしたぜ☆
                if (natta)
                {
                    return(AbstractConvMove.ToMove01bNariSasi(Med_Parser.FenSujiDan_Masu(f, str1, str2), dstMs));
                }
                else
                {
                    return(AbstractConvMove.ToMove01aNarazuSasi(Med_Parser.FenSujiDan_Masu(f, str1, str2), dstMs));
                }
            }
        }
Exemplo n.º 8
0
        public static int GetNanameDan(Masu ms, TobikikiDirection kikiDir)
        {
            switch (kikiDir)
            {
            case TobikikiDirection.KY:
            case TobikikiDirection.None:
                // 横方向(0オリジン)
                return(Conv_Masu.ToDanO0_WithoutErrorCheck((int)ms));

            case TobikikiDirection.KT:
            case TobikikiDirection.S:
                // 縦方向
                return(massugudanD[(int)ms]);

            case TobikikiDirection.ZHa:
            case TobikikiDirection.ZHs:
                return(nanamedanD[(int)ms][Conv_TobikikiDirection.ToUgokikataArrayIndex(kikiDir)]);

            default:
                throw new Exception(string.Format("想定外の方向 dir={0}", kikiDir));
            }
        }
Exemplo n.º 9
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)
        {
#if DEBUG
            Debug.Assert(Conv_Masu.IsBanjoOrError(ms_src), $"ms_src=[{ms_src}] kymS.masuYososu=[{PureSettei.banHeimen}]");
            Debug.Assert(Conv_Masu.IsBanjo(ms_dst), "盤外に指したぜ☆?");
#endif

            // バリュー
            int v = 0;

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

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

            SetDstMasu_WithoutErrorCheck(ref v, ms_dst);

            // 打った駒なし

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

            return((Move)v);
        }
Exemplo n.º 10
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)
        {
#if DEBUG
            Debug.Assert(Conv_Masu.IsBanjoOrError(ms_src), "");
            Debug.Assert(Conv_Masu.IsBanjo(ms_dst), "盤外に指したぜ☆?");
#endif

            // バリュー
            int v = 0;

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

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

            SetDstMasu_WithoutErrorCheck(ref v, ms_dst);

            // 打った駒なし

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

            return((Move)v);
        }
Exemplo n.º 11
0
 public static int GetDstDan_WithoutErrorCheck(int ss)
 {
     // (v & m) >> s + 1。 v:バリュー、m:マスク、s:シフト
     return(Conv_Masu.ToDanO1_WithoutErrorCheck((int)GetDstMasu_WithoutErrorCheck(ss)));
     // if (Move.Toryo == ss) { return Conv_Masu.ERROR_DAN; } // 解析不能☆
 }
Exemplo n.º 12
0
 public static int GetDstSuji_WithoutErrorCheck(int ss)
 {
     // (v & m) >> s + 1。 v:バリュー、m:マスク、s:シフト
     return(Conv_Masu.ToSujiO1_WithoutErrorCheck((int)GetDstMasu_WithoutErrorCheck(ss)));
     // if (Move.Toryo == ss) { return Conv_Masu.ERROR_SUJI; } // エラーチェック付き
 }
Exemplo n.º 13
0
 public static int GetSrcDan_WithoutErrorCheck(int ss)
 {
     // (v & m) >> s + 1。 v:バリュー、m:マスク、s:シフト
     return(Conv_Masu.ToDanO1_WithoutErrorCheck((int)GetSrcMasu_WithoutErrorCheck(ss)));
     // if (Move.Toryo == ss || AbstractConvMove.IsUtta(ss)) { return Conv_Masu.ERROR_DAN; }  // エラーチェック付き
 }
Exemplo n.º 14
0
        ///// <summary>
        /////
        ///// </summary>
        ///// <param name="out_restString"></param>
        ///// <param name="commandline">B3といった文字列☆</param>
        ///// <returns></returns>
        //public static bool TryParseMs(
        //    string commandline,
        //    Kyokumen ky,
        //    ref int caret,
        //    out Masu result
        //)
        //{
        //    //「B4」形式と想定
        //    // テキスト形式の符号「A4 …」の最初の1要素を、切り取ってトークンに分解します。

        //    //------------------------------------------------------------
        //    // リスト作成
        //    //------------------------------------------------------------

        //    Match m = Itiran_FenParser.GetMasuMovePattern(Option_Application.Optionlist.USI).Match(commandline, caret);
        //    if (m.Success)
        //    {
        //        Util_String.SkipMatch(commandline, ref caret, m);

        //        // 符号1「B4」を元に、Masu を作ります。

        //        // 盤上の駒を動かしたぜ☆
        //        result = Med_Parser.FenSujiDan_Masu(
        //            Option_Application.Optionlist.USI,
        //            m.Groups[1].Value, //ABCabc か、 ZKH
        //            m.Groups[2].Value //1234   か、 *
        //            );
        //        return true;
        //    }

        //    // 「B4B3」形式ではなかった☆(^△^)!? 次の一手が読めない☆
        //    result = ky.MASU_ERROR;
        //    return false;
        //}

        /// <summary>
        /// A1 を 0 に。
        /// </summary>
        /// <param name="f"></param>
        /// <param name="suji"></param>
        /// <param name="dan"></param>
        /// <returns></returns>
        public static Masu FenSujiDan_Masu(FenSyurui f, string suji, string dan)
        {
            return(Conv_Masu.ToMasu(LisInt.FenSuji_Int(f, suji), LisInt.FenDan_Int(f, dan)));
        }
Exemplo n.º 15
0
        /// <summary>
        /// 指したあとの、次の局面へと更新するぜ☆
        /// ハッシュも差分変更するぜ☆
        ///
        /// 手番を進める処理は、分けるぜ☆(^~^)
        /// </summary>
        /// <param name="ss">指し手☆</param>
        public static bool TryFailDoMoveAll(
            Move ss,
            MoveType ssType
#if DEBUG
            , FenSyurui f
            , IDebugMojiretu reigai1
            , bool isAssertYokusei // 駒の取り合いは呼び出し回数が多いので、アサートを抑制したいときに真
            , string hint
#endif
            )
        {
#if DEBUG
            isAssertYokusei = false;//FIXME:
#endif



            // 投了なら、なにも更新せず終了☆(^▽^)
            if (Move.Toryo == ss)
            {
                PureMemory.dmv_ks_c = Komasyurui.Yososu;
                goto gt_EndMethod;
            }
            MoveGenAccessor.BunkaiMoveDmv(ss);

            Debug.Assert(Conv_Koma.IsOk(PureMemory.dmv_km_t0), string.Format("Do km_t0={0}", PureMemory.dmv_km_t0));
            Debug.Assert(Conv_Koma.IsOk(PureMemory.dmv_km_t1), "Do");
            Debug.Assert(Conv_Masu.IsBanjoOrError(PureMemory.dmv_ms_t1), "");
            Debug.Assert(Conv_Koma.IsOkOrKuhaku(PureMemory.dmv_km_c), "Do");

            if (AbstractConvMove.IsUtta(ss))
            {
                // 打った場合☆(^~^)

                // 駒台から駒を減らすんだぜ☆(^~^)
                if (TryFail_DaiOff(
                        PureMemory.dmv_ms_t0, // 打ち、の場合は使わないので、エラー値を入れておく
                        PureMemory.dmv_km_t0, // 打つ駒
                        PureMemory.dmv_mk_t0, // 持駒
                        PureMemory.dmv_ms_t1  // 移動先升

#if DEBUG
                        , f
                        , reigai1
#endif
                        ))
                {
                    return(Pure.FailTrue("TryFail_Tejun3_IdomotoJibunnoKomaTorinozoku"));
                }
            }
            else
            {
                // 盤上の駒を動かした場合☆(^~^)


                // 移動先に駒があれば取る
                if (CanDstOff(PureMemory.dmv_km_c))
                {
                    if (TryFail_DstOff(
                            PureMemory.dmv_ms_t1, // 移動先升
                            PureMemory.dmv_km_c,  // あれば、移動先の相手の駒(取られる駒; capture)
                            PureMemory.dmv_ks_c
#if DEBUG
                            , f
                            , reigai1
#endif
                            ))
                    {
                        return(Pure.FailTrue("TryFail_Tejun1_IdosakiNoKomaWoToru"));
                    }

                    // 取った駒が有れば駒台に増やすぜ☆(^~^)
                    if (TryFail_DaiOn(
                            PureMemory.dmv_km_c,// あれば、移動先の相手の駒(取られる駒; capture)
                            PureMemory.dmv_ks_c,
                            PureMemory.dmv_mk_c
#if DEBUG
                            , f
                            , reigai1
#endif
                            ))
                    {
                        return(Pure.FailTrue("TryFail_Tejun2_TottaKomaWoKomadainiOku"));
                    }
                }


                // 移動元から自分の駒を取り除くぜ☆(^~^)
                if (TryFail_SrcOff(
                        ss,
                        PureMemory.dmv_ms_t0,
                        PureMemory.dmv_km_t0,
                        PureMemory.dmv_mk_t0,
                        PureMemory.dmv_ms_t1 // 移動先升

    #if DEBUG
                        , f
                        , reigai1
    #endif
                        ))
                {
                    return(Pure.FailTrue("TryFail_Tejun3_IdomotoJibunnoKomaTorinozoku"));
                }
            }

            // 移動先に手番の駒を置くぜ☆(^~^)
            if (TryFail_DstOn(
                    PureMemory.dmv_ms_t0,
                    PureMemory.dmv_km_t1,
                    PureMemory.dmv_ms_t1 // 移動先升

#if DEBUG
                    , f
                    , reigai1
#endif
                    ))
            {
                return(Pure.FailTrue("TryFail_Tejun4_IdosakiNiTebanonKomawoOku"));
            }


            //────────────────────────────────────────
            // 最後に診断
            //────────────────────────────────────────
gt_EndMethod:
            return(Pure.SUCCESSFUL_FALSE);
        }
Exemplo n.º 16
0
        /// <summary>
        /// 初期局面としてセットするぜ☆(^▽^)
        /// </summary>
        public static bool TryFail_SetSyokiKyokumen_ByFen(
            FenSyurui f,
            string[] danMojiretu, // [0~3]1段目~4段目、[0~2]1筋目~3筋目
            string motigoma,
            string tb_Mojis       //手番
#if DEBUG
            , IDebugMojiretu dbg_reigai
#endif
            )
        {
            PureMemory.gky_ky.Tukurinaosi_ClearKyokumen();

            // 持ち駒パース
            {
                //PureMemory.gky_ky.motigomaItiran.Clear();
                if ("-" != motigoma)// '-' は持ち駒無し
                {
                    int maisu = 0;
                    for (int caret = 0; caret < motigoma.Length; caret++)
                    {
                        char ch = motigoma[caret];

                        int numeric;
                        if (int.TryParse(ch.ToString(), out numeric))
                        {
                            maisu = maisu * 10 + numeric;
                        }
                        else
                        {
                            Motigoma mk;
                            if (!LisMotiKoma.TryParseFen(f, ch, out mk))
                            {
                                return(Pure.FailTrue("TryParseFen"));
                            }
                            else
                            {
                                // 枚数の指定がなかったとき(=0)は、1。
                                PureMemory.gky_ky.motigomaItiran.Set(mk, maisu == 0 ? 1 : maisu);
                                maisu = 0;
                            }
                        }
                    }
                }
            }

            // 盤上の升(既にクリアされているものとするぜ☆)
            int suji;

            for (int dan = 1; dan <= danMojiretu.Length; dan++) // 1段目~N段目 の順に解析。
            {
                //
                // "2z" のように、3列を 2桁 で表記しているので、タテ筋のループ・カウントの数え方には注意だぜ☆(^~^)
                //
                suji = 1;
                int  ruikeiKuhakuSu = 0;                 //累計空白数
                bool isPowerupKoma  = false;             //パワーアップ駒(成りゴマ)
                for (int caret = 0;                      //caret < 3 &&
                     caret < danMojiretu[dan - 1].Length // 可変長配列☆
                     ; caret++)
                {
                    char moji = danMojiretu[dan - 1][caret];

                    int kuhaku;
                    if ('+' == moji)
                    {
                        isPowerupKoma = true;
                    }
                    else if (int.TryParse(moji.ToString(), out kuhaku))
                    {
                        // 数字は空き升の個数なので、筋を進めるぜ☆(^▽^)
                        // とりあえず 1~9 まで対応できるだろうなんだぜ☆(^~^)
                        //for (int i = 0; i < kuhaku; i++)
                        //{
                        ruikeiKuhakuSu = ruikeiKuhakuSu * 10 + kuhaku;
                        //}

                        //Mojiretu reigai1 = new StringBuilder();
                        //reigai1.AppendLine($"未定義の空白の数 moji=[{moji}]");
                        //reigai1.AppendLine($"dan   =[{dan}]");
                        //reigai1.AppendLine($"caret =[{caret}]");
                        //reigai1.AppendLine($"danMojiretu[dan-1] =[{danMojiretu[dan - 1]}]");

                        //throw new Exception(reigai1.ToContents());
                    }
                    else
                    {
                        // 駒でした。
                        if (0 < ruikeiKuhakuSu)
                        {
                            // 空白は置かなくていいのでは?
                            //Masu ms = Conv_Masu.ToMasu(suji, dan);
                            //Koma km_actual = GetBanjoKoma(ms);
                            //HerasuBanjoKoma(ms, km_actual, true);

                            suji          += ruikeiKuhakuSu;
                            ruikeiKuhakuSu = 0;
                        }

                        Piece tmp;
                        if (!LisKoma.Try_ParseFen(f, (isPowerupKoma ? $"+{moji}" : moji.ToString()), out tmp))
                        {
#if DEBUG
                            Pure.Sc.AddErr(string.Format("SetNaiyoで未定義の駒が指定されました。 fen moji=[{0}]", moji));
#endif
                            return(Pure.FailTrue("Try_ParseFen"));
                        }
                        isPowerupKoma = false;

                        if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//SetNaiyo
                                Conv_Masu.ToMasu(suji, dan), tmp, true
#if DEBUG
                                , dbg_reigai
#endif
                                ))
                        {
                            return(Pure.FailTrue("TryFail_Oku"));
                        }
                        // あとで適用

                        suji += 1;
                    }
                }

                if (0 < ruikeiKuhakuSu)
                {
                    // 空白は置かなくていいのでは?
                    //Masu ms = Conv_Masu.ToMasu(suji, dan);
                    //HerasuBanjoKoma(ms, GetBanjoKoma(ms), true);

                    suji          += ruikeiKuhakuSu;
                    ruikeiKuhakuSu = 0;
                }
            }

            // 手番
            {
                Taikyokusya syokikyokumenTai;
                if (!Med_Parser.Try_MojiToTaikyokusya(f, tb_Mojis, out syokikyokumenTai))
                {
#if DEBUG
                    dbg_reigai.AppendLine(string.Format("SetNaiyoで未定義の手番が指定されたんだぜ☆ isSfen={0} 入力={1} 出力={2}",
                                                        f,
                                                        tb_Mojis,
                                                        syokikyokumenTai
                                                        ));
                    //reigai1.AppendLine($"ky.Teban=[{PureMemory.gky_ky.yomiKy.teban}]");
                    //reigai1.AppendLine($"BanTateHaba=[{PureSettei.banTateHaba}]");

                    dbg_reigai.AppendLine(string.Format("持ち駒数一覧({0}件)", danMojiretu.Length));
                    foreach (Motigoma mk in Conv_Motigoma.itiran)
                    {
                        dbg_reigai.AppendLine(string.Format("{0}={1}", mk, PureMemory.gky_ky.motigomaItiran.yomiMotigomaItiran.Count(mk)));
                    }
#endif
                    return(Pure.FailTrue("Try_Taikyokusya"));
                    //throw new Exception($"対局者のパースエラー tb_Mojis=[{tb_Mojis}]{reigai1.ToContents()}");
                }
                // 先手番始まりか、後手番始まりか、に合わせるぜ☆(^~^)
                PureMemory.ResetTebanArray(syokikyokumenTai);
                // 手番には 1 が入っていると思うんだが、無視して 0 スタートに固定するぜ☆(^~^)
                // PureMemory.ClearTeme();
            }

            return(Pure.SUCCESSFUL_FALSE);
        }
Exemplo n.º 17
0
        /// <summary>
        /// トライできる先。
        /// </summary>
        /// <param name="ky">局面</param>
        /// <param name="kikiBB">手番らいおんの利きビットボード</param>
        /// <param name="tb">手番</param>
        /// <param name="ms1">手番らいおんがいる升</param>
        /// <returns></returns>
        public static Bitboard GetTrySaki(Bitboard kikiBB, Masu ms1)
        {
#if DEBUG
            Util_Test.AppendLine("テスト: トライルール", Pure.Sc.dbgMojiretu);
#endif
            m_trySakiBB_.Clear();

            // 自分はN段目にいる☆
            int  dan     = Conv_Masu.ToDanO1_JibunSiten(PureMemory.kifu_teban, ms1);
            bool nidanme = 2 == dan;
#if DEBUG
            Util_Test.AppendLine($"2段目にいるか☆?[{nidanme}] わたしは[{dan}]段目にいるぜ☆", Pure.Sc.dbgMojiretu);
#endif
            if (!nidanme)
            {
#if DEBUG
                Util_Test.AppendLine("むりだぜ☆", Pure.Sc.dbgMojiretu);
                //Util_Test.Flush(reigai1);
#endif
                return(m_trySakiBB_);
            }

            // 1段目に移動できる升☆

            m_trySakiBB_.Set(kikiBB);
            m_trySakiBB_.Siborikomi(BitboardsOmatome.bb_try[PureMemory.kifu_nTeban]);

#if DEBUG
            Interproject.project.Dbg_TryRule1(kikiBB, m_trySakiBB_);
#endif

            // 味方の駒がないところ☆
            Bitboard spaceBB = new Bitboard();
            spaceBB.Set(BitboardsOmatome.bb_boardArea);
            PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_teban, spaceBB);
            m_trySakiBB_.Siborikomi(spaceBB);

#if DEBUG
            Interproject.project.Dbg_TryRule2(spaceBB, m_trySakiBB_);
#endif
            if (m_trySakiBB_.IsEmpty())
            {
#if DEBUG
                Util_Test.AppendLine("むりだぜ☆", Pure.Sc.dbgMojiretu);
                //Util_Test.Flush(reigai1);
#endif
                return(m_trySakiBB_);
            }

            // 相手の利きが届いていないところ☆
            Bitboard safeBB = new Bitboard();
            safeBB.Set(BitboardsOmatome.bb_boardArea);
            PureMemory.gky_ky.yomiKy.yomiShogiban.yomiKikiBan.ToSitdown_BBKikiZenbu(PureMemory.kifu_aiteban, safeBB);
            m_trySakiBB_.Siborikomi(safeBB);

#if DEBUG
            Interproject.project.Dbg_TryRule3(safeBB, m_trySakiBB_);
#endif
            if (m_trySakiBB_.IsEmpty())
            {
#if DEBUG
                Util_Test.AppendLine("むりだぜ☆", Pure.Sc.dbgMojiretu);
                //Util_Test.Flush(reigai1);
#endif
                return(m_trySakiBB_);
            }

#if DEBUG
            Util_Test.AppendLine("トライできるぜ☆", Pure.Sc.dbgMojiretu);
            //Util_Test.Flush(reigai1);
#endif

            return(m_trySakiBB_);
        }
Exemplo n.º 18
0
        /// <summary>
        /// 盤のサイズが設定されたあとに呼び出すこと
        /// </summary>
        public static void Tukurinaosi(
#if DEBUG
            string dbg_hint
#endif
            )
        {
            int tate          = PureSettei.banTateHaba;
            int yoko          = PureSettei.banYokoHaba;
            int heimen        = PureSettei.banHeimen;
            int nanamedanDLen = PureSettei.banNanameDanLen;

            {
                //----------------------------------------
                // ビットボードの作り直し(端チェックをするものを先に)
                //----------------------------------------
                // 筋
                {
                    // o--
                    // o--
                    // o--
                    // o--
                    bb_sujiArray = new Bitboard[yoko];
                    // 左端列を立てる。
                    bb_sujiArray[0] = new Bitboard();
                    for (int iDan = 0; iDan < tate; iDan++)
                    {
                        bb_sujiArray[0].Standup((Masu)(iDan * yoko));
                    }
                    // 1ビットずつ左シフトしていく。
                    for (int iSuji = 1; iSuji < yoko; iSuji++)
                    {
                        bb_sujiArray[iSuji] = new Bitboard();
                        bb_sujiArray[iSuji].Set(bb_sujiArray[iSuji - 1]);
                        bb_sujiArray[iSuji].LeftShift(1);
                    }
                }
                // 段
                {
                    bb_danArray = new Bitboard[tate];
                    // 1段目のビットは全て立てるぜ☆(^~^)
                    bb_danArray[0] = new Bitboard();
                    for (int iSuji = 0; iSuji < yoko; iSuji++)
                    {
                        bb_danArray[0].Standup((Masu)iSuji);// 1段目は筋も升も同じ番号。
                    }
                    // 2段目以降は、左ビットシフト☆(^~^)
                    for (int iDan = 1; iDan < tate; iDan++)
                    {
                        bb_danArray[iDan] = new Bitboard();
                        bb_danArray[iDan].Set(bb_danArray[iDan - 1]);
                        bb_danArray[iDan].LeftShift(yoko);
                        //#if DEBUG
                        //                    Util_Machine.Syuturyoku.AppendLine($"iDan=[{ iDan }] KyokumenImpl.BB_DanArray[iDan]=[{ KyokumenImpl.BB_DanArray[iDan].Value }] Option_Application.Optionlist.BanTateHaba=[{ Option_Application.Optionlist.BanTateHaba }] Option_Application.Optionlist.BanYokoHaba=[{ Option_Application.Optionlist.BanYokoHaba }]");
                        //                    Util_Machine.Flush(Util_Machine.Syuturyoku);
                        //#endif
                    }
                }

                //────────────────────
                // トライ用ビットボード
                //────────────────────
                bb_try = new Bitboard[Conv_Taikyokusya.itiran.Length];
                bb_try[(int)Taikyokusya.T1] = bb_danArray[0];
                bb_try[(int)Taikyokusya.T2] = bb_danArray[PureSettei.banTateHaba - 1];
                // トライ段
                {
                    bb_try[(int)Taikyokusya.T1] = bb_danArray[0];
                    bb_try[(int)Taikyokusya.T2] = bb_danArray[tate - 1];
                }

                //────────────────────
                // 成り用ビットボード
                //────────────────────
                bb_nareruZone = new Bitboard[Conv_Taikyokusya.itiran.Length];
                if (PureSettei.gameRule == GameRule.HonShogi)
                {
                    // 9x9マス盤を想定☆(^~^)
                    bb_nareruZone[(int)Taikyokusya.T1] = bb_danArray[0].Clone();
                    bb_nareruZone[(int)Taikyokusya.T1].Standup(bb_danArray[1]);
                    bb_nareruZone[(int)Taikyokusya.T1].Standup(bb_danArray[2]);
                    bb_nareruZone[(int)Taikyokusya.T2] = bb_danArray[PureSettei.banTateHaba - 1].Clone();
                    bb_nareruZone[(int)Taikyokusya.T2].Standup(bb_danArray[PureSettei.banTateHaba - 2]);
                    bb_nareruZone[(int)Taikyokusya.T2].Standup(bb_danArray[PureSettei.banTateHaba - 3]);
                }
                else
                {
                    bb_nareruZone[(int)Taikyokusya.T1] = bb_danArray[0].Clone();
                    bb_nareruZone[(int)Taikyokusya.T2] = bb_danArray[PureSettei.banTateHaba - 1].Clone();
                }


                //────────────────────
                // ビットボードのうち、ゲームに使っているビット
                //────────────────────
                bb_boardArea_ = new Bitboard();
                // ビットを立てていく。
                if (0 < PureSettei.banHeimen)
                {
                    bb_boardArea.Set(1);
                    for (int i = 1; i < PureSettei.banHeimen; i++)
                    {
                        bb_boardArea.LeftShift(1);
                        bb_boardArea.Standup((Masu)0);
                    }
                }
                else
                {
                    bb_boardArea.Clear();
                }

                //────────────────────
                // うさぎが飛べる升ビットボード
                //────────────────────
                bb_usagigaMiginiToberu   = new Bitboard[Conv_Taikyokusya.itiran.Length];
                bb_usagigaHidariniToberu = new Bitboard[Conv_Taikyokusya.itiran.Length];
                foreach (Taikyokusya tai in Conv_Taikyokusya.itiran)
                {
                    bb_usagigaMiginiToberu[(int)tai]   = new Bitboard();
                    bb_usagigaHidariniToberu[(int)tai] = new Bitboard();

                    bb_usagigaMiginiToberu[(int)tai].Set(bb_boardArea);
                    bb_usagigaHidariniToberu[(int)tai].Set(bb_boardArea);

                    // 1段目と2段目を省く
                    for (int iDanO0 = 0; iDanO0 < 2; iDanO0++)
                    {
                        bb_usagigaMiginiToberu[(int)tai].Sitdown(bb_danArray[Conv_Masu.ToDanO0_JibunSiten_ByDanO0(tai, iDanO0)]);
                        bb_usagigaHidariniToberu[(int)tai].Sitdown(bb_danArray[Conv_Masu.ToDanO0_JibunSiten_ByDanO0(tai, iDanO0)]);
                    }

                    // 右跳びは 9筋 を省く
                    bb_usagigaMiginiToberu[(int)tai].Sitdown(bb_sujiArray[Conv_Masu.ToSujiO0_JibunSiten_BySujiO0(tai, PureSettei.banYokoHaba - 1)]);
                    // 左跳びは 1筋 を省く
                    bb_usagigaHidariniToberu[(int)tai].Sitdown(bb_sujiArray[Conv_Masu.ToSujiO0_JibunSiten_BySujiO0(tai, 0)]);
                }
            }



            //────────────────────
            // 筋一列ビットボード
            //────────────────────
            // o--
            // o--
            // o--
            // o--
            bb_sujiArray    = new Bitboard[PureSettei.banYokoHaba];
            bb_sujiArray[0] = new Bitboard();
            //// 0x249 → 10 0100 1001(2進数)
            //BB_SujiArray[0].Set(0x249);
            // 筋一列を立てます
            for (int iDan = 0; iDan < PureSettei.banTateHaba; iDan++)
            {
                bb_sujiArray[0].Standup((Masu)(iDan * PureSettei.banYokoHaba));
            }

            // 2筋目以降
            for (int iSuji = 1; iSuji < PureSettei.banYokoHaba; iSuji++)
            {
                bb_sujiArray[iSuji] = new Bitboard();
                bb_sujiArray[iSuji].Set(bb_sujiArray[iSuji - 1]);
                bb_sujiArray[iSuji].LeftShift(1);
            }

            //────────────────────
            // 段一列ビットボード
            //────────────────────
            // ooo
            // ---
            // ---
            // ---
            bb_danArray    = new Bitboard[PureSettei.banTateHaba];
            bb_danArray[0] = new Bitboard();
            //// 0x07 → 111(2進数)
            //BB_DanArray[0].Set(0x07);
            // 段一列を立てます
            for (int iSuji = 0; iSuji < PureSettei.banYokoHaba; iSuji++)
            {
                bb_danArray[0].Standup((Masu)iSuji);
            }

            // 2段目以降
            for (int iDan = 1; iDan < PureSettei.banTateHaba; iDan++)
            {
                bb_danArray[iDan] = new Bitboard();
                bb_danArray[iDan].Set(bb_danArray[iDan - 1]);
                bb_danArray[iDan].LeftShift(PureSettei.banYokoHaba);
            }

            //────────────────────
            // ローテート・ビットボードの置換表
            //────────────────────
            RotateChikanhyo.Tukurinaosi();

            //────────────────────
            // 左上がり筋一列ビットボード
            //────────────────────
            // o---
            // -o--
            // --o-
            // ---o
            {
                bb_hidariAgariSujiArray = new Bitboard[PureSettei.banNanameDanLen];
                int preDiagonals = -1;
                ScanHidariAgariSuji((int diagonals, Masu ms) =>
                {
                    if (preDiagonals != diagonals)
                    {
                        bb_hidariAgariSujiArray[diagonals] = new Bitboard();
                        preDiagonals = diagonals;
                    }
                    bb_hidariAgariSujiArray[diagonals].Standup(ms);
                });
            }

            //────────────────────
            // 左下がり筋一列ビットボード
            //────────────────────
            // ---o
            // --o-
            // -o--
            // o---
            {
                bb_hidariSagariSujiArray = new Bitboard[PureSettei.banNanameDanLen];
                int preDiagonals = -1;
                ScanHidariSagariSuji((int diagonals, Masu ms) =>
                {
                    if (preDiagonals != diagonals)
                    {
                        bb_hidariSagariSujiArray[diagonals] = new Bitboard();
                        preDiagonals = diagonals;
                    }
                    bb_hidariSagariSujiArray[diagonals].Standup(ms);
                });
            }


            //────────────────────
            // 持駒を進める(打てる)ゾーン
            //────────────────────
            // 駒の行き所のない段に打つのを防止
            // 段配列をセットしたあとで
            {
                bb_uteruZone = new Bitboard[Conv_Koma.itiran.Length];
                foreach (Piece km in Conv_Koma.itiran)
                {
                    // まず、盤面全体に打てるとするぜ☆(^~^)
                    bb_uteruZone[(int)km] = bb_boardArea.Clone();

                    // 次に個別に、打てない場所を除外しろだぜ☆(^~^)
                    if (PureSettei.gameRule == GameRule.HonShogi)
                    {
                        switch (km)
                        {
                        // ひよこ、いのしし
                        case Piece.P1:
                        case Piece.L1:
                            bb_uteruZone[(int)km].Sitdown(bb_danArray[0]);
                            break;

                        case Piece.P2:
                        case Piece.L2:
                            bb_uteruZone[(int)km].Sitdown(bb_danArray[tate - 1]);
                            break;

                        // うさぎ
                        case Piece.N1:
                            bb_uteruZone[(int)km].Sitdown(bb_danArray[0]);
                            bb_uteruZone[(int)km].Sitdown(bb_danArray[1]);
                            break;

                        case Piece.N2:
                            bb_uteruZone[(int)km].Sitdown(bb_danArray[tate - 1]);
                            bb_uteruZone[(int)km].Sitdown(bb_danArray[tate - 2]);
                            break;

                        default:
                            break;
                        }
                    }
                }
            }


            //────────────────────
            // 駒の動き方
            //────────────────────
            KomanoUgokikataYk00.Tukurinaosi(
#if DEBUG
                dbg_hint
#endif
                );
        }
Exemplo n.º 19
0
 static void ToStandup_ByElement(Piece km, Masu ms, Bitboard bb_update)
 {
     Debug.Assert(Conv_Masu.IsBanjo(ms));
     bb_update.Standup(TonarikikiElement.ugokikataTon[(int)km][(int)ms]);
 }
Exemplo n.º 20
0
        /// <summary>
        /// 一手詰めの局面かどうか調べるぜ☆(^▽^)
        ///
        /// 盤上の駒を動かすのか、駒台の駒を打つのかによって、利き の形が異なるぜ☆(^~^)
        ///
        /// 自分が一手詰めを掛けられるから、この指し手は作らないでおこう、といった使い方がされるぜ☆(^▽^)
        ///
        /// FIXME: 成りを考慮してない
        /// </summary>
        /// <param name="ky2"></param>
        /// <param name="ms_t0">移動元。持ち駒の場合、エラー値</param>
        /// <param name="ms_t1">移動先</param>
        /// <param name="tebanHioute"></param>
        /// <returns></returns>
        public static bool CheckBegin_Tume1_BanjoKoma()
        {
            Debug.Assert(Conv_Masu.IsBanjo(PureMemory.ssss_ugoki_ms_dst), "升エラー");

            if (!PureSettei.ittedumeTukau)
            {
                return(false);
            }

            // 動かす駒
            Komasyurui ks_t0;

            if (!PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ExistsKoma(PureMemory.kifu_teban, PureMemory.ssss_ugoki_ms_src, out ks_t0))
            {
                // エラー。盤上の駒ではないのかも☆(^~^)
                throw new Exception(Interproject.project.Owata("TryFail_Ittedume_BanjoKoma gky.ky.shogiban.ibashoBan.ExistsBBKoma(1)", PureMemory.tnsk_hyoji));
            }

            Piece km_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks_t0, PureMemory.kifu_teban);
            Piece km_t1 = km_t0; // FIXME: 成りを考慮していないぜ☆(>_<)

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

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

            if (!PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.IsIntersect(Med_Koma.ToRaion(PureMemory.kifu_aiteban),                                            // 相手のらいおん
                                                                           BitboardsOmatome.KomanoUgokikataYk00.Clone_Merge(km_t0, PureMemory.ssss_ugoki_ms_dst) // 移動先での駒の利き
                                                                           ))                                                                                    // 相手らいおん が、移動先での駒の利きの中に居ないんだったら、一手詰め にはならないぜ☆(^~^)
            {
                // FIXME: ステイルメイトは考えてないぜ☆(>_<)
                return(false);
            }

            Bitboard bb_idogoKikiNew = new Bitboard();// 移動後の、利き
            {
                // 盤上の重ね利きの数を差分更新するぜ☆(^▽^)
                // 移動元の駒の利きを消すぜ☆(^▽^)
                PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km_t0, PureMemory.ssss_ugoki_ms_src);

                // 現局面より 利き が減っているのが正しい


                // 移動先の駒の利きを増やすぜ☆(^▽^)
                PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km_t1, PureMemory.ssss_ugoki_ms_dst);

                // ここで、現行の利きは変更されているぜ☆(^~^)駒は移動していないので、再計算の駒配置は 現行の利きと異なるぜ☆(^~^)

                // 移動後の利きを作り直し
                bb_idogoKikiNew = PureMemory.gky_ky.shogiban.kikiBan.RefBB_FromKikisuZenbuPositiveNumber(PureMemory.kifu_teban);

                // 盤上の重ね利きの数の差分更新を元に戻すぜ☆(^▽^)
                {
                    // 移動先の駒の利きを減らすぜ☆(^▽^)
                    PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km_t1, PureMemory.ssss_ugoki_ms_dst);

                    // 駒の利きを減らしているぜ☆(^~^) 駒は減っていないので、再計算すると結果が異なるぜ☆(^~^)

                    // 移動元の駒の利きを増やすぜ☆(^▽^)
                    PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km_t0, PureMemory.ssss_ugoki_ms_src);
                }
            }



            Bitboard bb1 = PureMemory.hot_bb_raion8KinboAr[PureMemory.kifu_nAiteban].Clone();                          // 相手らいおん が逃げれる、相手らいおんの周りの空白

            PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, bb1); // 相手の駒がない升
            return
                (bb1.Sitdown(bb_idogoKikiNew)                                                                          // こっちの利きがない升
                 .IsEmpty());                                                                                          // がない場合、詰み☆

            ;
        }
Exemplo n.º 21
0
        public static bool CanDoMove(Move ss, out MoveMatigaiRiyu reason)
        {
            if (Move.Toryo == ss)
            {
                reason = MoveMatigaiRiyu.Karappo; return(true);
            }                                                                       // 投了はOKだぜ☆(^~^)

            // 打つ駒調べ
            MotigomaSyurui mksUtta = AbstractConvMove.GetUttaKomasyurui(ss);// 打った駒の種類
            bool           utta    = MotigomaSyurui.Yososu != mksUtta;

            if (utta)
            {
                // 「打」の場合、持ち駒チェック☆
                if (!PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.HasMotigoma(Med_Koma.MotiKomasyuruiAndTaikyokusyaToMotiKoma(mksUtta, PureMemory.kifu_teban)))
                {
                    // 持駒が無いのに打とうとしたぜ☆(>_<)
                    reason = MoveMatigaiRiyu.NaiMotiKomaUti;
                    return(false);
                }
            }

            // 移動先、打つ先 調べ☆
            Masu ms_dst = AbstractConvMove.GetDstMasu_WithoutErrorCheck((int)ss); // 移動先升

            if (!Conv_Masu.IsBanjo(ms_dst))
            {
                // 盤外に移動しようとしたぜ☆(^~^)
                reason = MoveMatigaiRiyu.BangaiIdo;
                return(false);
            }
            Piece       km_dst    = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(ms_dst);
            Taikyokusya tai_dstKm = Med_Koma.KomaToTaikyokusya(km_dst);

            if (km_dst != Piece.Kuhaku && PureMemory.kifu_teban == tai_dstKm)
            {
                // 自分の駒を取ろうとするのは、イリーガル・ムーブだぜ☆(^▽^)
                reason = MoveMatigaiRiyu.TebanKomaNoTokoroheIdo;
                return(false);
            }
            else if (utta && km_dst != Piece.Kuhaku)
            {
                // 駒があるところに打ち込んではいけないぜ☆(^▽^)
                reason = MoveMatigaiRiyu.KomaGaAruTokoroheUti;
                return(false);
            }


            // 移動元調べ☆
            Piece km_src;

            if (utta)
            {
                // 「打」のときは ここ。
                km_src = Med_Koma.MotiKomasyuruiAndTaikyokusyaToKoma(mksUtta, PureMemory.kifu_teban);
            }
            else
            {
                Masu ms_src = AbstractConvMove.GetSrcMasu_WithoutErrorCheck((int)ss); // 移動先升
                km_src = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(ms_src);
                Taikyokusya tai_srcKm = Med_Koma.KomaToTaikyokusya(km_src);
                if (km_src == Piece.Kuhaku)
                {
                    // 空き升に駒があると思って動かそうとするのは、イリーガル・ムーブだぜ☆(^▽^)
                    reason = MoveMatigaiRiyu.KuhakuWoIdo;
                    return(false);
                }
                else if (tai_srcKm != PureMemory.kifu_teban)
                {
                    // 相手の駒を動かそうとするのは、イリーガル・ムーブだぜ☆(^▽^)
                    reason = MoveMatigaiRiyu.AiteNoKomaIdo;
                    return(false);
                }


                // 移動方向調べ
                if (!BitboardsOmatome.KomanoUgokikataYk00.IsIntersect(
                        km_src,
                        ms_src, //この2つのマスが交わっているか
                        ms_dst  //この2つのマスが交わっているか
                        ))
                {
                    // その駒の種類からは、ありえない動きをしたぜ☆(^▽^)
//#if DEBUG

//                    throw new Exception($"その駒の種類からは、ありえない動きをしたぜ☆(^▽^) ms1=[{ ms_src }] ms2=[{ ms_dst }]");
//#else
                    reason = MoveMatigaiRiyu.SonoKomasyuruiKarahaArienaiUgoki;
                    return(false);
//#endif
                }
            }


            // 成り調べ
            if (AbstractConvMove.IsNatta(ss))//成りを指示した場合
            {
                switch (PureSettei.gameRule)
                {
                case GameRule.DobutuShogi:
                {
                    if (Med_Koma.KomaToKomasyurui(km_src) != Komasyurui.H)
                    {
                        // ひよこ以外が、にわとりになろうとしました☆
                        reason = MoveMatigaiRiyu.NarenaiNari;
                        return(false);
                    }
                }
                break;

                case GameRule.HonShogi:
                {
                    switch (Med_Koma.KomaToKomasyurui(km_src))
                    {
                    case Komasyurui.H:
                    case Komasyurui.K:
                    case Komasyurui.N:
                    case Komasyurui.S:
                    case Komasyurui.U:
                    case Komasyurui.Z:
                        // セーフ
                        break;

                    case Komasyurui.I:
                    case Komasyurui.PH:
                    case Komasyurui.PK:
                    case Komasyurui.PN:
                    case Komasyurui.PS:
                    case Komasyurui.PU:
                    case Komasyurui.PZ:
                    case Komasyurui.R:
                    case Komasyurui.Yososu:            //FIXME:
                    default:
                    {
                        // 成れる駒以外が、成ろうとしました☆
                        reason = MoveMatigaiRiyu.NarenaiNari;
                        return(false);
                    }
                    }
                }
                break;
                }
            }

            reason = MoveMatigaiRiyu.Karappo;
            return(true);
        }