Beispiel #1
0
        public string Execute(
            ref KifuParserA_Result result,
            IRoomViewModel roomViewModel,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            nextState = this;

            if (genjo.InputLine.StartsWith("moves"))
            {
                //>>>>> 棋譜が始まります。

                Logger.Trace("(^△^)「" + genjo.InputLine + "」vs【" + this.GetType().Name + "】 : ウム☆ moves 分かるぜ☆");

                genjo.InputLine = genjo.InputLine.Substring("moves".Length);
                genjo.InputLine = genjo.InputLine.Trim();


                nextState = KifuParserA_StateA2_SfenMoves.GetInstance();
            }
            else
            {
                Logger.Trace("\(^o^)/「" + genjo.InputLine + "」vs【" + this.GetType().Name + "】 : movesがない☆! 終わるぜ☆");
                genjo.ToBreak = true;
            }

            return(genjo.InputLine);
        }
Beispiel #2
0
        /// <summary>
        /// 1ステップずつ実行します。
        /// </summary>
        /// <param name="inputLine"></param>
        /// <param name="kifu"></param>
        /// <param name="larabeLogger"></param>
        /// <returns></returns>
        public string Execute_Step(
            ref KifuParserA_Result result,
            Model_Taikyoku model_Taikyoku,
            KifuParserA_Genjo genjo
            ,
            [CallerMemberName] string memberName    = "",
            [CallerFilePath] string sourceFilePath  = "",
            [CallerLineNumber] int sourceLineNumber = 0
            )
        {
            //shogiGui_Base.Model_PnlTaikyoku.Kifu.AssertPside(shogiGui_Base.Model_PnlTaikyoku.Kifu.CurNode, "Execute_Step",logTag);

#if DEBUG
            Logger.Trace("┏━━━━━┓(^o^)");
            Logger.Trace($"わたしは {this.State.GetType().Name} の Execute_Step だぜ☆ : 呼出箇所={memberName}.{sourceFilePath}.{sourceLineNumber}");
#endif

            KifuParserA_State nextState;
            genjo.InputLine = this.State.Execute(
                ref result,
                model_Taikyoku,
                out nextState, this,
                genjo);
            this.State = nextState;

            return(genjo.InputLine);
        }
Beispiel #3
0
        /// <summary>
        /// 最初から最後まで実行します。(きふわらべCOMP用)
        /// </summary>
        /// <param name="inputLine"></param>
        /// <param name="kifu"></param>
        /// <param name="larabeLogger"></param>
        public void Execute_All(
            ref KifuParserA_Result result,
            Model_Taikyoku model_Taikyoku,
            KifuParserA_Genjo genjo
            ,
            [CallerMemberName] string memberName    = "",
            [CallerFilePath] string sourceFilePath  = "",
            [CallerLineNumber] int sourceLineNumber = 0
            )
        {
#if DEBUG
            Logger.Trace("┏━━━━━━━━━━┓");
            Logger.Trace($"わたしは {this.State.GetType().Name} の Execute_All だぜ☆ : 呼出箇所={memberName}.{sourceFilePath}.{sourceLineNumber}");
#endif

            KifuParserA_State nextState = this.State;

            while (!genjo.IsBreak())//breakするまでくり返し。
            {
                if ("" == genjo.InputLine)
                {
                    // FIXME: コンピューターが先手のとき、ここにくる?

                    // 異常時。
                    //FIXME: Logger.Trace($"\(^o^)/「{genjo.InputLine}」入力がない3☆! 終わるぜ☆");
                    genjo.ToBreak_Abnormal();
                    goto gt_NextLoop1;
                }


                genjo.InputLine = this.State.Execute(
                    ref result,
                    model_Taikyoku,
                    out nextState, this,
                    genjo);
                this.State = nextState;

gt_NextLoop1:
                ;
            }



            //if (null != genjo.StartposImporter_OrNull)
            //{
            //    // SFENの解析結果を渡すので、
            //    // その解析結果をどう使うかは、委譲します。
            //    this.Delegate_OnChangeSky_Im(
            //        model_PnlTaikyoku,
            //        genjo,
            //        logTag
            //        );
            //}
        }
Beispiel #4
0
        public string Execute(
            ref KifuParserA_Result result,
            Model_Taikyoku model_Taikyoku,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            nextState = this;

            Logger.Error($"(^△^)「{genjo.InputLine}」vs【{this.GetType().Name}】 : さて、どんな内容なんだぜ☆?");

            StartposImporter startposImporter1;
            string           restText;

            bool successful = StartposImporter.TryParse(
                genjo.InputLine,
                out startposImporter1,
                out restText
                );

            genjo.StartposImporter_OrNull = startposImporter1;
            Logger.Error($"(^△^)restText=「{restText}」 successful=【{successful}】");

            if (successful)
            {
                genjo.InputLine = restText;

                //if(null!=genjo.StartposImporter_OrNull)
                //{
                //    // SFENの解析結果を渡すので、
                //    // その解析結果をどう使うかは、委譲します。
                //    owner.Delegate_OnChangeSky_Im(
                //        model_PnlTaikyoku,
                //        genjo,
                //        logTag
                //        );
                //}

                nextState = KifuParserA_StateA2_SfenMoves.GetInstance();
            }
            else
            {
                // 解析に失敗しました。
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                genjo.ToBreak_Abnormal();
            }

            return(genjo.InputLine);
        }
