Exemplo n.º 1
0
        public static bool MatchTaikyokusya(string line, ref int caret, out Taikyokusya out_tai
#if DEBUG
                                            , IDebugMojiretu hyoji
#endif
                                            )
        {
            Match m = GetTaikyokusyaPattern(PureSettei.fenSyurui).Match(line, caret);

            if (m.Success)
            {
                string tai_moji = m.Groups[1].Value;

                if (!Med_Parser.Try_MojiToTaikyokusya(PureSettei.fenSyurui, tai_moji, out out_tai))
                {
                    // パースエラーの場合(エラーにはしない)
                    return(false);
                }

                // キャレットを進めます
                Util_String.SkipMatch(line, ref caret, m);
                return(true);
            }
            else
            {
                out_tai = Taikyokusya.Yososu;
                return(false);
            }
        }
Exemplo n.º 2
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.º 3
0
        public static bool MatchKomasyurui(string line, ref int caret, out Komasyurui out_ks)
        {
            Match m = GetKomaPattern(PureSettei.fenSyurui).Match(line, caret);

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

                // 駒種類(FIXME: 後手の表記だと誤動作になるか?)
                string ks_moji = m.Groups[1].Value;
                out_ks = Med_Parser.MojiToKomasyurui(PureSettei.fenSyurui, ks_moji);
                return(true);
            }
            else
            {
                out_ks = Komasyurui.Yososu;
                return(false);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// ここからコンソール・アプリケーションが始まるぜ☆(^▽^)
        ///
        /// PCのコンソール画面のプログラムなんだぜ☆(^▽^)
        /// Unityでは中身は要らないぜ☆(^~^)
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            try
            {
                var engineConf = new EngineConf();
                EntitiesLayer.Implement(engineConf);

                var playing = new Playing(engineConf);

                /*
                 #if DEBUG
                 * // いろいろテスト☆
                 * System.Console.WriteLine("# デバッグ");
                 * System.Console.WriteLine($"# (1L<<31)=[{(1L << 31)}]");
                 * System.Console.WriteLine($"# (1L<<32)=[{(1L << 32)}]");
                 * System.Console.WriteLine($"# (1L<<33)=[{(1L << 33)}]");
                 * System.Console.WriteLine($"# (1L<<62)=[{(1L << 62)}]");
                 * System.Console.WriteLine($"# (1L<<63)=[{(1L << 63)}]");
                 * System.Console.WriteLine($"# (1L<<64)=[{(1L << 64)}]");
                 * System.Console.WriteLine($"# (1L<<65)=[{(1L << 65)}]");
                 * System.Console.WriteLine($"# (long.MinValue << 1)=[{(long.MinValue << 1)}]");
                 * System.Console.WriteLine($"# (~0UL)=[{(~0UL)}]");
                 * System.Console.WriteLine($"# (~0UL << 1)=[{(~0UL << 1)}]");
                 #endif
                 */


                //────────────────────────────────────────
                // (手順1)アプリケーション開始前に設定しろだぜ☆(^▽^)!
                //────────────────────────────────────────
                {
                    // アプリケーション開始後は Face_Kifuwarabe.Execute("set 名前 値") を使って設定してくれだぜ☆(^▽^)
                    // ↓コメントアウトしているところは、デフォルト値を使っている☆(^~^)

                    //Option_Application.Optionlist.AspirationFukasa = 7;
                    //Option_Application.Optionlist.AspirationWindow = Hyokati.Hyokati_SeiNoSu_Hiyoko;
                    //Option_Application.Optionlist.BetaCutPer = 100;
                    //Option_Application.Optionlist.HanpukuSinkaTansakuTukau = true;
                    //Option_Application.Optionlist.JohoJikan = 3000;

                    //──────────
                    // 定跡
                    //──────────
                    Option_Application.Optionlist.JosekiPer = 0;     // 定跡を利用する確率。0~100。
                    Option_Application.Optionlist.JosekiRec = false; // 定跡は記録しない
                                                                     //Option_Application.Optionlist.JosekiRec = true;// 定跡を記録する☆

                    //Option_Application.Optionlist.Learn = false;
                    //Option_Application.Optionlist.NikomaHyokaKeisu = 1.0d;
                    //Option_Application.Optionlist.NikomaGakusyuKeisu = 0.001d;// HYOKA_SCALEが 1.0d のとき、GAKUSYU_SCALE 0.00001d なら、小数点部を広く使って じっくりしている☆(^~^)
                    //Option_Application.Optionlist.P1Com = false;
                    Option_Application.Optionlist.P2Com = true;           //対局者2はコンピューター☆
                                                                          //Option_Application.Optionlist.PNChar = new SasiteCharacter[] { SasiteCharacter.HyokatiYusen, SasiteCharacter.HyokatiYusen };
                                                                          //Option_Application.Optionlist.PNName = new string[] { "対局者1", "対局者2" };
                                                                          //Option_Application.Optionlist.RandomCharacter = false;
                                                                          //Option_Application.Optionlist.RandomNikoma = false;
                                                                          //Option_Application.Optionlist.RandomStart = false;
                                                                          //Option_Application.Optionlist.RenzokuTaikyoku = false;
                    Option_Application.Optionlist.SagareruHiyoko = false; // さがれるひよこモード☆ アプリケーション開始後は Face_Kifuwarabe.Execute("set SagareruHiyoko true") コマンドを使って設定すること☆ #仲ルール
                    Option_Application.Optionlist.SaidaiFukasa   = 13;    // コンピューターの読みの最大深さ

                    //──────────
                    // 成績
                    //──────────
                    Option_Application.Optionlist.SeisekiRec = false; // 成績は記録しない
                                                                      //Option_Application.Optionlist.SeisekiRec = true;// 成績を記録する☆

                    //Option_Application.Optionlist.SennititeKaihi = false;

                    //──────────
                    // 思考時間
                    //──────────
                    Option_Application.Optionlist.SikoJikan       = 5000; // 500; // 最低でも用意されているコンピューターが思考する時間(ミリ秒)
                    Option_Application.Optionlist.SikoJikanRandom = 5000; // 1501;// 追加で増えるランダム時間の最大(この値未満)。 期待値を考えて設定しろだぜ☆(^~^)例: ( 500 + 1500 ) / 2 = 1000
                                                                          //Option_Application.Optionlist.TranspositionTableTukau = true;
                                                                          //Option_Application.Optionlist.UseTimeOver = true;
                }

                StringBuilder syuturyoku = Util_Machine.Syuturyoku;

                // (手順3)アプリケーション開始時設定 を終えた後に これを呼び出すこと☆(^~^)!
                Option_Application.TimeManager.Stopwatch_Savefile.Start();// 定跡ファイルの保存間隔の計測
                Option_Application.TimeManager.Stopwatch_RenzokuRandomRule.Start();

                // 平手初期局面を作るぜ☆(*^~^*)
                Option_Application.Kyokumen.DoHirate(Option_Application.Optionlist.USI, syuturyoku);

                Util_Machine.Assert_Sabun_Kiki("アプリケーション始30", Option_Application.Kyokumen.Sindan);

                /*
                 * Util_Application.LoadJoseki(syuturyoku);// 定跡ファイルの読込み
                 * Util_Application.LoadSeiseki(syuturyoku);// 成績ファイルの読込み
                 * Util_Application.LoadNikoma(syuturyoku);// 二駒関係ファイルの読込み
                 */

                // ゲームモード設定☆
                Util_Application.GameMode = GameMode.Karappo;

                // まず最初に「USI\n」が届くかどうかを判定☆(^~^)
                Util_ConsoleGame.ReadCommandline(syuturyoku);
                //string firstInput = Util_Machine.ReadLine();
                if (Util_Commandline.Commandline == "usi")
                {
                    Option_Application.Optionlist.USI = true;

                    var     engineName   = engineConf.GetEngine("Name");
                    Version version      = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
                    var     engineAuthor = engineConf.GetEngine("Author");

                    playing.UsiOk($"{engineName} {version.Major}.{version.Minor}.{version.Build}", engineAuthor, syuturyoku);
                }
                else
                {
                    Util_ConsoleGame.WriteMessage_TitleGamen(syuturyoku);// とりあえず、タイトル画面表示☆(^~^)
                }

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

                for (; ;) //メインループ(無限ループ)
                {
                    //────────────────────────────────────────
                    // (手順2)ユーザー入力
                    //────────────────────────────────────────
                    Util_Commandline.InitCommandline();             // コマンド・ライン初期化☆
                    Util_Commandline.ReadCommandBuffer(syuturyoku); // コマンド・バッファー読取り☆

                    if (Util_Commandline.Commandline != null)
                    {
                        // コマンド・バッファーにコマンドラインが残っていたようなら、そのまま使うぜ☆(^▽^)
                    }
                    else if (
                        GameMode.Game == Util_Application.GameMode // ゲームモードの場合☆
                        &&
                        Util_Application.IsComputerNoBan(ky)       // コンピューターの番の場合☆
                        )
                    {
                        Util_Commandline.ClearCommandline(); // コマンドラインは消しておくぜ☆(^▽^)
                    }
                    else
                    {
                        Util_ConsoleGame.ReadCommandline(syuturyoku);// コンソールからのキー入力を受け取るぜ☆(^▽^)(コンソール・ゲーム用)
                    }

                    if (GameMode.Game == Util_Application.GameMode)
                    {
                        // 指す前の局面☆(定跡 登録用)
                        Util_ConsoleGame.Init_JosekiToroku(ky);

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

                            // ここで do コマンド(do b3b2 等)を先行して解析するぜ☆(^▽^)
                            if (Util_Commandline.Caret != Util_Commandline.Commandline.IndexOf("do ", Util_Commandline.Caret))
                            {
                                // do以外のコマンドであれば、コマンドラインを保持したまま、そのまま続行
                            }
                            // 以下、do コマンドの場合☆
                            else if (!Util_Application.ParseDoMove(ky, out Move inputSasite))
                            {
                                // do コマンドのパースエラー表示(コンソール・ゲーム用)☆(^~^)
                                syuturyoku.AppendLine(ConvMove.Setumei(MoveMatigaiRiyu.ParameterSyosikiMatigai));
                                var msg = syuturyoku.ToString();
                                syuturyoku.Clear();
                                Logger.Flush(msg);
                                Util_Commandline.CommentCommandline();                       // コマンドの誤発動防止
                            }
                            else if (!ky.CanDoMove(inputSasite, out MoveMatigaiRiyu reason)) // 指し手の合否チェック
                            {
                                // イリーガル・ムーブなどの、エラー理由表示☆(^~^)
                                syuturyoku.AppendLine(ConvMove.Setumei(reason));
                                var msg = syuturyoku.ToString();
                                syuturyoku.Clear();
                                Logger.Flush(msg);
                            }
                            else
                            {
                                // do コマンドを実行するぜ☆(^▽^)
                                // 1手指す☆!(^▽^)
                                Nanteme konoTeme = new Nanteme();// 使いまわさないだろう☆(^~^)ここで作ってしまおう☆
                                ky.DoMove(Option_Application.Optionlist.USI, inputSasite, MoveType.N00_Karappo, ref konoTeme, ky.CurrentOptionalPhase, syuturyoku);


                                Util_Application.JudgeKettyaku(inputSasite, ky);// 勝敗判定☆(^▽^)

                                // 局面出力
                                Util_Information.Setumei_NingenGameYo(ky, syuturyoku);
                                Util_ConsoleGame.Update1_JosekiToroku(inputSasite, ky, syuturyoku);// やるなら、定跡更新☆(^▽^)
                            }
                        }// 人間おわり☆(^▽^)

                        //────────────────────────────────────────
                        // (手順4)コンピューターの手番
                        //────────────────────────────────────────
                        else if (Util_Application.IsComputerNoBan(ky))                                                                                                        //コンピューターの番☆
                        {
                            Util_ConsoleGame.AppendMessage_ComputerSikochu(ky, syuturyoku);                                                                                   // 表示(コンピューター思考中☆)

                            Move bestSasite = Util_Application.Go(playing, ky, out HyokatiUtiwake best_hyokatiUTiwake, Face_YomisujiJoho.Dlgt_WriteYomisujiJoho, syuturyoku); // コンピューターに1手指させるぜ☆
                            Util_Application.JudgeKettyaku(bestSasite, ky);                                                                                                   // 勝敗判定☆(^▽^)

                            Util_ConsoleGame.Update2_JosekiToroku(bestSasite, best_hyokatiUTiwake.EdaBest, ky, syuturyoku);                                                   // やるなら、定跡更新☆(^▽^)
                            Util_ConsoleGame.ShowMessage_KettyakuJi(ky, syuturyoku);                                                                                          // 決着していた場合はメッセージ表示☆(^~^)
                        }// コンピューターの手番おわり☆(^~^)

                        //────────────────────────────────────────
                        // (手順5)決着時
                        //────────────────────────────────────────
                        if (Util_Application.IsKettyaku(ky))                                    // 決着が付いているなら☆
                        {
                            Util_Application.DoTejun5_SyuryoTaikyoku1(playing, ky, syuturyoku); // 対局終了時
                        }
                    }

                    //────────────────────────────────────────
                    // (手順6)ゲーム用の指し手以外のコマンドライン実行
                    //────────────────────────────────────────
                    string commandline = Util_Commandline.Commandline;
                    int    caret       = Util_Commandline.Caret;
                    Util_Commandline.IsQuit         = false;
                    Util_Commandline.IsKyokumenEcho = true; // ゲーム・モードの場合、特に指示がなければ コマンド終了後、局面表示を返すぜ☆
                    if (null == commandline)
                    {
                        // 未設定
                    }
                    else if (commandline == "")
                    {
                        // 空打ちは無視するか、からっぽモードでは、ゲームモードに切り替えるぜ☆(^▽^)
                        if (GameMode.Karappo == Util_Application.GameMode)// 感想戦での発動防止☆
                        {
                            // ゲームモード(対局開始)
                            Util_Application.GameMode = GameMode.Game;
                        }
                    }
                    // なるべく、アルファベット順☆(^▽^)同じつづりで始まる単語の場合、語句の長い単語を優先にしないと if 文が通らないぜ☆www
                    else if (caret == commandline.IndexOf("@", caret))
                    {
                        playing.Atmark(commandline);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("#", caret))
                    {
                        // 受け付けるが、何もしないぜ☆(^▽^)www
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("bitboard", caret))
                    {
                        // テスト用だぜ☆(^~^)
                        if (commandline == "bitboard")
                        {
                            // ビットボード表示☆

                            // 筋
                            {
                                for (int iSuji = 0; iSuji < Option_Application.Optionlist.BanYokoHaba; iSuji++)
                                {
                                    Util_Information.Setumei_1Bitboard($"筋{iSuji}", ky.BB_SujiArray[iSuji], syuturyoku);
                                }
                                syuturyoku.AppendLine();
                            }
                            // 段
                            {
                                for (int iDan = 0; iDan < Option_Application.Optionlist.BanTateHaba; iDan++)
                                {
                                    Util_Information.Setumei_1Bitboard($"段{iDan}", ky.BB_DanArray[iDan], syuturyoku);
                                }
                                syuturyoku.AppendLine();
                            }
                            // トライ
                            {
                                Util_Information.Setumei_Bitboards(new string[] { "対局者1", "対局者2(トライ)" },
                                                                   new Bitboard[] { ky.BB_Try[(int)Phase.Black], ky.BB_Try[(int)Phase.White] }, syuturyoku);
                                syuturyoku.AppendLine();
                            }

                            Util_Information.HyojiKomanoIbasho(ky.Shogiban, syuturyoku);                       // 駒の居場所☆
                            Util_Information.HyojiKomanoKikiSu(ky.Shogiban, syuturyoku);                       // 駒の重ね利き数☆
                            Util_Information.HyojiKomanoKiki(ky.Shogiban, syuturyoku);                         // 駒の利き☆
                            Util_Information.HyojiKomanoUgoki(ky.Shogiban, ky.Sindan.MASU_YOSOSU, syuturyoku); // 駒の動き☆
                            return;
                        }

                        // うしろに続く文字は☆(^▽^)
                        int caret2 = 0;
                        Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret2, "bitboard ");

                        if (caret2 == commandline.IndexOf("kiki", caret2))
                        {
                            // 重ね利きビットボード表示☆

                            // 駒別
                            {
                                // 再計算
                                Shogiban saikeisan = new Shogiban(ky.Sindan);
                                saikeisan.Tukurinaosi_1_Clear_KikiKomabetu();
                                saikeisan.Tukurinaosi_2_Input_KikiKomabetu(ky.Sindan);
                                saikeisan.TukurinaosiBBKikiZenbu();

                                syuturyoku.AppendLine("利き:(再計算)全部、駒別");
                                Util_Information.HyojiKomanoKiki(saikeisan, syuturyoku);

                                // 現行
                                syuturyoku.AppendLine("利き:(現行)全部、駒別");
                                Util_Information.HyojiKomanoKiki(ky.Shogiban, syuturyoku);
                            }

                            // 全部
                            {
                                // 再計算
                                Shogiban saikeisan = new Shogiban(ky.Sindan);
                                saikeisan.TukurinaosiKikisuZenbu(ky.Shogiban, ky.Sindan);
                                saikeisan.TukurinaosiKikisuKomabetu(ky.Shogiban, ky.Sindan);

                                syuturyoku.AppendLine("利き数:(再計算)全部、駒別");
                                Util_Information.HyojiKomanoKikiSu(saikeisan, syuturyoku);

                                // 現行
                                syuturyoku.AppendLine("利き数:全部(現行)全部、駒別");
                                Util_Information.HyojiKomanoKikiSu(ky.Shogiban, syuturyoku);
                            }

                            return;
                        }
                        else if (caret2 == commandline.IndexOf("remake", caret2))
                        {
                            // 駒の動き方を作り直し
                            ky.Shogiban.Tukurinaosi_1_Clear_KomanoUgokikata(ky.Sindan.MASU_YOSOSU);
                            ky.Shogiban.Tukurinaosi_2_Input_KomanoUgokikata(ky.Sindan);
                        }

                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("cando", caret))
                    {
                        // GameMode.Game == Util_Application.GameMode ? CommandMode.NingenYoConsoleGame : CommandMode.NigenYoConsoleKaihatu,
                        // うしろに続く文字は☆(^▽^)
                        int caret2 = 0;
                        Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret2, "cando ");

                        if (!Med_Parser.TryFenMove(Option_Application.Optionlist.USI, commandline, ref caret2, ky.Sindan, out Move ss))
                        {
                            throw new Exception($"パースエラー [{commandline}]");
                        }

                        if (ky.CanDoMove(ss, out MoveMatigaiRiyu riyu))
                        {
                            syuturyoku.AppendLine("cando, true");
                        }
                        else
                        {
                            syuturyoku.Append("cando, false, ");
                            syuturyoku.AppendLine(riyu.ToString());
                        }
                    }
                    else if (caret == commandline.IndexOf("clear", caret))
                    {
                        Util_Machine.Clear();
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("do", caret))
                    {
                        playing.Do(
                            Option_Application.Optionlist.USI,
                            commandline,
                            ky,
                            GameMode.Game == Util_Application.GameMode ? CommandMode.NingenYoConsoleGame : CommandMode.NigenYoConsoleKaihatu,
                            syuturyoku);
                    }
                    else if (caret == commandline.IndexOf("gameover", caret))
                    {
                        playing.Gameover(commandline, ky, syuturyoku);
                    }
                    else if (caret == commandline.IndexOf("go", caret))
                    {
                        var isSfen = Option_Application.Optionlist.USI;
                        var mode   = CommandMode.NigenYoConsoleKaihatu;
                        playing.Go(isSfen, mode, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("hash", caret))
                    {
                        playing.Hash(ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("hirate", caret))
                    {
                        playing.Hirate(Option_Application.Optionlist.USI, ky, syuturyoku);
                    }
                    else if (caret == commandline.IndexOf("honyaku", caret))
                    {
                        playing.Honyaku(commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("hyoka", caret))
                    {
                        playing.Hyoka(commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("isready", caret))
                    {
                        playing.ReadyOk(syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("jam", caret))
                    {
                        playing.Jam(Option_Application.Optionlist.USI, ky, syuturyoku);
                    }
                    else if (caret == commandline.IndexOf("jokyo", caret))
                    {
                        playing.Jokyo(commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("joseki", caret))
                    {
                        playing.Joseki(Option_Application.Optionlist.USI, commandline, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("kansosen", caret))
                    {
                        // 駒の場所を表示するぜ☆(^▽^)
                        playing.Kansosen(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("kifu", caret))
                    {
                        // 駒の場所を表示するぜ☆(^▽^)
                        playing.Kifu(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("kikikazu", caret))
                    {
                        // 利きの数を調べるぜ☆(^▽^)
                        playing.KikiKazu(commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("kiki", caret))
                    {
                        // 利きを調べるぜ☆(^▽^)
                        playing.Kiki(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("koma", caret))
                    {
                        // 駒の場所を表示するぜ☆(^▽^)
                        playing.Koma_cmd(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("ky", caret))
                    {
                        // 局面を表示するぜ☆(^▽^)
                        Util_Machine.Assert_Sabun_Kiki("飛び利き増やす1", ky.Sindan);
                        playing.Ky(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Machine.Assert_Sabun_Kiki("飛び利き増やす2", ky.Sindan);

                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("manual", caret))
                    {
                        // "man" と同じ☆(^▽^)
                        playing.Man(syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("man", caret))
                    {
                        // "manual" と同じ☆(^▽^)
                        playing.Man(syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("masu", caret))
                    {
                        playing.Masu_cmd(commandline, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("nikoma", caret))
                    {
                        playing.Nikoma(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("position", caret))
                    {
                        playing.Position();

                        // うしろに続く文字は☆(^▽^)
                        int caret2 = 0;
                        Util_String.YomuTangoTobasuMatubiKuhaku(commandline, ref caret2, out string token);

                        if ("position" == token)
                        {
                            // パース☆!(^▽^)
                            if (!ky.ParsePositionvalue(Option_Application.Optionlist.USI, commandline, ref caret2, true, false, out string moves, syuturyoku))
                            {
                                string msg = "パースに失敗だぜ☆(^~^)! #黒牛";
                                syuturyoku.AppendLine(msg);
                                var msg2 = syuturyoku.ToString();
                                syuturyoku.Clear();
                                Logger.Flush(msg2);
                                throw new Exception(msg);
                            }

                            // 棋譜を作成するぜ☆(^▽^)
                            Kifu kifu = new Kifu();

                            // 初期局面
                            {
                                StringBuilder mojiretu = new StringBuilder();
                                ky.AppendFenTo(Option_Application.Optionlist.USI, mojiretu);
                                kifu.SyokiKyokumenFen = mojiretu.ToString();
                            }

                            // うしろに続く文字は☆(^▽^)
                            Util_String.YomuTangoTobasuMatubiKuhaku(commandline, ref caret2, out token);
                            if ("" != moves)
                            {
                                // moves が続いていたら☆(^~^)

                                // 頭の moves を取り除くぜ☆(*^~^*)
                                moves = moves.Substring("moves ".Length);

                                kifu.AddMoves(Option_Application.Optionlist.USI, moves, ky.Sindan);

                                // positionで渡された最終局面まで進めようぜ☆(^▽^)www
                                kifu.GoToFinish(Option_Application.Optionlist.USI, ky, syuturyoku);
                            }

                            // 初回は「position startpos」しか送られてこない☆(^~^)
                        }
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("quit", caret))
                    {
                        playing.Quit();
                        Util_Commandline.IsQuit = true;
                    }
                    else if (caret == commandline.IndexOf("result", caret))
                    {
                        playing.Result(ky, syuturyoku, CommandMode.NigenYoConsoleKaihatu);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("rnd", caret))
                    {
                        playing.Rnd(ky, syuturyoku);
                    }
                    else if (caret == commandline.IndexOf("move", caret))
                    {
                        playing.MoveCmd(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("see", caret))
                    {
                        playing.See(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("seiseki", caret))
                    {
                        playing.Seiseki(Option_Application.Optionlist.USI, commandline, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("setoption", caret))
                    {
                        // // とりあえず無視☆(*^~^*)

                        // 「setoption name 名前 value 値」といった書式なので、
                        // 「set 名前 値」に変えたい。

                        // うしろに続く文字は☆(^▽^)
                        int caret2 = 0;
                        Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret2, "setoption ");
                        Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret2, "name ");
                        int end = commandline.IndexOf("value ", caret2);
                        if (-1 != end)
                        {
                            StringBuilder sb = new StringBuilder();
                            sb.Append("set ");
                            sb.Append(commandline.Substring(caret2, end - caret2)); //名前
                            caret2 = end + "value ".Length;
                            sb.Append(commandline.Substring(caret2));               //値

                            playing.Set(sb.ToString(), ky, syuturyoku);
                        }

                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("set", caret))
                    {
                        playing.Set(commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("taikyokusya", caret))
                    {
                        playing.Taikyokusya_cmd(commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("test", caret))
                    {
                        playing.Test(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("tantaitest", caret))
                    {
                        playing.TantaiTest(playing, Option_Application.Optionlist.USI, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("tumeshogi", caret))
                    {
                        // "tu" と同じ☆(^▽^)
                        playing.TumeShogi(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("tu", caret))
                    {
                        // "tumeshogi" と同じ☆(^▽^)
                        playing.TumeShogi(Option_Application.Optionlist.USI, commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("undo", caret))
                    {
                        playing.Undo(commandline, ky, syuturyoku);
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("usinewgame", caret))
                    {
                        playing.UsiNewGame();
                        Util_Commandline.IsKyokumenEcho = false;
                    }
                    else if (caret == commandline.IndexOf("usi", caret))
                    {
                        //ここは普通、来ない☆(^~^)
                        var     engineName   = engineConf.GetEngine("Name");
                        Version version      = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
                        var     engineAuthor = engineConf.GetEngine("Author");

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

                        syuturyoku.AppendLine("そんなコマンドは無いぜ☆(>_<) man で調べろだぜ☆(^▽^)");
                        var msg = syuturyoku.ToString();
                        syuturyoku.Clear();
                        Logger.Flush(msg);
                    }

                    if (Util_Commandline.IsQuit)
                    {
                        break;//goto gt_EndLoop1;
                    }

                    // 次の入力を促す表示をしてるだけだぜ☆(^~^)
                    Util_Commandline.ShowPrompt(playing, Option_Application.Optionlist.USI, ky, syuturyoku);
                }//無限ループ
                 //gt_EndLoop1:
                 //;

                // 開発モードでは、ユーザー入力を待機するぜ☆(^▽^)

                // (手順5)アプリケーション終了時に呼び出せだぜ☆(^▽^)!
                Face_Kifuwarabe.OnApplicationFinished(syuturyoku);
            }
            catch (Exception ex)
            {
                // エラーが起こりました。
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                // どうにもできないので  ログだけ取って無視します。
                Logger.Fatal($"(^ー^)「大外枠でキャッチ」:{ex}");
                Console.Out.WriteLine("bestmove resign");
                //throw;//追加
            }
        }
Exemplo n.º 5
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);
        }