Exemple #1
0
        /// <summary>
        /// 指し手情報を分解するぜ☆(^~^)
        /// 駒を動かす方を手番、相手を相手番と考えるぜ☆(^~^)
        /// </summary>
        public static void BunkaiMoveDmv(Move ss)
        {
            //
            // 動かす駒を t0 と呼ぶとする。
            //      移動元を t0、移動先を t1 と呼ぶとする。
            // 取られる駒を c と呼ぶとする。
            //      取られる駒の元位置は t1 、駒台は 3 と呼ぶとする。
            //

            // 変数をグローバルに一時退避
            // 移動先升
            PureMemory.dmv_ms_t1 = AbstractConvMove.GetDstMasu_WithoutErrorCheck((int)ss);
            // あれば、移動先の相手の駒(取られる駒; capture)
            PureMemory.dmv_km_c = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(PureMemory.kifu_aiteban, PureMemory.dmv_ms_t1);
            PureMemory.dmv_ks_c = Med_Koma.KomaToKomasyurui(PureMemory.dmv_km_c);
            PureMemory.dmv_mk_c = Med_Koma.BanjoKomaToMotiKoma(PureMemory.dmv_km_c);

            if (AbstractConvMove.IsUtta(ss))
            {
                // 打
                PureMemory.dmv_ms_t0 = Conv_Masu.masu_error;

                // 指し手から「持駒」を判別
                PureMemory.dmv_mks_t0 = AbstractConvMove.GetUttaKomasyurui(ss);
                PureMemory.dmv_mk_t0  = Med_Koma.MotiKomasyuruiAndTaikyokusyaToMotiKoma(PureMemory.dmv_mks_t0, PureMemory.kifu_teban);
                // 「持駒」から「駒」へ変換
                PureMemory.dmv_km_t0 = Med_Koma.MotiKomasyuruiAndTaikyokusyaToKoma(PureMemory.dmv_mks_t0, PureMemory.kifu_teban);

                // 持ち駒は t0 も t1 も同じ。
                PureMemory.dmv_km_t1 = PureMemory.dmv_km_t0;
                PureMemory.dmv_ks_t0 = Med_Koma.MotiKomasyuruiToKomasyrui(PureMemory.dmv_mks_t0); //おまとめ☆(^~^)
                PureMemory.dmv_ks_t1 = PureMemory.dmv_ks_t0;                                      //追加
                //#if DEBUG
                //                if (!gky.ky.motiKomas.sindanMK.HasMotiKoma(mk_t0))
                //                {
                //                    CommandK.Ky(isSfen, "ky", gky, syuturyoku);
                //                    Util_Machine.Flush(syuturyoku);
                //                }
                //#endif
                Debug.Assert(PureMemory.gky_ky.motigomaItiran.yomiMotigomaItiran.HasMotigoma(PureMemory.dmv_mk_t0),
                             $"持っていない駒を打つのか☆(^~^)!? mks_src=[{ PureMemory.dmv_mks_t0 }] mk_utu=[{ PureMemory.dmv_mk_t0 }]");
            }
            else
            {
                // 指し
                PureMemory.dmv_ms_t0  = AbstractConvMove.GetSrcMasu_WithoutErrorCheck((int)ss);
                PureMemory.dmv_km_t0  = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(PureMemory.dmv_ms_t0);
                PureMemory.dmv_ks_t0  = Med_Koma.KomaToKomasyurui(PureMemory.dmv_km_t0);//移動元の駒の種類
                PureMemory.dmv_mks_t0 = MotigomaSyurui.Yososu;
                PureMemory.dmv_mk_t0  = Motigoma.Yososu;
                if (AbstractConvMove.IsNatta(ss)) // 駒が成るケース
                {
                    PureMemory.dmv_ks_t1 = Conv_Komasyurui.ToNariCase(PureMemory.dmv_ks_t0);
                    PureMemory.dmv_km_t1 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(PureMemory.dmv_ks_t1, PureMemory.kifu_teban);
                }
                else // 駒が成らないケース
                {
                    PureMemory.dmv_km_t1 = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(PureMemory.dmv_ms_t0);
                    PureMemory.dmv_ks_t1 = PureMemory.dmv_ks_t0;
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// 改造FEN符号表記
        /// </summary>
        /// <returns></returns>
        public static void AppendFenTo(FenSyurui f, Move ss, StringBuilder syuturyoku)
        {
            if (Move.Toryo == ss)
            {
                syuturyoku.Append(Itiran_FenParser.GetToryo(f)); return;
            }

            int v = (int)ss;//バリュー(ビットフィールド)

            // 打った駒の種類(取り出すのは難しいので関数を使う☆)
            MotigomaSyurui mksUtta = AbstractConvMove.GetUttaKomasyurui(ss);

            if (MotigomaSyurui.Yososu != mksUtta)//指定があれば
            {
                // 打でした。

                // (自)筋・(自)段は書かずに、「P*」といった表記で埋めます。
                SpkMotiKomasyurui.AppendFenTo(f, mksUtta, syuturyoku);
                syuturyoku.Append("*");
            }
            else
            {
                //------------------------------------------------------------
                // (自)筋
                //------------------------------------------------------------
                //Option_Application.Optionlist.USI
                switch (f)
                {
                case FenSyurui.sfe_n:
                {
                    syuturyoku.Append(PureSettei.banYokoHaba + 1 - AbstractConvMove.GetSrcSuji_WithoutErrorCheck(v));
                }
                break;

                case FenSyurui.dfe_n:
                {
                    syuturyoku.Append(Conv_Kihon.ToAlphabetLarge(AbstractConvMove.GetSrcSuji_WithoutErrorCheck(v)));
                }
                break;

                default:
                    throw new Exception(string.Format("未定義 {0}", f));
                }

                //------------------------------------------------------------
                // (自)段
                //------------------------------------------------------------
                //Option_Application.Optionlist.USI
                switch (f)
                {
                case FenSyurui.sfe_n:
                {
                    syuturyoku.Append(Conv_Kihon.ToAlphabetSmall(AbstractConvMove.GetSrcDan_WithoutErrorCheck(v)));
                }
                break;

                case FenSyurui.dfe_n:
                {
                    syuturyoku.Append(AbstractConvMove.GetSrcDan_WithoutErrorCheck(v).ToString());
                }
                break;

                default:
                    throw new Exception(string.Format("未定義 {0}", f));
                }
            }

            //------------------------------------------------------------
            // (至)筋
            //------------------------------------------------------------
            //Option_Application.Optionlist.USI
            switch (f)
            {
            case FenSyurui.sfe_n:
            {
                syuturyoku.Append(PureSettei.banYokoHaba + 1 - AbstractConvMove.GetDstSuji_WithoutErrorCheck(v));
            }
            break;

            case FenSyurui.dfe_n:
            {
                syuturyoku.Append(Conv_Kihon.ToAlphabetLarge(AbstractConvMove.GetDstSuji_WithoutErrorCheck(v)));
            }
            break;

            default:
                throw new Exception(string.Format("未定義 {0}", f));
            }

            //------------------------------------------------------------
            // (至)段
            //------------------------------------------------------------
            //Option_Application.Optionlist.USI
            switch (f)
            {
            case FenSyurui.sfe_n:
            {
                syuturyoku.Append(Conv_Kihon.ToAlphabetSmall(AbstractConvMove.GetDstDan_WithoutErrorCheck(v)));
            }
            break;

            case FenSyurui.dfe_n:
            {
                syuturyoku.Append(AbstractConvMove.GetDstDan_WithoutErrorCheck(v).ToString());
            }
            break;

            default:
                throw new Exception(string.Format("未定義 {0}", f));
            }

            //------------------------------------------------------------
            // 成
            //------------------------------------------------------------
            int natta;

            {
                // (v & m) >> s + 1。 v:バリュー、m:マスク、s:シフト
                natta = (v & (int)MoveMask.NATTA) >> (int)MoveShift.NATTA;
            }
            if (1 == natta)
            {
                syuturyoku.Append("+");
            }
        }
Exemple #3
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);
        }