示例#1
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());                                           // がない場合、詰み☆

            ;
        }
示例#2
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());                                                          // 相手らいおん が逃げれる升がない場合、詰み☆
        }