Beispiel #1
0
        public static void Setumei(FenSyurui f, StringBuilder hyoji)
        {
            bool isBelow = false;

            MoveGenAccessor.ScanBestYomisuji((int iKifu, ref bool toBreak) =>
            {
                if (isBelow)
                {
                    // 2週目以降は空白を挟むぜ☆(^~^)
                    hyoji.Append(" ");
                }
                else
                {
                    isBelow = true;
                }

                SpkMove.AppendFenTo(f, PureMemory.kifu_moveArray[iKifu], hyoji);
            });
        }
Beispiel #2
0
        // 成れる駒(Nareru Koma) 逼迫返討手
        public static void GenerateNk_HippakuKaeriutiTe()
        {
            if (PureMemory.hot_isNigerarenaiCheckerAr[PureMemory.kifu_nTeban])
            {
                // 逃げられない状況で、王手が掛かけられていれば☆(^~^)

                // 成れる場合
                while (PureMemory.ssss_bbVar_idosaki_nari.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst))
                {
                    PureMemory.SetSsssGenk(
                        Tume1Hantei.CheckBegin_Tume1_BanjoKoma(),// 一手詰めルーチン☆
                        false,
                        false
                        );

                    // チェッカーを取るような全ての手は、選択肢に入れるぜ☆(^~^)
                    MoveGenAccessor.AddMoveNariGood();

                    if (Tume1Hantei.CheckEnd_Tume1())
                    {
                        break;
                    }                                           //終了☆
                }

                while (PureMemory.ssss_bbVar_idosaki_narazu.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst))
                {
                    PureMemory.SetSsssGenk(
                        Tume1Hantei.CheckBegin_Tume1_BanjoKoma(),// 一手詰めルーチン☆
                        false,
                        false
                        );

                    // チェッカーを取るような全ての手は、選択肢に入れるぜ☆(^~^)
                    MoveGenAccessor.AddMoveNarazuGood();

                    if (Tume1Hantei.CheckEnd_Tume1())
                    {
                        break;
                    }                                           //終了☆
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// 1手指すぜ☆(^▽^)
        /// </summary>
        public static void DoMove(Move ss)
        {
            MoveType ssType = MoveType.N00_Karappo;

            if (DoMoveOpe.TryFailDoMoveAll(ss, ssType
#if DEBUG
                                           , PureSettei.fenSyurui
                                           , PureAppli.syuturyoku1
                                           , false
                                           , "Shogi34#DoMove"
#endif
                                           ))
            {
                throw new Exception(PureAppli.syuturyoku1.ToString());
            }
            MoveGenAccessor.AddKifu(ss, ssType, PureMemory.dmv_ks_c);
//#if DEBUG
//            Util_Tansaku.Snapshot("Shogi34", dbg_reigai);
//#endif
        }
Beispiel #4
0
        // らいおん、成れない駒(X Koma) 駒を取る手
        public static void GenerateXk_KomaWoToruTe()
        {
            while (PureMemory.ssss_bbVar_idosaki_narazu.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst))
            {
                // 駒を取るような全ての手は、選択肢に入れるぜ☆(^~^)

                PureMemory.SetSsssGenk(
                    Tume1Hantei.CheckBegin_Tume1_BanjoKoma(),// 一手詰めルーチン☆
                    false,
                    NigemitiWatasuKansyu.IsNigemitiWoAkeru()
                    );

                MoveGenAccessor.AddMoveNarazuGoodXorBad();

                if (Tume1Hantei.CheckEnd_Tume1())
                {
                    break;
                }                                           //終了☆
            }
        }
Beispiel #5
0
        // 成れない駒(X Koma) 捨て緩慢指し(タダ捨て指し)
        public static void GenerateXk_SuteKanmanZasi()
        {
            Debug.Assert(Conv_Koma.IsOk(PureMemory.ssss_ugoki_km), "");

            // 王手も除外するぜ☆(^▽^)
            GenerateMove03.KesuOte();

            while (PureMemory.ssss_bbVar_idosaki_narazu.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst)) // 立っているビットを降ろすぜ☆
            {
                if (GenerateMove03.TadasuteNoUgoki())                                                 // 相手の利きがあって、自分を除いた味方の利きがない升 に限るぜ☆(^▽^)www
                {
                    PureMemory.SetSsssGenk(
                        false, // タダ捨てに、一手詰めは無いだろう☆(*^~^*)
                        GenerateMove03.IsMisuteruUgoki(),
                        false  //逃げ道を開けて逃がすかどうかは判定しないぜ☆(^~^)
                        );

                    MoveGenAccessor.AddMoveNarazuGoodXorBad();
                }
            }
        }
Beispiel #6
0
        // 成れる駒(Nareru Koma) らいおんキャッチ調査 | らいおんキャッチ
        public static void GenerateNk_RaionCatch()
        {
            // 成れる場合
            if (PureMemory.ssss_bbVar_idosaki_nari.GetNTZ(out PureMemory.ssss_ugoki_ms_dst))
            {
                // らいおんをキャッチする手は、1つ見つければOKだぜ☆(^~^)

                if (MoveType.N17_RaionCatchChosa == PureMemory.ssss_ugoki_kakuteiSsType)
                {
                    // 調査するだけ☆ らいおんキャッチできることが分かったので終了☆(^~^)
                    PureMemory.hot_raionCatchChosaAr[PureMemory.kifu_nTeban] = true;
                    return;
                }

                MoveGenAccessor.AddMoveNariGood();
                PureMemory.SetTansakuUtikiri(TansakuUtikiri.RaionTukamaeta);
            }

            if (PureMemory.ssss_bbVar_idosaki_narazu.GetNTZ(out PureMemory.ssss_ugoki_ms_dst))
            {
                // らいおんをキャッチする手は、1つ見つければOKだぜ☆(^~^)

                if (MoveType.N17_RaionCatchChosa == PureMemory.ssss_ugoki_kakuteiSsType)
                {
                    // 調査するだけ☆ らいおんキャッチできることが分かったので終了☆(^~^)
                    PureMemory.hot_raionCatchChosaAr[PureMemory.kifu_nTeban] = true;
                    return;
                }

                PureMemory.SetSsssGenk(
                    false,
                    false,
                    NigemitiWatasuKansyu.IsNigemitiWoAkeru()
                    );
                MoveGenAccessor.AddMoveNarazuGoodXorBad();
                PureMemory.SetTansakuUtikiri(TansakuUtikiri.RaionTukamaeta);
            }
        }