Beispiel #5
0
        public string Execute(
            ref KifuParserA_Result result,
            Model_Taikyoku model_Taikyoku,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            nextState = this;

            if (genjo.InputLine.StartsWith("startpos"))
            {
                // 平手の初期配置です。
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#if DEBUG
                Logger.Trace($"(^△^)「{genjo.InputLine}」vs【{this.GetType().Name}】 : 平手のようなんだぜ☆");
#endif

                genjo.InputLine = genjo.InputLine.Substring("startpos".Length);
                genjo.InputLine = genjo.InputLine.Trim();

                //----------------------------------------
                // 棋譜を空っぽにし、平手初期局面を与えます。
                //----------------------------------------
                {
                    model_Taikyoku.Kifu.Clear();// 棋譜を空っぽにします。

                    model_Taikyoku.Kifu.GetRoot().Value.SetKyokumen(
                        SkyConst.NewInstance(Util_SkyWriter.New_Hirate(Playerside.P1),
                                             0                                                    //初期配置は 0手目済み。)
                                             ));                                                  //SFENのstartpos解析時
                    model_Taikyoku.Kifu.SetProperty(Word_KifuTree.PropName_Startpos, "startpos"); //平手の初期局面
                }

                nextState = KifuParserA_StateA1a_SfenStartpos.GetInstance();
            }
            else
            {
                //#if DEBUG
                // : 局面の指定のようなんだぜ☆ 対応していない☆?
                Logger.Error($"(^△^)ここはスルーして次に状態遷移するんだぜ☆\n「{genjo.InputLine}」vs【{this.GetType().Name}】");
                //#endif
                nextState = KifuParserA_StateA1b_SfenLnsgkgsnl.GetInstance();
            }

            return(genjo.InputLine);
        }
Beispiel #6
0
        public string Execute(
            ref KifuParserA_Result result,
            Model_Taikyoku model_Taikyoku,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            nextState = this;

            if (genjo.InputLine.StartsWith("position"))
            {
                // SFEN形式の「position」コマンドが、入力欄に入っていました。
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                //------------------------------------------------------------
                // まずこのブロックで「position ~ moves 」まで(*1)を処理します。
                //------------------------------------------------------------
                //
                //          *1…初期配置を作るということです。
                //

#if DEBUG
                Logger.Trace($"(^△^)「{genjo.InputLine}」vs【{this.GetType().Name}】 : フムフム... SFEN形式か...☆");
#endif
                genjo.InputLine = genjo.InputLine.Substring("position".Length);
                genjo.InputLine = genjo.InputLine.Trim();


                nextState = KifuParserA_StateA1_SfenPosition.GetInstance();
            }
            else if ("" == genjo.InputLine)
            {
                // 異常時。
                Logger.Error($"\(^o^)/「{genjo.InputLine}」入力がない2☆! 終わるぜ☆");
                genjo.ToBreak_Abnormal();
            }
            else
            {
#if DEBUG
                Playerside pside = model_Taikyoku.Kifu.CurNode.Value.KyokumenConst.KaisiPside;
                Logger.Trace($"(^△^)「{genjo.InputLine}」vs【{this.GetType().Name}】 : フムフム... positionじゃなかったぜ☆ 日本式か☆? SFENでmovesを読んだあとのプログラムに合流させるぜ☆ : 先後=[{pside}]");
#endif
                nextState = KifuParserA_StateA2_SfenMoves.GetInstance();
            }

            return(genjo.InputLine);
        }
Beispiel #7
0
        public string Execute(
            ref KifuParserA_Result result,
            IRoomViewModel roomViewModel,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            nextState = this;

            StartposImporter startposImporter;
            string           restText;

            bool successful = StartposImporter.TryParse(
                genjo.InputLine,
                out startposImporter,
                out restText
                );

            if (successful)
            {
                genjo.InputLine = restText;

                // SFENの解析結果を渡すので、
                // その解析結果をどう使うかは、委譲します。
                owner.Delegate_OnChangeSky_Im_Srv(
                    roomViewModel,
                    startposImporter,
                    genjo
                    );

                nextState = KifuParserA_StateA2_SfenMoves.GetInstance();
            }
            else
            {
                // 解析に失敗しました。
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                genjo.ToBreak = true;
            }

            return(genjo.InputLine);
        }
Beispiel #8
0
        public string Execute(
            ref KifuParserA_Result result,
            Model_Taikyoku model_Taikyoku,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            nextState = this;

            if (genjo.InputLine.StartsWith("moves"))
            {
                //>>>>> 棋譜が始まります。
                Logger.Trace($"(^△^)「{genjo.InputLine}」vs【{this.GetType().Name}】 : ウム☆ moves 分かるぜ☆");

                genjo.InputLine = genjo.InputLine.Substring("moves".Length);
                genjo.InputLine = genjo.InputLine.Trim();


                nextState = KifuParserA_StateA2_SfenMoves.GetInstance();
            }
            else if ("" == genjo.InputLine)
            {
                // FIXME: コンピューターが先手のとき、ここにくる?

                // 異常時。
                Logger.Error($"\(^o^)/「{genjo.InputLine}」入力がない1☆! 終わるぜ☆");
                genjo.ToBreak_Abnormal();
            }
            else
            {
                // 異常時。
                Logger.Error($"\(^o^)/「{genjo.InputLine}」vs【{this.GetType().Name}】 : movesがない☆! 終わるぜ☆");
                genjo.ToBreak_Abnormal();
            }

            return(genjo.InputLine);
        }