Beispiel #7
0
        // 仲間を見捨てる動きは Badへ☆(^~^)
        // らいおん ぼっち緩慢指 | 紐付き緩慢指 (らいおんは 捨て緩慢指し をやらないぜ☆)
        public static void GenerateRaion_BottiKanmanZasi_HimodukiKanmanZasi()
        {
            // トライ は除外するぜ☆(^▽^)
            GenerateMove03.KesuTry();
            // らいおん が自分から 相手の利きに飛び込むのを防ぐぜ☆(^▽^)www
            GenerateMove03.KesuRaionJisatusyu();

            while (PureMemory.ssss_bbVar_idosaki_narazu.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst))// 立っているビットを降ろすぜ☆
            {
                PureMemory.SetSsssGenk(
                    Tume1Hantei.CheckBegin_Tume1_BanjoKoma(), // 一手詰めルーチン☆
                    GenerateMove03.IsMisuteruUgoki(),
                    false                                     //逃げ道を開けて逃がすかどうかは判定しないぜ☆(^~^)
                    );

                MoveGenAccessor.AddMoveNarazuGoodXorBad();

                if (Tume1Hantei.CheckEnd_Tume1())
                {
                    break;
                }                                           //終了☆
            }
        }
Beispiel #8
0
        /// <summary>
        /// 指定した指し手をやりなおす動きをするぜ☆(^▽^)
        /// </summary>
        /// <param name="ss"></param>
        public static bool TryFailUndoMove(
#if DEBUG
            FenSyurui dbg_f
            , IDebugMojiretu dbg_reigai
#endif
            )
        {
            //────────────────────────────────────────
            // 手番
            //────────────────────────────────────────
            // 事前に戻すぜ☆(^▽^)
            PureMemory.RemoveTeme();

            //────────────────────────────────────────
            // まず最初に整合性を確認だぜ☆(^~^)
            //────────────────────────────────────────

            //────────────────────────────────────────
            // グローバル変数に、結果を入れておくぜ☆(^~^)
            //────────────────────────────────────────
            MoveGenAccessor.BunkaiMoveUmv();

            if (Move.Toryo == PureMemory.umv_ss)
            {
                goto gt_EndMethod;
            }                                                          // なにも更新せず終了☆(^▽^)


            if (TryFail_Tejun1_IdosakiNoTebanNoKomaWoTorinozoku(
#if DEBUG
                    dbg_f
                    , dbg_reigai
#endif
                    ))
            {
                return(Pure.FailTrue("TryFail_Tejun1_IdosakiNoTebanNoKomaWoTorinozoku"));
            }

            if (AbstractConvMove.IsUtta(PureMemory.umv_ss))
            {
                // 打つ
                if (TryFail_Tejun2Utu_IdomotoniTebannoKomawoModosu(
#if DEBUG
                        dbg_f
                        , dbg_reigai
#endif
                        ))
                {
                    return(Pure.FailTrue("TryFail_Tejun2_IdomotoniTebannoKomawoModosu"));
                }
            }
            else
            {
                // 指す
                if (TryFail_Tejun2Sasu_IdomotoniTebannoKomawoModosu(
#if DEBUG
                        dbg_f
                        , dbg_reigai
#endif
                        ))
                {
                    return(Pure.FailTrue("TryFail_Tejun2_IdomotoniTebannoKomawoModosu"));
                }
            }


            if (TryFail_Tejun3_KomadaiKaraTottakomawoJogai(
#if DEBUG
                    dbg_f
                    , dbg_reigai
#endif
                    ))
            {
                return(Pure.FailTrue("TryFail_Tejun3_KomadaiKaraTottakomawoJogai"));
            }

            if (TryFail_Tejun4_IdosakiniTottakomawoModosu(
#if DEBUG
                    dbg_f
                    , dbg_reigai
#endif
                    ))
            {
                return(Pure.FailTrue("TryFail_Tejun4_IdosakiniTottakomawoModosu"));
            }

            //────────────────────────────────────────
            // 最後に一括更新
            //────────────────────────────────────────

gt_EndMethod:
            //────────────────────────────────────────
            // 最後に整合性を確認だぜ☆(^~^)
            //────────────────────────────────────────
            return(Pure.SUCCESSFUL_FALSE);
        }
Beispiel #9
0
        /// <summary>
        /// ここからコンソール・アプリケーションが始まるぜ☆(^▽^)
        ///
        /// PCのコンソール画面のプログラムなんだぜ☆(^▽^)
        /// Unityでは中身は要らないぜ☆(^~^)
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            var playing = new Playing();

            var programSupport = new ProgramSupport();

            // (手順2)きふわらべの応答は、文字列になって ここに入るぜ☆(^▽^)
            // syuturyoku.ToContents() メソッドで中身を取り出せるぜ☆(^~^)
            StringBuilder hyoji = PureAppli.syuturyoku1;

            Interproject.project = new WinconsoleProject();

            if (PureAppli.TryFail_Init())
            {
                Logger.Flush(hyoji);
                throw new Exception(hyoji.ToString());
            }

            // コンソールゲーム用の設定上書き
            ConsolegameSettei.Init_PureAppliOverride();



            // まず最初に「USI\n」が届くかどうかを判定☆(^~^)
            Util_ConsoleGame.ReadCommandline(programSupport, hyoji);
            if (programSupport.commandline == "usi")
            {
                // 「将棋所」で本将棋を指す想定☆(^~^)
                // CommandA.Atmark("@USI9x9", hyoji);

                PureSettei.usi       = true;
                PureSettei.fenSyurui = FenSyurui.sfe_n;

                PureSettei.p1Com             = false;
                PureSettei.p2Com             = false;
                PureSettei.tobikikiTukau     = true; // FIXME: 飛び利きはまだ不具合修正されていないぜ☆(^~^)
                ComSettei.himodukiHyokaTukau = true; // FIXME: 紐付き評価は、使うとしておこう☆(^~^)
                // ルールを確定してから 局面を作れだぜ☆(^~^)
                LisGenkyoku.SetRule(
                    GameRule.HonShogi, 9, 9,
                    @"シウネイライネウシ
 キ     ゾ 
ヒヒヒヒヒヒヒヒヒ
         
         
         
ひひひひひひひひひ
 ぞ     き 
しうねいらいねうし"
                    , new Dictionary <Motigoma, int>()
                {
                    { Motigoma.K, 0 },
                    { Motigoma.Z, 0 },
                    { Motigoma.H, 0 },
                    { Motigoma.k, 0 },
                    { Motigoma.z, 0 },
                    { Motigoma.h, 0 },
                }
                    );

                var profilePath = System.Configuration.ConfigurationManager.AppSettings["Profile"];
                var toml        = Toml.ReadFile(Path.Combine(profilePath, "Engine.toml"));

                var     engineName   = toml.Get <TomlTable>("Engine").Get <string>("Name");
                Version version      = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
                var     engineAuthor = toml.Get <TomlTable>("Engine").Get <string>("Author");

                playing.UsiOk(programSupport.commandline, $"{engineName} {version.Major}.{version.Minor}.{version.Build}", engineAuthor, hyoji);
            }
            else
            {
                SpkNaration.Speak_TitleGamen(hyoji);// とりあえず、タイトル画面表示☆(^~^)
                Logger.Flush(hyoji);
            }

            //Face_Kifuwarabe.Execute("", Option_Application.Kyokumen, syuturyoku); // 空打ちで、ゲームモードに入るぜ☆(^▽^)
            // 空打ちで、ゲームモードに入るぜ☆(^▽^)
            // このプログラムでは(A)コマンド・モード、(B)ゲーム・モード の2種類があるぜ☆
            // 最初は コマンド・モードになっている☆(^~^)
            //
            // ゲームモード
            //      (1)手番
            //              人間、コンピューターの設定が有効になり、
            //              人間の手番のときにしかコマンドが打てなくなるぜ☆
            //      (2)合法手
            //              指し手の合法手チェックを行うぜ☆
            //      (3)自動着手
            //              コンピューターは自分の手番で 指すぜ☆
            //      (4)決着
            //              決着すると ゲームモード を抜けるぜ☆ 連続対局設定の場合は抜けない☆(^▽^)
            //
            // コマンドモード
            //      (1)手番
            //              MAN vs MAN扱い
            //      (2)合法手
            //              チェックしない☆ ひよこをナナメに進めるのも、ワープするのも可能☆
            //      (3)自動着手
            //              しない☆
            //      (4)決着
            //              しない☆ [Enter]キーを空打ちすると、ゲームモードに変わるぜ☆(^▽^)

            bool result1 = Pure.SUCCESSFUL_FALSE;

            for (; ;) //メインループ(無限ループ)
            {
                #region (手順2)ユーザー入力
                //────────────────────────────────────────
                // (手順2)ユーザー入力
                //────────────────────────────────────────
                Util_ConsoleGame.Begin_Mainloop(playing, programSupport, hyoji);
                if (programSupport.commandline != null)
                {
                    // コマンド・バッファーにコマンドラインが残っていたようなら、そのまま使うぜ☆(^▽^)
                }
                else if (
                    GameMode.Game == PureAppli.gameMode // ゲームモードの場合☆
                    &&
                    Console02.IsComputerNoBan()         // コンピューターの番の場合☆
                    )
                {
                    programSupport.ClearCommandline(); // コマンドラインは消しておくぜ☆(^▽^)
                }
                else
                {
                    Util_ConsoleGame.ReadCommandline(programSupport, hyoji);// コンソールからのキー入力を受け取るぜ☆(^▽^)(コンソール・ゲーム用)
                }
                #endregion

                #region ゲームセクション
                if (GameMode.Game == PureAppli.gameMode)
                {
                    #region 手番の開始時
                    //────────────────────────────────────────
                    // 手番の開始時
                    //────────────────────────────────────────

                    // 手番の開始時に 何かやることがあれば ここに書けだぜ☆(^~^)
                    #endregion

                    #region (手順3)人間の手番
                    //────────────────────────────────────────
                    // (手順3)人間の手番
                    //────────────────────────────────────────
                    if (Console02.IsNingenNoBan()) // 人間の手番
                    {
                        // ゲームモードでの人間の手番では、さらにコマンド解析

                        // ここで do コマンド(do b3b2 等)を先行して解析するぜ☆(^▽^)
                        if (programSupport.caret != programSupport.commandline.IndexOf("do ", programSupport.caret))
                        {
                            // do以外のコマンドであれば、コマンドラインを保持したまま、そのまま続行
                        }
                        // 以下、do コマンドの場合☆
                        else if (!programSupport.ParseDoMove(out Move inputMove))
                        {
                            // do コマンドのパースエラー表示(コンソール・ゲーム用)☆(^~^)
                            SpkMove.AppendSetumei(MoveMatigaiRiyu.ParameterSyosikiMatigai, hyoji);
                            hyoji.AppendLine();
                            Logger.Flush(hyoji);
                            programSupport.CommentCommandline();                                // コマンドの誤発動防止
                        }
                        else if (!GenkyokuOpe.CanDoMove(inputMove, out MoveMatigaiRiyu reason)) // 指し手の合否チェック
                        {
                            // イリーガル・ムーブなどの、エラー理由表示☆(^~^)
                            SpkMove.AppendSetumei(reason, hyoji);
                            hyoji.AppendLine();
                            Logger.Flush(hyoji);
                        }
                        else
                        {
                            // do コマンドを実行するぜ☆(^▽^)

                            // 1手指す☆!(^▽^)
                            if (!Util_Control.Try_DoMove_Input(inputMove
#if DEBUG
                                                               , PureSettei.fenSyurui
                                                               , (IDebugMojiretu)hyoji
#endif
                                                               ))
                            {
                                result1 = Pure.FailTrue("Try_DoMove_Input");
                                goto gt_EndLoop1;
                            }
                            // 勝敗判定☆(^▽^)
                            if (!Util_Kettyaku.Try_JudgeKettyaku(inputMove
#if DEBUG
                                                                 , hyoji
#endif
                                                                 ))
                            {
                                result1 = Pure.FailTrue("Try_JudgeKettyaku");
                                goto gt_EndLoop1;
                            }

                            // 局面出力
                            SpkBan_1Column.Setumei_NingenGameYo(PureMemory.kifu_endTeme, hyoji);
                        }
                    }// 人間おわり☆(^▽^)
                    #endregion
                    #region (手順4)コンピューターの手番
                    //────────────────────────────────────────
                    // (手順4)コンピューターの手番
                    //────────────────────────────────────────
                    else if (Console02.IsComputerNoBan())         //コンピューターの番☆
                    {
                        SpkNaration.Speak_ComputerSikochu(hyoji); // 表示(コンピューター思考中☆)
                        Logger.Flush(hyoji);

                        // コンピューターに1手指させるぜ☆
                        Util_Tansaku.PreGo();
                        if (Util_Tansaku.TryFail_Go(hyoji))
                        {
                            result1 = Pure.FailTrue("Try_Go");
                            goto gt_EndLoop1;
                        }
                        // 勝敗判定☆(^▽^)
                        if (!Util_Kettyaku.Try_JudgeKettyaku(PureMemory.tnsk_kohoMove
#if DEBUG
                                                             , hyoji
#endif
                                                             ))
                        {
                            result1 = Pure.FailTrue("Try_JudgeKettyaku");
                            goto gt_EndLoop1;
                        }

                        SpkNaration.Speak_KettyakuJi(hyoji);// 決着していた場合はメッセージ表示☆(^~^)
                        Logger.Flush(hyoji);
                    }// コンピューターの手番おわり☆(^~^)
                    #endregion
                    #region (手順5)決着時
                    //────────────────────────────────────────
                    // (手順5)決着時
                    //────────────────────────────────────────
                    if (Genkyoku.IsKettyaku())// 決着が付いているなら☆
                    {
                        // 対局終了時
                        // 表示(コンソール・ゲーム用)
                        {
                            playing.Result(hyoji, CommandMode.NingenYoConsoleGame);
                            hyoji.AppendLine("終わったぜ☆(^▽^)");
                            Logger.Flush(hyoji);
                        }



                        // 棋譜の初期局面を更新☆
                        {
                            StringBuilder kyFen_temp = new StringBuilder();
                            SpkGenkyokuOpe.AppendFenTo(PureSettei.fenSyurui, kyFen_temp);
                            PureMemory.kifu_syokiKyokumenFen = kyFen_temp.ToString();
                        }


                        // TODO: 成績は保存しないにしても、棋譜は欲しいときもあるぜ☆(^~^)
                        // 棋譜を作ろうぜ☆
                        hyoji.AppendLine("感想戦を行う場合は kansosen と打てだぜ☆(^▽^) そのあと kifu 1 とか打て☆(^▽^)");
                        hyoji.AppendLine("終わるときは hirate な☆(^▽^)");
                        Logger.Flush(hyoji);

                        // 初期局面に戻すぜ☆(^▽^)
                        Util_Taikyoku.Clear();

                        // 棋譜カーソルを0にすれば、初期局面に戻るだろ☆www(^▽^)
                        MoveGenAccessor.BackTemeToFirst_AndClearTeme();


                        if (Util_Machine.IsRenzokuTaikyokuStop())
                        {
                            // 連続対局を止めるぜ☆(^▽^)
                            ConsolegameSettei.renzokuTaikyoku = false;
                            hyoji.AppendLine($"{Util_Machine.RENZOKU_TAIKYOKU_STOP_FILE }> done");
                        }

                        if (!ConsolegameSettei.renzokuTaikyoku)
                        {
                            // ゲームモードを解除するぜ☆(^~^)
                            if (GameMode.Game == PureAppli.gameMode)// 感想戦での発動防止☆
                            {
                                PureAppli.gameMode = GameMode.Karappo;
                            }
                        }
                        else
                        {
                            // 連続対局中☆(^~^)
                        }

                        // コマンドの誤発動防止
                        programSupport.CommentCommandline();
                    }
                    #endregion
                }
                #endregion
                #region (手順6)ゲーム用の指し手以外のコマンドライン実行
                //────────────────────────────────────────
                // (手順6)ゲーム用の指し手以外のコマンドライン実行
                //────────────────────────────────────────
                bool   result2 = Pure.SUCCESSFUL_FALSE;
                string cmdline = programSupport.commandline;
                int    caret   = programSupport.caret;
                programSupport.isQuit          = false;
                programSupport.isKyokumenEcho1 = false; // ゲーム・モードの場合、特に指示がなければ コマンド終了後、局面表示を返すぜ☆

                if (playing.isMultipleLineCommand)
                {
                    // TODO: 複数行コマンド中☆(^~^)
                    //syuturyoku.AppendLine($"TODO: ky set 複数行コマンド中☆(^~^)(2) commandline={ commandline}");
                    //isKyokumenEcho1 = false;
                    if (cmdline == ".")
                    {
                        // 「.」だけの行が来たら終了だぜ☆(^~^)
                        playing.isMultipleLineCommand = false;
                        // 実行☆(^~^)
                        playing.dlgt_multipleLineCommand(playing.multipleLineCommand);
                        playing.multipleLineCommand.Clear();
                        //syuturyoku.AppendLine($"TODO: 複数行コマンドは={ sbMultipleLineCommand}");
                    }
                    else
                    {
                        playing.multipleLineCommand.Add(cmdline);
                    }
                    goto gt_EndCommand;
                }

                if (null == cmdline)
                {
                    // 未設定
                    programSupport.isKyokumenEcho1 = true;
                }
                else if (cmdline == "")
                {
                    programSupport.isKyokumenEcho1 = true;
                    // 空打ちは無視するか、からっぽモードでは、ゲームモードに切り替えるぜ☆(^▽^)
                    if (GameMode.Karappo == PureAppli.gameMode)// 感想戦での発動防止☆
                    {
                        // ゲームモード(対局開始)
                        PureAppli.gameMode = GameMode.Game;
                    }
                }
                // なるべく、アルファベット順☆(^▽^)同じつづりで始まる単語の場合、語句の長い単語を優先にしないと if 文が通らないぜ☆www
                else if (caret == cmdline.IndexOf("@", caret))
                {
                    playing.Atmark(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("#", caret))
                {
                }                                                 // 受け付けるが、何もしないぜ☆(^▽^)www
                else if (caret == cmdline.IndexOf("bitboard", caret))
                {
                    // ビットボードの表示テスト用だぜ☆(^~^)
                    if (playing.TryFail_Bitboard(cmdline, hyoji))
                    {
                        result2 = Pure.FailTrue("TryFail_Bitboard");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("cando", caret))
                {
                    playing.CanDo(PureSettei.fenSyurui, cmdline, GameMode.Game == PureAppli.gameMode ? CommandMode.NingenYoConsoleGame : CommandMode.NigenYoConsoleKaihatu, hyoji);
                    programSupport.isKyokumenEcho1 = true;
                }
                else if (caret == cmdline.IndexOf("chikanhyo", caret))
                {
                    if (playing.TryFail_ChikanHyo(cmdline, hyoji
                                                  ))
                    {
                        result2 = Pure.FailTrue("TryFail_ChikanHyo");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("clear", caret))
                {
                    playing.Clear();
                }
                else if (caret == cmdline.IndexOf("dosub", caret))
                {
                    if (playing.TryFail_DoSub(cmdline, hyoji))
                    {
                        result2 = Pure.FailTrue("TryFail_Do");
                        goto gt_EndCommand;
                    }
                    programSupport.isKyokumenEcho1 = true;
                }
                else if (caret == cmdline.IndexOf("do", caret))
                {
                    if (playing.TryFail_Do(
                            PureSettei.fenSyurui,
                            cmdline,
                            GameMode.Game == PureAppli.gameMode ? CommandMode.NingenYoConsoleGame : CommandMode.NigenYoConsoleKaihatu, hyoji
                            ))
                    {
                        result2 = Pure.FailTrue("TryFail_Do");
                        goto gt_EndCommand;
                    }
                    programSupport.isKyokumenEcho1 = true;
                }
#if DEBUG
                else if (caret == cmdline.IndexOf("dump", caret))
                {
                    if (CommandD.TryFail_Dump(cmdline, hyoji
                                              ))
                    {
                        return(Pure.FailTrue("TryFail_Dump"));
                    }
                }
#endif
                else if (caret == cmdline.IndexOf("fugo", caret))
                {
                    if (playing.TryFail_Fugo(cmdline, hyoji
                                             ))
                    {
                        result2 = Pure.FailTrue("TryFail_Fugo");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("gameover", caret))
                {
                    playing.Gameover(cmdline, hyoji); programSupport.isKyokumenEcho1 = true;
                }
                else if (caret == cmdline.IndexOf("go", caret))
                {
                    var result3 = playing.TryFail_Go(
                        PureSettei.usi,
                        PureSettei.fenSyurui,
                        CommandMode.NigenYoConsoleKaihatu
                        , hyoji
                        );
                    if (result3)
                    {
                        result2 = Pure.FailTrue("Try_Go");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("hirate", caret))
                {
                    playing.Hirate(cmdline, hyoji); programSupport.isKyokumenEcho1 = true;
                }
                else if (caret == cmdline.IndexOf("honyaku", caret))
                {
                    playing.Honyaku(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("hyoka", caret))
                {
                    playing.Hyoka(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("ojama", caret))
                {
                    if (playing.TryFail_Ojama(cmdline, hyoji
                                              ))
                    {
                        result2 = Pure.FailTrue("TryFail_Ojama");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("isready", caret))
                {
                    playing.ReadOk(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("jokyo", caret))
                {
                    playing.Jokyo(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("kansosen", caret))
                {
                    playing.Kansosen(PureSettei.fenSyurui, cmdline, hyoji);
                }                                                                                                                // 駒の場所を表示するぜ☆(^▽^)
                else if (caret == cmdline.IndexOf("kifu", caret))
                {
                    playing.Kifu(PureSettei.fenSyurui, cmdline, hyoji);
                }                                                                                                        // 駒の場所を表示するぜ☆(^▽^)
                else if (caret == cmdline.IndexOf("kikisu", caret))
                {
                    // 利きの数を調べるぜ☆(^▽^)
                    // 旧名「kikikazu」→「kikisu」
                    playing.Kikisu(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("kiki", caret))
                {
                    // 利きを調べるぜ☆(^▽^)
                    var result3 = playing.TryFail_Kiki(cmdline, hyoji);
                    if (result3)
                    {
                        result2 = Pure.FailTrue("TryFail_Kiki");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("koma", caret))
                {
                    Pure.Sc.Push("komaコマンド");
                    playing.Koma_cmd(PureSettei.fenSyurui, cmdline, hyoji);
                    Pure.Sc.Pop();
                }// 駒の場所を表示するぜ☆(^▽^)
                else if (caret == cmdline.IndexOf("ky", caret))
                {
                    // 局面をクリアーしてやり直すときもここを通るので、ここで局面アサートを入れてはいけないぜ☆(^~^)

                    if (playing.TryFail_Ky(cmdline, hyoji))
                    {
                        result2 = Pure.FailTrue("Try_Ky");
                        goto gt_EndCommand;
                    }
                }// 局面を表示するぜ☆(^▽^)
                else if (caret == cmdline.IndexOf("manual", caret))
                {
                    playing.Man(hyoji);
                }                                                                          // "man" と同じ☆(^▽^)
                else if (caret == cmdline.IndexOf("man", caret))
                {
                    playing.Man(hyoji);
                }                                                                       // "manual" と同じ☆(^▽^)
                else if (caret == cmdline.IndexOf("masu", caret))
                {
                    playing.Masu_cmd(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("nanamedan", caret))
                {
                    if (playing.TryFail_Nanamedan(cmdline, hyoji
                                                  ))
                    {
                        result2 = Pure.FailTrue("TryFail_Nanamedan");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("nisinsu", caret))
                {
                    if (playing.TryFail_Nisinsu(cmdline, hyoji
                                                ))
                    {
                        result2 = Pure.FailTrue("TryFail_Nisinsu");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("position", caret))
                {
                    playing.Position(PureSettei.fenSyurui, cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("prego", caret))
                {
                    playing.PreGo(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("quit", caret))
                {
                    programSupport.isQuit = true; programSupport.isKyokumenEcho1 = true;
                }
                else if (caret == cmdline.IndexOf("result", caret))
                {
                    playing.Result(hyoji, CommandMode.NigenYoConsoleKaihatu);
                }
                else if (caret == cmdline.IndexOf("rnd", caret))
                {
                    if (!playing.Try_Rnd(
#if DEBUG
                            (IDebugMojiretu)hyoji
#endif
                            ))
                    {
                        result2 = Pure.FailTrue("commandline");
                        goto gt_EndCommand;
                    }
                    programSupport.isKyokumenEcho1 = true;
                }
                else if (caret == cmdline.IndexOf("move", caret))
                {
                    if (playing.TryFail_Move_cmd(cmdline, hyoji))
                    {
                        result2 = Pure.FailTrue("TryFail_Move_cmd");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("setoption", caret))
                {
                    playing.Setoption(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("set", caret))
                {
                    playing.Set(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("taikyokusya", caret))
                {
                    playing.Taikyokusya_cmd(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("tansaku", caret))
                {
                    playing.Tansaku(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("test", caret))
                {
                    if (playing.TryFail_Test(cmdline, hyoji))
                    {
                        result2 = Pure.FailTrue("TryFail_Test");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("tonarikiki", caret))
                {
                    if (playing.TryFail_Tonarikiki(cmdline, hyoji))
                    {
                        result2 = Pure.FailTrue("TryFail_Tonarikiki");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("tumeshogi", caret))
                {
                    playing.TumeShogi(PureSettei.fenSyurui, cmdline, hyoji);
                }                                                                                                                  // "tu" と同じ☆(^▽^)
                else if (caret == cmdline.IndexOf("tu", caret))
                {
                    playing.TumeShogi(PureSettei.fenSyurui, cmdline, hyoji);
                }                                                                                                           // "tumeshogi" と同じ☆(^▽^)
                else if (caret == cmdline.IndexOf("ugokikata", caret))
                {
                    if (playing.TryFail_Ugokikata(cmdline, hyoji))
                    {
                        result2 = Pure.FailTrue("TryFail_Ugokikata");
                        goto gt_EndCommand;
                    }
                }
                else if (caret == cmdline.IndexOf("undo", caret))
                {
                    playing.Undo(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("updaterule", caret))
                {
                    playing.UpdateRule(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("usinewgame", caret))
                {
                    playing.UsiNewGame(cmdline, hyoji);
                }
                else if (caret == cmdline.IndexOf("usi", caret))
                {
                    //ここは普通、来ない☆(^~^)
                    var profilePath = System.Configuration.ConfigurationManager.AppSettings["Profile"];
                    var toml        = Toml.ReadFile(Path.Combine(profilePath, "Engine.toml"));

                    var     engineName   = toml.Get <TomlTable>("Engine").Get <string>("Name");
                    Version version      = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
                    var     engineAuthor = toml.Get <TomlTable>("Engine").Get <string>("Author");

                    playing.UsiOk(cmdline, $"{engineName} {version.Major}.{version.Minor}.{version.Build}", engineAuthor, hyoji);
                }
                else
                {
                    // 表示(コンソール・ゲーム用)
                    hyoji.Append("「");
                    hyoji.Append(cmdline);
                    hyoji.AppendLine("」☆?(^▽^)");

                    hyoji.AppendLine("そんなコマンドは無いぜ☆(>_<) man で調べろだぜ☆(^▽^)");
                    Logger.Flush(hyoji);
                    programSupport.isKyokumenEcho1 = true;
                }
gt_EndCommand:

                if (result2)
                {
                    result1 = Pure.FailTrue("Try_DoCommandline");
                    goto gt_EndLoop1;
                }

                if (programSupport.isQuit)
                {
                    break;//goto gt_EndLoop1;
                }

                // 次の入力を促す表示をしてるだけだぜ☆(^~^)
                programSupport.ShowPrompt(playing, PureSettei.fenSyurui, hyoji);

                #endregion
            }//無限ループ
gt_EndLoop1:
            ;

            if (result1)
            {
                Logger.Flush(hyoji);
                Console.WriteLine("おわり☆(^▽^)");
                Console.ReadKey();
                //throw new Exception(syuturyoku.ToContents());
            }
            // 開発モードでは、ユーザー入力を待機するぜ☆(^▽^)

            //────────────────────────────────────────
            // (手順7)保存して終了
            //────────────────────────────────────────
            // 保存していないものを保存するぜ☆(^▽^)
            // ファイルに書き出していないログが溜まっていれば、これで全部書き出します。
            Logger.Flush(PureAppli.syuturyoku1);
        }
Beispiel #10
0
        /// <summary>
        /// コンピューターの思考の開始だぜ☆(^▽^)
        /// ここが入り口だぜ☆(^~^)
        ///
        /// 最善手は yomisuji[0] に入っているぜ☆(^▽^)
        /// </summary>
        /// <returns></returns>
        public static bool TryFail_Go(StringBuilder hyoji)
        {
            tmp_bestHyokaSu.Clear();
            if (PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.IsEmpty(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, PureMemory.kifu_teban)))
            {
                // 自分のらいおんがいない局面の場合、投了☆
#if DEBUG
                PureMemory.tnsk_syuryoRiyu = TansakuSyuryoRiyu.JibunRaionInai;
                PureMemory.tnsk_kohoMove   = Move.Toryo;
                tmp_bestHyokaSu.tumeSu     = Conv_Tumesu.Stalemate;
#endif
            }
            else
            {
                //────────────────────────────────────────
                // 反復深化ループ☆(^~^)
                //────────────────────────────────────────
                Move currMove = Move.Toryo;
                tmp_currHyokaSu.Clear();
                for (HanpukuSinka.happaenoFukasa = 1;
                     // まだ思考に時間を使っていい
                     !ComSettei.timeManager.IsTimeOver_IterationDeeping()
                     ; HanpukuSinka.happaenoFukasa++)
                {
                    Debug.Assert(0 <= HanpukuSinka.happaenoFukasa && HanpukuSinka.happaenoFukasa < PureMemory.ssss_moveList.Length, "");

                    if (ComSettei.saidaiFukasa < HanpukuSinka.happaenoFukasa)
                    {
                        // 最大深さを超えた場合
                        Util_Joho.JohoMatome(
                            HanpukuSinka.happaenoFukasa,
                            tmp_bestHyokaSu,
                            hyoji
#if DEBUG
                            , "SaidaiFukasaGoe"
#endif
                            );
                        break;
                    }

                    // ここでは現在の局面に盤面を戻してあると思えだぜ☆(^~^)

                    Debug.Assert(1 <= HanpukuSinka.happaenoFukasa && HanpukuSinka.happaenoFukasa < PureMemory.ssss_moveList.Length, "");
                    ComSettei.SetSikoJikan_KonkaiNoTansaku();//思考時間(ランダム込み)を確定させるぜ☆(^~^)

                    PureMemory.SetTnskHyoji(hyoji);
                    //カウントダウン式の数字☆(^▽^) 反復深化探索の1週目は 1、2週目は 2 だぜ☆(^▽^)
                    PureMemory.SetTnskFukasa(HanpukuSinka.happaenoFukasa);
                    Tansaku_(
                        out currMove,
                        out tmp_currHyokaSu// 相手番の指し手の評価値が入ってくるぜ☆(^~^)
                        );

                    // TODO: 1手も読めていなければ、さっさと投了したいぜ☆(^~^)

                    if (tmp_currHyokaSu.isHaki)
                    {
                        // 時間切れ等の中途半端探索のとき☆
                        // この計算結果は、無視するぜ☆(^~^)

                        // ここに来るときは探索終了だぜ☆(^~^)
                        break;// 読みを終了しようなんだぜ☆
                    }
                    else
                    {
                        // 更新☆(^▽^)

                        PureMemory.tnsk_itibanFukaiNekkoKaranoFukasa_JohoNoTameni = HanpukuSinka.happaenoFukasa;
                        PureMemory.tnsk_kohoMove = currMove;
                        tmp_bestHyokaSu.ToSet(tmp_currHyokaSu);

                        if (Conv_Tumesu.CatchRaion == tmp_bestHyokaSu.tumeSu)
                        {
                            // 「0手詰められ」が返ってきているなら、負けました、をいう場面だぜ☆
#if DEBUG
                            PureMemory.tnsk_syuryoRiyu = TansakuSyuryoRiyu.Minus2TeTumerare;
#endif
                            break;// 読みを終了しようなんだぜ☆
                        }
                    }
                }//ループ

                // ストップウォッチ
                ComSettei.timeManager.stopwatch_Tansaku.Stop();
            }

            //────────────────────────────────────────
            // 詰め、詰められ
            //────────────────────────────────────────
            {
                Util_Taikyoku.Update(
                    tmp_bestHyokaSu,
                    PureMemory.kifu_teban
                    );
            }

            //────────────────────────────────────────
            // 指し手は決まった☆(^~^)
            // 指して、局面を進めておくぜ☆(^~^)
            //────────────────────────────────────────
            // 何これ
            if (DoMoveOpe.TryFailDoMoveAll(
                    PureMemory.tnsk_kohoMove,
                    MoveType.N00_Karappo
#if DEBUG
                    , PureSettei.fenSyurui
                    , (IDebugMojiretu)hyoji
                    , true//アサート抑制
                    , "TryFail_Go(1)"
#endif
                    ))
            {
                return(Pure.FailTrue("GenkyokuOpe.Try_DoMove(1)"));
            }
            // 手番を進めるぜ☆(^~^)
            MoveGenAccessor.AddKifu(PureMemory.tnsk_kohoMove, MoveType.N00_Karappo, PureMemory.dmv_ks_c);
#if DEBUG
            Util_Tansaku.Snapshot("Go(1)確定指し", PureMemory.tnsk_kohoMove);
#endif


            // 指し手が決まったときにも、強制情報表示
            {
                if (0 == PureMemory.tnsk_itibanFukaiNekkoKaranoFukasa_JohoNoTameni)
                {
#if DEBUG
                    hyoji.AppendLine($@"0手投了してないかだぜ☆?(^~^)
tansakuSyuryoRiyu=[{PureMemory.tnsk_syuryoRiyu}]
Option_Application.Optionlist.SaidaiFukasa=[{ComSettei.saidaiFukasa}]
Option_Application.Optionlist.SikoJikan_KonkaiNoTansaku=[{ComSettei.sikoJikan_KonkaiNoTansaku}]
Option_Application.Optionlist.SikoJikan=[{ComSettei.sikoJikan}]
Option_Application.Optionlist.SikoJikanRandom=[{ComSettei.sikoJikanRandom}]
");
                    return(Pure.FailTrue("0手投了"));
#endif
                }
            }

#if DEBUG
            hyoji.AppendLine(string.Format("bestMove: [{0}] ss={1}",
                                           PureMemory.tnsk_kaisiTeme,
                                           SpkMove.ToString_Fen(PureSettei.fenSyurui, PureMemory.tnsk_kohoMove)
                                           ));
#endif
            return(Pure.SUCCESSFUL_FALSE);
        }
Beispiel #11
0
        /// <summary>
        /// 探索だぜ☆(^▽^)
        /// </summary>
        /// <param name="ky"></param>
        /// <param name="alpha"></param>
        /// <param name="fukasa">カウントダウン式の数字☆(^▽^) 反復深化探索の1週目の初期値は 1、2週目の初期値は 2 だぜ☆(^▽^)
        /// これがどんどんカウントダウンしていくぜ☆(^▽^) 0 で呼び出されたときは葉にしてすぐ処理を終われよ☆(^▽^)www</param>
        /// <param name="out_yomisujiToBack"></param>
        /// <param name="out_bestHyokatiAb1">手番から見た指し手の評価値だぜ☆(^~^)</param>
        /// <param name="out_edaBest_Komawari_JohoNoTame">内訳の目視確認用に使うだけの項目。</param>
        /// <param name="out_edaBest__Okimari_JohoNoTame">内訳の目視確認用に使うだけの項目。</param>
        /// <param name="out_edaBest_____Riyu_JohoNoTame">内訳の目視確認用に使うだけの項目。</param>
        /// <param name="dlgt_CreateJoho"></param>
        /// <returns></returns>
        private static void Tansaku_(
            out Move out_bestMove,
            out Hyokati out_bestHyokasu // 手番側の指し手の評価値だぜ☆(^~^)
            )
        {
            Debug.Assert(0 <= PureMemory.tnsk_fukasa && PureMemory.tnsk_fukasa < PureMemory.ssss_moveList.Length, "");

            out_bestMove    = Move.Toryo;
            out_bestHyokasu = null;

            //────────────────────────────────────────
            // 時間切れ判定
            //────────────────────────────────────────
            if (ComSettei.timeManager.IsTimeOver_TansakuChu())
            {
                out_bestMove    = Move.Toryo;
                out_bestHyokasu = new Hyokati(
                    Conv_Hyokati.Hyokati_Rei,
                    Conv_Tumesu.Stalemate,
                    true // 今回の探索の結果は破棄するぜ☆(^~^)
#if DEBUG
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , HyokaRiyu.JikanGire
                    , ""
#endif
                    );
#if DEBUG
                Util_Tansaku.Snapshot("時間切れだぜ☆(^~^)", out_bestMove);
#endif
                return;
            }

            //────────────────────────────────────────
            // 葉
            //────────────────────────────────────────
            #region 葉
            if (
                // 深さ0 で呼び出されたときは、葉にしろということだぜ☆(^▽^)www
                PureMemory.tnsk_fukasa == 0
                )
            {
                // 深さ(根っこからの深さ)は 1 以上で始まるから、ループの1週目は、スルーされるはずだぜ☆(^▽^)
                // 1手指して 枝を伸ばしたとき、相手の手番の局面になっているな☆(^▽^)そのとき ここを通る可能性があるぜ☆

                //
                // 末端局面で評価値を作らないぜ☆(^~^)!
                // 指し手を、指したときに作るんだぜ☆(^~^)!
                //

                PureMemory.tnsk_happaTeme = PureMemory.kifu_endTeme;

                // 「手目」カーソルは DoMove で1つ進んでいるはずなので、戻すんだぜ☆(^~^)
                out_bestMove    = PureMemory.kifu_moveArray[PureMemory.kifu_endTeme - 1];
                out_bestHyokasu = new Hyokati(PureMemory.gky_hyokati);


                // 葉で情報表示
                Util_Joho.JohoMatome(
                    PureMemory.tnsk_fukasa + 1,
                    out_bestHyokasu,
                    PureMemory.tnsk_hyoji
#if DEBUG
                    , out_bestHyokasu.dbg_riyu.ToString()
#endif
                    );
#if DEBUG
                Util_Tansaku.Snapshot("葉だぜ☆(^~^)", out_bestMove);
#endif
                return;//枝を戻る(正常終了)
            }
            #endregion

            //────────────────────────────────────────
            // 指し手生成
            //────────────────────────────────────────
            // グローバル変数 Util_MoveSeisei.Sslist に指し手がセットされるぜ☆(^▽^)
            MoveGenAccessor.DoMovePickerBegin(MoveType.N21_All);
            MovePicker01.MovePickerN01(MoveType.N21_All, true);

            #region ステイルメイト
            //────────────────────────────────────────
            // ステイル・メイト
            //────────────────────────────────────────
            if (PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].listCount < 1)
            {
                // 詰んでるぜ☆(^~^)
                out_bestMove    = Move.Toryo;
                out_bestHyokasu = new Hyokati(
                    Conv_Hyokati.Hyokati_Rei,
                    Conv_Tumesu.Stalemate,
                    false
#if DEBUG
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , HyokaRiyu.Stalemate
                    , ""
#endif
                    );

                // ステイルメイトで情報表示
                Util_Joho.JohoMatome(
                    PureMemory.tnsk_fukasa + 1,// 深さは 0 になっているので、Tansaku していない状態(=+1 して)に戻すぜ☆
                    out_bestHyokasu,
                    PureMemory.tnsk_hyoji
#if DEBUG
                    , "Stalemate"
#endif
                    );
#if DEBUG
                Util_Tansaku.Snapshot("ステイルメイトだぜ☆(^~^)", out_bestMove);
                MoveSeiseiAccessor.DumpMoveSeisei(PureMemory.tnsk_hyoji);
#endif
                return;//枝を戻る(正常終了)
            }
            #endregion


            for (int iSs = 0; iSs < PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].listCount; iSs++)
            {
                // 枝☆ 適当にここらへんでカウントアップするかだぜ☆(^~^)
                PureMemory.tnsk_tyakusyuEdas++;



                //────────────────────────────────────────
                // 指す
                //────────────────────────────────────────

//#if DEBUG
//                Util_Tansaku.Snapshot("ドゥ前", hyoji);
//#endif

                Move     ss_jibun     = PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].moveList[iSs];
                MoveType ssType_jibun = PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].moveTypeList[iSs];

                if (DoMoveOpe.TryFailDoMoveAll(
                        ss_jibun,
                        ssType_jibun
#if DEBUG
                        , PureSettei.fenSyurui
                        , (IDebugMojiretu)PureMemory.tnsk_hyoji
                        , false
                        , "TryFail_Tansaku_(1)"
#endif
                        ))
                {
                    // 探索時にエラーが起こった場合は強制終了☆(^~^)
                    throw new Exception(PureMemory.tnsk_hyoji.ToString());
                }
                // 手番を進めるぜ☆(^~^)
                MoveGenAccessor.AddKifu(
                    ss_jibun,
                    ssType_jibun,
                    PureMemory.dmv_ks_c);
#if DEBUG
                Util_Tansaku.Snapshot("ドゥ後・探索前", out_bestMove);
#endif

                Move ss_aite;
                //MoveType eda_moveType;
                // goto文で飛ぶと未割当になるので、ヌルでも入れておくぜ☆(^~^)
                Hyokati hyokasu_aiteToJibun = null;

                // この指し手が、駒を取った手かどうか☆

                PureMemory.SetTnskHyoji(PureMemory.tnsk_hyoji);
                // 探索者がプラスでスタートして、
                // 探索者の反対側はマイナスになり、
                // 探索者の反対側の反対側はプラスに戻るぜ☆(^▽^)
                PureMemory.DecreaseTnskFukasa();
                Tansaku_(
                    out ss_aite,
                    out hyokasu_aiteToJibun
                    // 相手番の指し手の評価値が入ってくるぜ☆(^~^)
                    );
                PureMemory.IncreaseTnskFukasa();
//#if DEBUG
//                Util_Tansaku.Snapshot("探索後・アンドゥ前", hyoji);
//#endif

                //────────────────────────────────────────
                // 詰みを発見していれば、打ち切りフラグを立てるぜ☆(*^~^*)
                //────────────────────────────────────────
                bool undoAndBreak = false;
                if (hyokasu_aiteToJibun.tumeSu == Conv_Tumesu.CatchRaion)
                {
                    out_bestMove    = ss_jibun;
                    out_bestHyokasu = new Hyokati(
                        Conv_Hyokati.Hyokati_Rei,
                        Conv_Tumesu.CatchRaion,// この枝にこれるようなら、勝ち宣言だぜ☆(^▽^)
                        false
                #if DEBUG
                        , Conv_Hyokati.Hyokati_Rei
                        , Conv_Hyokati.Hyokati_Rei
                        , Conv_Hyokati.Hyokati_Rei
                        , HyokaRiyu.TansakuRaionCatch
                        , ""
                #endif
                        );
                    // 打ち切りで情報表示
                    Util_Joho.JohoMatome(
                        PureMemory.tnsk_fukasa,
                        out_bestHyokasu,
                        PureMemory.tnsk_hyoji
#if DEBUG
                        , "TansakuRaionCatch"
#endif
                        );

                    // 詰みではなく、らいおんきゃっち または トライかを 調べるぜ☆(^~^)
                    // この手番は、
                    // この指し手を選べば、勝てるという理屈だが……☆
                    undoAndBreak = true;
#if DEBUG
                    Util_Tansaku.Snapshot("らいおんキャッチだぜ☆(^~^)", out_bestMove);
#endif
                }

                // 探索で先の枝から戻ってきたときは、評価の符号を反転し、詰め手数のカウントもアップするぜ☆(^~^)
                hyokasu_aiteToJibun.CountUpTume();
                hyokasu_aiteToJibun.ToHanten();



                if (UndoMoveOpe.TryFailUndoMove(
#if DEBUG
                        PureSettei.fenSyurui
                        , (IDebugMojiretu)PureMemory.tnsk_hyoji
#endif
                        ))
                {
                    // 探索時にエラーが起こった場合は強制終了☆(^~^)
                    throw new Exception(PureMemory.tnsk_hyoji.ToString());
                }

#if DEBUG
                Util_Tansaku.Snapshot("アンドゥ後", out_bestMove);
#endif

                //────────────────────────────────────────
                // これ以上 弟要素を探索するのを止め、枝を戻るかどうか☆(^~^)
                //────────────────────────────────────────
                #region 打ち切り各種
                if (undoAndBreak)
                {
                    // (1)千日手の権利を相手に渡すために低点数付け<それ以降の手は読まない>
                    // (2)らいおん を捕獲した
                    // (3)トライ した
#if DEBUG
                    Util_Tansaku.Snapshot("アンドゥ後ブレイクだぜ☆(^~^)", out_bestMove);
#endif
                    break;//枝を戻る(正常終了)
                }
                #endregion

                //────────────────────────────────────────
                // アップデート・枝ベスト
                //────────────────────────────────────────
                #region アップデート・枝ベスト

                // 点数が付かないことがあって、その場合 ベスト指し手 を1度も選ばない
                // 「<=」にすると同点だったら、指し手のオーダリングの低いのを選ぶが☆(^~^)
                if (null == out_bestHyokasu)
                {
                    out_bestMove    = ss_jibun;
                    out_bestHyokasu = hyokasu_aiteToJibun;// new HyokaSu(eda_hyokasu);//ここで新規作成
#if DEBUG
                    Util_Tansaku.Snapshot("アップデート枝ベスト1回目だぜ☆(^~^)", out_bestMove);
#endif
                }
                else if (out_bestHyokasu.hyokaTen < hyokasu_aiteToJibun.hyokaTen)
                {
                    out_bestMove = ss_jibun;
                    out_bestHyokasu.ToSet(hyokasu_aiteToJibun);

                    // 兄弟の中で一番の読み筋だぜ☆(^▽^)
                    // ↓
                    // TODO: ここで情報を表示したいが……☆(^~^)
#if DEBUG
                    Util_Tansaku.Snapshot("アップデート枝ベストだぜ☆(^~^)", out_bestMove);
#endif
                }
                #endregion
            }//指し手ループ
             //;

            // このノードでの最大評価を返すんだぜ☆(^▽^)
            // ここでアルファを返してしまうと、アルファが1回も更新されなかったときに、このノードの最大評価ではないものを返してしまうので不具合になるぜ☆(^~^)

            if (null == out_bestHyokasu)
            {
                out_bestMove    = Move.Toryo;
                out_bestHyokasu = new Hyokati(
                    Conv_Hyokati.Hyokati_Rei,
                    Conv_Tumesu.None,
                    false
#if DEBUG
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , HyokaRiyu.Fumei
                    , "ループ抜け"
#endif
                    );

                // ステイルメイトで情報表示
                Util_Joho.JohoMatome(
                    PureMemory.tnsk_fukasa,
                    out_bestHyokasu,
                    PureMemory.tnsk_hyoji
#if DEBUG
                    , "LoopOut"
#endif
                    );

#if DEBUG
                Util_Tansaku.Snapshot("評価の決まらない、ループ抜けだぜ☆(^~^)", out_bestMove);
#endif
                return;//枝を戻る(正常終了)
            }
        }
Beispiel #12
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);
        }