Beispiel #9
0
        public string Execute(
            ref KifuParserA_Result result,
            IRoomViewModel roomViewModel,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            nextState = this;


            if (genjo.InputLine.StartsWith("position"))
            {
                // SFEN形式の「position」コマンドが、入力欄に入っていました。
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                //------------------------------------------------------------
                // まずこのブロックで「position ~ moves 」まで(*1)を処理します。
                //------------------------------------------------------------
                //
                //          *1…初期配置を作るということです。
                //

                Logger.Trace("(^△^)「" + genjo.InputLine + "」vs【" + this.GetType().Name + "】 : フムフム... SFEN形式か...☆");
                genjo.InputLine = genjo.InputLine.Substring("position".Length);
                genjo.InputLine = genjo.InputLine.Trim();


                nextState = KifuParserA_StateA1_SfenPosition.GetInstance();
            }
            else
            {
                Logger.Trace("(^△^)「" + genjo.InputLine + "」vs【" + this.GetType().Name + "】 : フムフム... positionじゃなかったぜ☆ 日本式か☆? SFENでmovesを読んだあとのプログラムに合流させるぜ☆ : 先後=[" + roomViewModel.GameViewModel.Kifu.CountPside(roomViewModel.GameViewModel.Kifu.CurNode) + "]");
                nextState = KifuParserA_StateA2_SfenMoves.GetInstance();
            }

            return(genjo.InputLine);
        }
Beispiel #10
0
        public string Execute(
            ref KifuParserA_Result result,
            IRoomViewModel roomViewModel,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            nextState = this;

            if (genjo.InputLine.StartsWith("startpos"))
            {
                // 平手の初期配置です。
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                Logger.Trace("(^△^)「" + genjo.InputLine + "」vs【" + this.GetType().Name + "】 : 平手のようなんだぜ☆");

                genjo.InputLine = genjo.InputLine.Substring("startpos".Length);
                genjo.InputLine = genjo.InputLine.Trim();

                {
                    roomViewModel.GameViewModel.Kifu.Clear();                                                          // 棋譜を空っぽにします。

                    roomViewModel.GameViewModel.Kifu.GetRoot().Value.SetKyokumen(new SkyConst(Util_Sky.New_Hirate())); //SFENのstartpos解析時
                    roomViewModel.GameViewModel.Kifu.SetProperty(KifuTreeImpl.PropName_Startpos, "startpos");          //平手の初期局面
                }

                nextState = KifuParserA_StateA1a_SfenStartpos.GetInstance();
            }
            else
            {
                Logger.Trace("(^△^)「" + genjo.InputLine + "」vs【" + this.GetType().Name + "】 : 局面の指定のようなんだぜ☆");
                nextState = KifuParserA_StateA1b_SfenLnsgkgsnl.GetInstance();
            }

            return(genjo.InputLine);
        }
Beispiel #11
0
        public string Execute(
            ref KifuParserA_Result result,
            IRoomViewModel roomViewModel,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            // 現局面。
            SkyConst src_Sky = roomViewModel.GameViewModel.Kifu.CurNode.Value.ToKyokumenConst;
            //            Debug.Assert(!Util_MasuNum.OnKomabukuro((int)((RO_Star_Koma)src_Sky.StarlightIndexOf((Finger)0).Now).Masu), "カレント、駒が駒袋にあった。");

            bool isHonshogi = true;                                                                                                   //FIXME:暫定
            int  tesumi_yomiGenTeban_forLog = roomViewModel.GameViewModel.Kifu.CountTesumi(roomViewModel.GameViewModel.Kifu.CurNode); // 0;//FIXME:暫定。読み進めている現在の手目

            //            Debug.Assert(!Util_MasuNum.OnKomabukuro((int)((RO_Star_Koma)kifu.NodeAt(tesumi_yomiGenTeban_forLog).Value.ToKyokumenConst.StarlightIndexOf((Finger)0).Now).Masu), "[" + tesumi_yomiGenTeban_forLog + "]手目、駒が駒袋にあった。");

            nextState = this;

            if (0 < genjo.InputLine.Trim().Length)
            {
                ShootingStarlightable nextTe = Util_Sky.NullObjectMove;
                string rest;

                //「6g6f」形式と想定して、1手だけ読込み
                string str1;
                string str2;
                string str3;
                string str4;
                string str5;
                string str6;
                string str7;
                string str8;
                string str9;
                if (KifuIO_MovesParsers.ParseSfen_FromText(
                        genjo.InputLine, out str1, out str2, out str3, out str4, out str5, out rest)
                    &&
                    !(str1 == "" && str2 == "" && str3 == "" && str4 == "" && str5 == "")
                    )
                {
                    KifuIO_MovesExecuter.ExecuteSfenMoves_FromTextSub(
                        isHonshogi,
                        str1,  //123456789 か、 PLNSGKRB
                        str2,  //abcdefghi か、 *
                        str3,  //123456789
                        str4,  //abcdefghi
                        str5,  //+
                        out nextTe,
                        roomViewModel.GameViewModel.Kifu,
                        "_SFENパース1",
                        tesumi_yomiGenTeban_forLog
                        );
                }
                else
                {
                    //>>>>> 「6g6f」形式ではなかった☆

                    //「▲6六歩」形式と想定して、1手だけ読込み
                    if (KifuIO_MovesParsers.ParseJfugo_FromText(
                            genjo.InputLine, out str1, out str2, out str3, out str4, out str5, out str6, out str7, out str8, out str9, out rest))
                    {
                        if (!(str1 == "" && str2 == "" && str3 == "" && str4 == "" && str5 == "" && str6 == "" && str7 == "" && str8 == "" && str9 == ""))
                        {
                            KifuIO_MovesExecuter.ExecuteJfugo_FromTextSub(
                                str1, //▲△
                                str2, //123…9、123…9、一二三…九
                                str3, //123…9、123…9、一二三…九
                                str4, // “同”
                                str5, //(歩|香|桂|…
                                str6, // 右|左…
                                str7, // 上|引
                                str8, //成|不成
                                str9, //打
                                out nextTe,
                                roomViewModel.GameViewModel.Kifu
                                );
                        }
                    }
                    else
                    {
                        //「6g6f」形式でもなかった☆

                        Logger.Trace("(^△^)「" + genjo.InputLine + "」vs【" + this.GetType().Name + "】 : !? 次の一手が読めない☆ inputLine=[" + genjo.InputLine + "]");
                        genjo.ToBreak = true;
                        goto gt_EndMethod;
                    }
                }

                genjo.InputLine = rest;



                if (null != nextTe)
                {
                    Finger figMovedKoma = Fingers.Error_1;
                    Finger figFoodKoma  = Fingers.Error_1;

                    Application.DoEvents(); // 時間のかかる処理の間にはこれを挟みます。

                    //------------------------------
                    // ★棋譜読込専用  駒移動
                    //------------------------------

                    Logger.Trace("一手指し開始 : 残りの符号つ「" + genjo.InputLine + "」");
                    bool isBack = false;
                    Node <ShootingStarlightable, KyokumenWrapper> out_newNode_OrNull;
                    KifuIO.Ittesasi(
                        nextTe,
                        roomViewModel.GameViewModel.Kifu,
                        isBack,
                        out figMovedKoma,
                        out figFoodKoma,
                        out out_newNode_OrNull//変更した現局面が、ここに入る。
                        );
                    result.Out_newNode_OrNull = out_newNode_OrNull;
                    Logger.Trace(Util_Sky.Json_1Sky(
                                     src_Sky, "一手指し終了",
                                     "_SFENパース2",
                                     tesumi_yomiGenTeban_forLog//読み進めている現在の手目
                                     ));
                }
                else
                {
                    genjo.ToBreak = true;
                    throw new Exception($"\(^o^)/teMoveオブジェクトがない☆! inputLine=[{genjo.InputLine}]");
                }
            }
            else
            {
                Logger.Trace("(^△^)現局面まで進んだのかだぜ☆?\n" + Util_Sky.Json_1Sky(
                                 src_Sky, "棋譜パース",
                                 "_SFENパース3",
                                 tesumi_yomiGenTeban_forLog//読み進めている現在の手目
                                 ));
                genjo.ToBreak = true;
            }

gt_EndMethod:
            return(genjo.InputLine);
        }
Beispiel #12
0
 public KifuParserA_Impl()
 {
     // 初期状態=ドキュメント
     this.State = KifuParserA_StateA0_Document.GetInstance();
 }
Beispiel #13
0
        /// <summary>
        /// C#のプログラムは、
        /// この Main 関数から始まり、 Main 関数を抜けて終わります。
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            var engineConf = new EngineConf();

            EntitiesLayer.Implement(engineConf);

            //
            var playing = new Playing();

            // 思考エンジンの、記憶を読み取ります。
            playing.shogisasi = new ShogisasiImpl(playing);
            playing.shogisasi.Kokoro.ReadTenonagare();

            try
            {
                //
                // 図.
                //
                //     プログラムの開始:  ここの先頭行から始まります。
                //     プログラムの実行:  この中で、ずっと無限ループし続けています。
                //     プログラムの終了:  この中の最終行を終えたとき、
                //                         または途中で Environment.Exit(0); が呼ばれたときに終わります。
                //                         また、コンソールウィンドウの[×]ボタンを押して強制終了されたときも  ぶつ切り  で突然終わります。

                //------+-----------------------------------------------------------------------------------------------------------------
                // 準備 |
                //------+-----------------------------------------------------------------------------------------------------------------
                // データの読取「道」
                Michi187Array.Load(engineConf.GetResourceFullPath("Michi187"));

                // データの読取「配役」
                Util_Haiyaku184Array.Load(engineConf.GetResourceFullPath("Haiyaku185"), Encoding.UTF8);

                // データの読取「強制転成表」 ※駒配役を生成した後で。
                ForcePromotionArray.Load(engineConf.GetResourceFullPath("InputForcePromotion"), Encoding.UTF8);
                File.WriteAllText(engineConf.GetResourceFullPath("OutputForcePromotion"), ForcePromotionArray.LogHtml());

                // データの読取「配役転換表」
                Data_HaiyakuTransition.Load(engineConf.GetResourceFullPath("InputSyuruiToHaiyaku"), Encoding.UTF8);
                File.WriteAllText(engineConf.GetResourceFullPath("OutputSyuruiToHaiyaku"), Data_HaiyakuTransition.LogHtml());



                //-------------------+----------------------------------------------------------------------------------------------------
                // ログファイル削除  |
                //-------------------+----------------------------------------------------------------------------------------------------
                //
                // 図.
                //
                //      フォルダー
                //          ├─ Engine.KifuWarabe.exe
                //          └─ log.txt               ←これを削除
                //
                Logger.RemoveAllLogFile();

                {
                    //-------------+----------------------------------------------------------------------------------------------------------
                    // ログ書込み  |  <この将棋エンジン>  製品名、バージョン番号
                    //-------------+----------------------------------------------------------------------------------------------------------
                    //
                    // 図.
                    //
                    //      log.txt
                    //      ┌────────────────────────────────────────
                    //      │2014/08/02 1:04:59> v(^▽^)v イェーイ☆ ... fugafuga 1.00.0
                    //      │
                    //      │
                    //
                    //
                    // 製品名とバージョン番号は、次のファイルに書かれているものを使っています。
                    // 場所:  [ソリューション エクスプローラー]-[ソリューション名]-[プロジェクト名]-[Properties]-[AssemblyInfo.cs] の中の、[AssemblyProduct]と[AssemblyVersion] を参照。
                    //
                    // バージョン番号を「1.00.0」形式(メジャー番号.マイナー番号.ビルド番号)で書くのは作者の趣味です。
                    //
                    string versionStr;
                    {
                        // バージョン番号
                        Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
                        versionStr = String.Format("{0}.{1}.{2}", version.Major, version.Minor.ToString("00"), version.Build);

                        //seihinName += " " + versionStr;
                    }

                    var engineName = engineConf.GetEngine("Name");
                    Logger.Trace($"v(^▽^)v イェーイ☆ ... {engineName} {versionStr}");
                }


                //-----------+------------------------------------------------------------------------------------------------------------
                // 通信開始  |
                //-----------+------------------------------------------------------------------------------------------------------------
                //
                // 図.
                //
                //      無限ループ(全体)
                //          │
                //          ├─無限ループ(1)
                //          │                      将棋エンジンであることが認知されるまで、目で訴え続けます(^▽^)
                //          │                      認知されると、無限ループ(2)に進みます。
                //          │
                //          └─無限ループ(2)
                //                                  対局中、ずっとです。
                //                                  対局が終わると、無限ループ(1)に戻ります。
                //
                // 無限ループの中に、2つの無限ループが入っています。
                //



                // ループ(全体)
                while (true)
                {
#if DEBUG_STOPPABLE
                    MessageBox.Show("きふわらべのMainの無限ループでブレイク☆!", "デバッグ");
                    System.Diagnostics.Debugger.Break();
#endif
                    // ループ(1つ目)
                    while (true)
                    {
                        // 将棋サーバーから何かメッセージが届いていないか、見てみます。
                        string line = Util_Message.Download_BlockingIO();
                        Logger.WriteLineR(line);

                        if ("usi" == line)
                        {
                            Version version      = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
                            var     engineName   = $"{engineConf.GetEngine("Name")} { version.Major}.{ version.Minor}.{ version.Build}";
                            var     engineAuthor = engineConf.GetEngine("Author");
                            playing.UsiOk(engineName, engineAuthor);
                        }
                        else if (line.StartsWith("setoption"))
                        {
                            Regex regex = new Regex(@"setoption name ([^ ]+)(?: value (.*))?", RegexOptions.Singleline);
                            Match m     = regex.Match(line);

                            if (m.Success)
                            {
                                string name  = (string)m.Groups[1].Value;
                                string value = "";

                                if (3 <= m.Groups.Count)
                                {
                                    // 「value ★」も省略されずにありました。
                                    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                                    value = (string)m.Groups[2].Value;
                                }

                                playing.SetOption(name, value);
                            }
                        }
                        else if ("isready" == line)
                        {
                            playing.ReadyOk();
                        }
                        else if ("usinewgame" == line)
                        {
                            playing.UsiNewGame();

                            // 無限ループ(1つ目)を抜けます。無限ループ(2つ目)に進みます。
                            break;
                        }
                        else if ("quit" == line)
                        {
                            playing.Quit();

                            // このプログラムを終了します。
                            goto end_usi;
                        }
                        else
                        {
                            //------------------------------------------------------------
                            // ○△□×!?
                            //------------------------------------------------------------
                            //
                            // /(^×^)\
                            //

                            // 通信が届いていますが、このプログラムでは  聞かなかったことにします。
                            // USIプロトコルの独習を進め、対応/未対応を選んでください。
                        }
                    }

                    // ループ(2つ目)
                    playing.AjimiEngine = new AjimiEngine(playing);

                    //
                    // 図.
                    //
                    //      この将棋エンジンが後手とします。
                    //
                    //      ┌──┬─────────────┬──────┬──────┬────────────────────────────────────┐
                    //      │順番│                          │計算        │tesumiCount │解説                                                                    │
                    //      ┝━━┿━━━━━━━━━━━━━┿━━━━━━┿━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┥
                    //      │   1│初回                      │            │            │相手が先手、この将棋エンジンが後手とします。                            │
                    //      │    │                          │            │0           │もし、この将棋エンジンが先手なら、初回は tesumiCount = -1 とします。    │
                    //      ├──┼─────────────┼──────┼──────┼────────────────────────────────────┤
                    //      │   2│position                  │+-0         │            │                                                                        │
                    //      │    │    (相手が指しても、     │            │            │                                                                        │
                    //      │    │     指していないときでも │            │            │                                                                        │
                    //      │    │     送られてきます)      │            │0           │                                                                        │
                    //      ├──┼─────────────┼──────┼──────┼────────────────────────────────────┤
                    //      │   3│go                        │+2          │            │+2 します                                                               │
                    //      │    │    (相手が指した)        │            │2           │    ※「go」は、「go ponder」「go mate」「go infinite」とは区別します。 │
                    //      ├──┼─────────────┼──────┼──────┼────────────────────────────────────┤
                    //      │   4│go ponder                 │+-0         │            │                                                                        │
                    //      │    │    (相手はまだ指してない)│            │2           │                                                                        │
                    //      ├──┼─────────────┼──────┼──────┼────────────────────────────────────┤
                    //      │   5│自分が指した              │+-0         │            │相手が指してから +2 すると決めたので、                                  │
                    //      │    │                          │            │2           │自分が指したときにはカウントを変えません。                              │
                    //      └──┴─────────────┴──────┴──────┴────────────────────────────────────┘
                    //


                    //PerformanceMetrics performanceMetrics = new PerformanceMetrics();//使ってない?

                    while (true)
                    {
                        // 将棋サーバーから何かメッセージが届いていないか、見てみます。
                        string line = Util_Message.Download_BlockingIO();
                        Logger.WriteLineR(line);

                        if (line.StartsWith("position"))
                        {
                            // 手番になったときに、“まず”、将棋所から送られてくる文字が position です。
                            // このメッセージを読むと、駒の配置が分かります。
                            //
                            // “が”、まだ指してはいけません。
                            Logger.Trace("(^△^)positionきたコレ!");

                            // 入力行を解析します。
                            KifuParserA_Result result = new KifuParserA_ResultImpl();
                            var roomViewModel         = new DefaultRoomViewModel(playing.Game.Kifu);
                            var genjo  = new KifuParserA_GenjoImpl(line);
                            var parser = new KifuParserA_Impl();
                            Logger.Trace($@"┏━━━━━━━━━━┓
わたしは {parser.State.GetType().Name} の Execute_All だぜ☆");

                            KifuParserA_State nextState = parser.State;

                            while (!genjo.ToBreak)
                            {
                                genjo.InputLine = parser.State.Execute(
                                    ref result,
                                    roomViewModel,
                                    out nextState, parser,
                                    genjo);
                                parser.State = nextState;
                            }


                            KifuNode kifuNode = (KifuNode)result.Out_newNode_OrNull;
                            int      tesumi_yomiGenTeban_forLog = 0;//ログ用。読み進めている現在の手目済

                            Logger.Trace(
                                Util_Sky.Json_1Sky(playing.Game.Kifu.CurNode.Value.ToKyokumenConst, "現局面になっているのかなんだぜ☆? line=[" + line + "] 棋譜=" + KirokuGakari.ToJapaneseKifuText(playing.Game.Kifu),
                                                   "PgCS",
                                                   tesumi_yomiGenTeban_forLog//読み進めている現在の手目
                                                   ));

                            //
                            // 局面画像ログ
                            //
                            if (kifuNode != null) // (2020-12-20 sun) なんでヌルになるのか分からないが、避けるぜ☆(^~^)
                            {
                                //SFEN文字列と、出力ファイル名を指定することで、局面の画像ログを出力します。
                                var ky       = kifuNode.ToRO_Kyokumen1();
                                var fullname = SpecifyFiles.LatestPositionLogPng.Name;
                                var env      = ShogisasiImpl.ReportEnvironment;
                                KyokumenPngWriterImpl.Write1(engineConf, ky, fullname, env);
                            }


                            //------------------------------------------------------------
                            // じっとがまん
                            //------------------------------------------------------------
                            //
                            // 応答は無用です。
                            // 多分、将棋所もまだ準備ができていないのではないでしょうか(?)
                            //
                            playing.Position();
                        }
                        else if (line.StartsWith("go ponder"))
                        {
                            playing.GoPonder();
                        }
                        // 「go ponder」「go mate」「go infinite」とは区別します。
                        else if (line.StartsWith("go"))
                        {
                            //------------------------------------------------------------
                            // あなたの手番です
                            //------------------------------------------------------------
                            //
                            // 図.
                            //
                            //      log.txt
                            //      ┌────────────────────────────────────────
                            //      ~
                            //      │2014/08/02 2:36:19> go btime 599000 wtime 600000 byoyomi 60000
                            //      │
                            //
                            // もう指していいときに、将棋所から送られてくる文字が go です。
                            //

                            // n手目を 2 増やします。
                            // 相手の手番と、自分の手番の 2つが増えた、という数え方です。
                            playing.Game.TesumiCount += 2;

                            //------------------------------------------------------------
                            // 先手 3:00  後手 0:00  記録係「50秒ぉ~」
                            //------------------------------------------------------------
                            //
                            // 上図のメッセージのままだと使いにくいので、
                            // あとで使いやすいように Key と Value の表に分けて持ち直します。
                            //
                            // 図.
                            //
                            //      goDictionary
                            //      ┌──────┬──────┐
                            //      │Key         │Value       │
                            //      ┝━━━━━━┿━━━━━━┥
                            //      │btime       │599000      │
                            //      ├──────┼──────┤
                            //      │wtime       │600000      │
                            //      ├──────┼──────┤
                            //      │byoyomi     │60000       │
                            //      └──────┴──────┘
                            //      単位はミリ秒ですので、599000 は 59.9秒 です。
                            //
                            Regex regex = new Regex(@"go btime (\d+) wtime (\d+) byoyomi (\d+)", RegexOptions.Singleline);
                            Match m     = regex.Match(line);

                            if (m.Success)
                            {
                                playing.Go((string)m.Groups[1].Value, (string)m.Groups[2].Value, (string)m.Groups[3].Value, "", "");
                            }
                            else
                            {
                                // (2020-12-16 wed) フィッシャー・クロック・ルールに対応☆(^~^)
                                regex = new Regex(@"go btime (\d+) wtime (\d+) binc (\d+) winc (\d+)", RegexOptions.Singleline);
                                m     = regex.Match(line);

                                playing.Go((string)m.Groups[1].Value, (string)m.Groups[2].Value, "", (string)m.Groups[3].Value, (string)m.Groups[4].Value);
                            }
                            //System.C onsole.WriteLine();

                            //throw new Exception("デバッグだぜ☆! エラーはキャッチできたかな~☆?(^▽^)");
                        }
                        else if (line.StartsWith("stop"))
                        {
                            playing.Stop();
                        }
                        else if (line.StartsWith("gameover"))
                        {
                            Regex regex = new Regex(@"gameover (.)", RegexOptions.Singleline);
                            Match m     = regex.Match(line);

                            if (m.Success)
                            {
                                playing.GameOver((string)m.Groups[1].Value);
                            }

                            // 無限ループ(2つ目)を抜けます。無限ループ(1つ目)に戻ります。
                            break;
                        }
                        // 独自コマンド「ログ出せ」
                        else if ("logdase" == line)
                        {
                            StringBuilder sb = new StringBuilder();
                            sb.Append("ログだせ~(^▽^)");

                            playing.Game.Kifu.ForeachZenpuku(
                                playing.Game.Kifu.GetRoot(), (int tesumi, KyokumenWrapper sky, Node <ShootingStarlightable, KyokumenWrapper> node, ref bool toBreak) =>
                            {
                                //sb.AppendLine("(^-^)");

                                if (null != node)
                                {
                                    if (null != node.Key)
                                    {
                                        string sfenText = Util_Sky.ToSfenMoveText(node.Key);
                                        sb.Append(sfenText);
                                        sb.AppendLine();
                                    }
                                }
                            });

                            File.WriteAllText("../../Logs/_log_ログ出せ命令.txt", sb.ToString());
                        }
                        else
                        {
                            //------------------------------------------------------------
                            // ○△□×!?
                            //------------------------------------------------------------
                            //
                            // /(^×^)\
                            //

                            // 通信が届いていますが、このプログラムでは  聞かなかったことにします。
                            // USIプロトコルの独習を進め、対応/未対応を選んでください。
                        }
                    }

                    //-------------------+----------------------------------------------------------------------------------------------------
                    // スナップショット  |
                    //-------------------+----------------------------------------------------------------------------------------------------
                    // 対局後のタイミングで、データの中身を確認しておきます。
                    // Key と Value の表の形をしています。(順不同)
                    //
                    // 図.
                    //      ※内容はサンプルです。実際と異なる場合があります。
                    //
                    //      setoptionDictionary
                    //      ┌──────┬──────┐
                    //      │Key         │Value       │
                    //      ┝━━━━━━┿━━━━━━┥
                    //      │USI_Ponder  │true        │
                    //      ├──────┼──────┤
                    //      │USI_Hash    │256         │
                    //      └──────┴──────┘
                    //
                    //      goDictionary
                    //      ┌──────┬──────┐
                    //      │Key         │Value       │
                    //      ┝━━━━━━┿━━━━━━┥
                    //      │btime       │599000      │
                    //      ├──────┼──────┤
                    //      │wtime       │600000      │
                    //      ├──────┼──────┤
                    //      │byoyomi     │60000       │
                    //      └──────┴──────┘
                    //
                    //      goMateDictionary
                    //      ┌──────┬──────┐
                    //      │Key         │Value       │
                    //      ┝━━━━━━┿━━━━━━┥
                    //      │mate        │599000      │
                    //      └──────┴──────┘
                    //
                    //      gameoverDictionary
                    //      ┌──────┬──────┐
                    //      │Key         │Value       │
                    //      ┝━━━━━━┿━━━━━━┥
                    //      │gameover    │lose        │
                    //      └──────┴──────┘
                    //
                    Logger.Trace("KifuParserA_Impl.LOGGING_BY_ENGINE, ┏━確認━━━━setoptionDictionary ━┓");
                    foreach (KeyValuePair <string, string> pair in playing.SetoptionDictionary)
                    {
                        Logger.Trace(pair.Key + "=" + pair.Value);
                    }
                    Logger.Trace("┗━━━━━━━━━━━━━━━━━━┛");

                    //Dictionary<string, string> goMateProperties = new Dictionary<string, string>();
                    //goMateProperties["mate"] = "";
                    //LarabeLoggerList_Warabe.ENGINE.WriteLine_AddMemo("┏━確認━━━━goMateDictionary━━━┓");
                    //foreach (KeyValuePair<string, string> pair in this.goMateProperties)
                    //{
                    //    LarabeLoggerList_Warabe.ENGINE.WriteLine_AddMemo(pair.Key + "=" + pair.Value);
                    //}

                    Logger.Trace("┗━━━━━━━━━━━━━━━━━━┛");
                }
            }
            catch (Exception ex)
            {
                // エラーが起こりました。
                //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                // どうにもできないので  ログだけ取って無視します。
                Logger.Fatal($"(^ー^)「大外枠でキャッチ」{ex}");
                Playing.Send("bestmove resign");
            }

end_usi:
            // 終了時に、妄想履歴のログを残します。
            playing.shogisasi.Kokoro.WriteTenonagare(playing.shogisasi);
        }
Beispiel #14
0
        public string Execute(
            ref KifuParserA_Result result,
            Model_Taikyoku model_Taikyoku,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            // 現局面。
            SkyConst src_Sky = model_Taikyoku.Kifu.CurNode.Value.KyokumenConst;
            //            Debug.Assert(!Util_MasuNum.OnKomabukuro((int)((RO_Star_Koma)src_Sky.StarlightIndexOf((Finger)0).Now).Masu), "カレント、駒が駒袋にあった。");

            bool isHonshogi = true;//FIXME:暫定

            // 現在の手番の開始局面+1
            int korekaranoTemezumi = src_Sky.Temezumi + 1;

            nextState = this;

            if (0 < genjo.InputLine.Trim().Length)
            {
                IMove  nextTe = Util_Sky258A.NullObjectMove;
                string rest;

                //「6g6f」形式と想定して、1手だけ読込み
                string str1;
                string str2;
                string str3;
                string str4;
                string str5;
                string str6;
                string str7;
                string str8;
                string str9;
                if (SfenMovesTextConv.ToTokens(
                        genjo.InputLine, out str1, out str2, out str3, out str4, out str5, out rest)
                    &&
                    !(str1 == "" && str2 == "" && str3 == "" && str4 == "" && str5 == "")
                    )
                {
                    ConvSfenMoveTokens.ToMove(
                        isHonshogi,
                        str1,  //123456789 か、 PLNSGKRB
                        str2,  //abcdefghi か、 *
                        str3,  //123456789
                        str4,  //abcdefghi
                        str5,  //+
                        out nextTe,
                        model_Taikyoku.Kifu,
                        "棋譜パーサーA_SFENパース1"
                        );
                }
                else
                {
                    //>>>>> 「6g6f」形式ではなかった☆

                    //「▲6六歩」形式と想定して、1手だけ読込み
                    if (Conv_JsaFugoText.ToTokens(
                            genjo.InputLine, out str1, out str2, out str3, out str4, out str5, out str6, out str7, out str8, out str9, out rest, model_Taikyoku.Kifu))
                    {
                        if (!(str1 == "" && str2 == "" && str3 == "" && str4 == "" && str5 == "" && str6 == "" && str7 == "" && str8 == "" && str9 == ""))
                        {
                            Conv_JsaFugoTokens.ToMove(
                                str1, //▲△
                                str2, //123…9、123…9、一二三…九
                                str3, //123…9、123…9、一二三…九
                                str4, // “同”
                                str5, //(歩|香|桂|…
                                str6, // 右|左…
                                str7, // 上|引
                                str8, //成|不成
                                str9, //打
                                out nextTe,
                                model_Taikyoku.Kifu
                                );
                        }
                    }
                    else
                    {
                        //「6g6f」形式でもなかった☆

                        Logger.Error($"(^△^)「{genjo.InputLine}」vs【{this.GetType().Name}】 : !? 次の一手が読めない☆ inputLine=[{genjo.InputLine}]");
                        genjo.ToBreak_Abnormal();
                        goto gt_EndMethod;
                    }
                }

                genjo.InputLine = rest;



                if (null != nextTe)
                {
                    IttesasuResult ittesasuResult = new IttesasuResultImpl(Fingers.Error_1, Fingers.Error_1, null, PieceType.None, null);

                    //
                    //FIXME: これが悪さをしていないか☆?
                    //FIXME: スピードが必要なので省略。
                    //Application.DoEvents(); // 時間のかかる処理の間にはこれを挟みます。
                    //

                    //------------------------------
                    // ★棋譜読込専用  駒移動
                    //------------------------------
                    //Logger.Trace($"一手指し開始 : 残りの符号つ「{genjo.InputLine}」");

                    //
                    //↓↓将棋エンジンが一手指し(進める)
                    //
                    Util_IttesasuRoutine.Before1(
                        new IttesasuArgImpl(
                            model_Taikyoku.Kifu.CurNode.Value,
                            src_Sky.KaisiPside,
                            nextTe,            //FIXME: if文で分けているので、これがヌルなはずはないと思うが。
                            korekaranoTemezumi //これから作る局面の、手目済み。
                            ),
                        out ittesasuResult,
                        "KifuParserA_StateA2_SfenMoves#Execute"
                        );

                    Util_IttesasuRoutine.Before2(
                        ref ittesasuResult
                        );

                    //----------------------------------------
                    // 次ノード追加、次ノードをカレントに。
                    //----------------------------------------
                    Util_IttesasuRoutine.After3_ChangeCurrent(
                        model_Taikyoku.Kifu,
                        ConvMoveStrSfen.ToMoveStrSfen(ittesasuResult.Get_SyuryoNode_OrNull.Key),
                        ittesasuResult.Get_SyuryoNode_OrNull
                        );

                    result.Out_newNode_OrNull = ittesasuResult.Get_SyuryoNode_OrNull;
                    //↑↑一手指し

                    //exceptionArea = 1090;
                    //Logger.Trace(Util_Sky307.Json_1Sky(
                    //    src_Sky,
                    //    "一手指し終了",
                    //    "SFENパース2",
                    //    src_Sky.Temezumi//読み進めている現在の手目
                    //    ));
                }
                else
                {
                    genjo.ToBreak_Abnormal();
                    throw new Exception($"\(^o^)/Moveオブジェクトがない☆! inputLine=[{genjo.InputLine}]");
                }
            }
            else
            {
                //Logger.Trace($"(^△^)現局面まで進んだのかだぜ☆?\n{Util_Sky307.Json_1Sky(
                //    src_Sky,
                //    "棋譜パース",
                //    "SFENパース3",
                //    src_Sky.Temezumi//読み進めている現在の手目
                //    )}");
                genjo.ToBreak_Normal();//棋譜パーサーAの、唯一の正常終了のしかた。
            }

gt_EndMethod:
            return(genjo.InputLine);
        }