Ejemplo n.º 1
0
        public void ReadyOk()
        {
            //------------------------------------------------------------
            // それでは定刻になりましたので……
            //------------------------------------------------------------
            //
            // 図.
            //
            //      log.txt
            //      ┌────────────────────────────────────────
            //      ~
            //      │2014/08/02 1:31:35> isready
            //      │
            //
            //
            // 対局開始前に、将棋所から送られてくる文字が isready です。


            //------------------------------------------------------------
            // 将棋エンジン「おっおっ、設定を終わらせておかなければ(汗、汗…)」
            //------------------------------------------------------------
#if DEBUG
            Logger.Trace("┏━━━━━設定━━━━━┓");
            foreach (KeyValuePair <string, string> pair in this.SetoptionDictionary)
            {
                // ここで将棋エンジンの設定を済ませておいてください。
                Logger.Trace($"{pair.Key}={pair.Value}");
            }
            Logger.Trace("┗━━━━━━━━━━━━┛");
#endif

            //------------------------------------------------------------
            // よろしくお願いします(^▽^)!
            //------------------------------------------------------------
            //
            // 図.
            //
            //      log.txt
            //      ┌────────────────────────────────────────
            //      ~
            //      │2014/08/02 2:03:33< readyok
            //      │
            //
            //
            // いつでも対局する準備が整っていましたら、 readyok を送り返します。
            Playing.Send("readyok");
        }
Ejemplo n.º 2
0
        public void Stop()
        {
            //------------------------------------------------------------
            // あなたの手番です  (すぐ指してください!)
            //------------------------------------------------------------
            //
            // 図.
            //
            //      log.txt
            //      ┌────────────────────────────────────────
            //      ~
            //      │2014/08/02 2:03:35> stop
            //      │
            //

            // 何らかの理由で  すぐ指してほしいときに、将棋所から送られてくる文字が stop です。
            //
            // 理由は2つ考えることができます。
            //  (1)1手前に、将棋エンジンが  将棋所に向かって「予想手」付きで指し手を伝えたのだが、
            //        相手の応手が「予想手」とは違ったので、予想手にもとづく思考を  今すぐ変えて欲しいとき。
            //
            //  (2)「急いで指すボタン」が押されたときなどに送られてくるようです?
            //
            // stop するのは思考です。  stop を受け取ったら  すぐに最善手を指してください。

            if (this.Game.GoPonderNow)
            {
                //------------------------------------------------------------
                // 将棋エンジン「(予想手が間違っていたって?)  △9二香 を指そうと思っていたんだが」
                //------------------------------------------------------------
                //
                // 図.
                //
                //      log.txt
                //      ┌────────────────────────────────────────
                //      ~
                //      │2014/08/02 2:36:21< bestmove 9a9b
                //      │
                //
                //
                //      1手前の指し手で、将棋エンジンが「bestmove ★ ponder ★」という形で  予想手付きで将棋所にメッセージを送っていたとき、
                //      その予想手が外れていたならば、将棋所は「stop」を返してきます。
                //      このとき  思考を打ち切って最善手の指し手をすぐに返信するわけですが、将棋所はこの返信を無視します☆w
                //      (この指し手は、外れていた予想手について考えていた“最善手”ですからゴミのように捨てられます)
                //      その後、将棋所から「position」「go」が再送されてくるのだと思います。
                //
                //          将棋エンジン「bestmove ★ ponder ★」
                //              ↓
                //          将棋所      「stop」
                //              ↓
                //          将棋エンジン「うその指し手返信」(無視されます)←今ここ
                //              ↓
                //          将棋所      「position」「go」
                //              ↓
                //          将棋エンジン「本当の指し手」
                //
                //      という流れと思います。
                // この指し手は、無視されます。(無視されますが、送る必要があります)
                Playing.Send("bestmove 9a9b");
            }
            else
            {
                //------------------------------------------------------------
                // じゃあ、△9二香で
                //------------------------------------------------------------
                //
                // 図.
                //
                //      log.txt
                //      ┌────────────────────────────────────────
                //      ~
                //      │2014/08/02 2:36:21< bestmove 9a9b
                //      │
                //
                //
                // 特に何もなく、すぐ指せというのですから、今考えている最善手をすぐに指します。
                Playing.Send("bestmove 9a9b");
            }
        }
Ejemplo n.º 3
0
        public void Go(string btime, string wtime, string byoyomi, string binc, string winc)
        {
            //------------------------------------------------------------
            // あなたの手番です
            //------------------------------------------------------------
            //
            // 図.
            //
            //      log.txt
            //      ┌────────────────────────────────────────
            //      ~
            //      │2014/08/02 2:36:19> go btime 599000 wtime 600000 byoyomi 60000
            //      │
            //
            // もう指していいときに、将棋所から送られてくる文字が go です。
            //


            //------------------------------------------------------------
            // 先手 3:00  後手 0:00  記録係「50秒ぉ~」
            //------------------------------------------------------------
            //
            // 上図のメッセージのままだと使いにくいので、
            // あとで使いやすいように Key と Value の表に分けて持ち直します。
            //
            // 図.
            //
            //      goDictionary
            //      ┌──────┬──────┐
            //      │Key         │Value       │
            //      ┝━━━━━━┿━━━━━━┥
            //      │btime       │599000      │
            //      ├──────┼──────┤
            //      │wtime       │600000      │
            //      ├──────┼──────┤
            //      │byoyomi     │60000       │
            //      └──────┴──────┘
            //      単位はミリ秒ですので、599000 は 59.9秒 です。
            //
            //----------------------------------------
            // 棋譜ツリー、局面データは、position コマンドで先に与えられているものとします。
            //----------------------------------------

            // ┏━━━━プログラム━━━━┓

            int latestTemezumi = this.Game.Kifu.CurNode.Value.KyokumenConst.Temezumi;     //現・手目済

            SkyConst src_Sky = this.Game.Kifu.NodeAt(latestTemezumi).Value.KyokumenConst; //現局面

            //Logger.Trace($"将棋サーバー「{latestTemezumi}手目、きふわらべ さんの手番ですよ!」 {line}");


            //----------------------------------------
            // 王の状態を調べます。
            //----------------------------------------
            Result_KingState result_kingState;

            {
                result_kingState = Result_KingState.Empty;

                RO_Star king1p = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.SenteOh).Now);
                RO_Star king2p = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.GoteOh).Now);
                //Logger.Trace("将棋サーバー「ではここで、王さまがどこにいるか確認してみましょう」");
                //Logger.Trace($"▲王の置き場={Conv_SyElement.Masu_ToOkiba(koma1.Masu)}");
                //Logger.Trace($"△王の置き場={Conv_SyElement.Masu_ToOkiba(koma2.Masu)}");

                if (Conv_SyElement.ToOkiba(king1p.Masu) != Okiba.ShogiBan)
                {
                    // 先手の王さまが将棋盤上にいないとき☆
                    result_kingState = Result_KingState.Lost_SenteOh;
                }
                else if (Conv_SyElement.ToOkiba(king2p.Masu) != Okiba.ShogiBan)
                {
                    // または、後手の王さまが将棋盤上にいないとき☆
                    result_kingState = Result_KingState.Lost_GoteOh;
                }
                else
                {
                    result_kingState = Result_KingState.Empty;
                }
            }

            //------------------------------------------------------------
            // わたしの手番のとき、王様が 将棋盤上からいなくなっていれば、投了します。
            //------------------------------------------------------------
            //
            //      将棋GUI『きふならべ』用☆ 将棋盤上に王さまがいないときに、本将棋で go コマンドが送られてくることは無いのでは☆?
            //
            switch (result_kingState)
            {
            case Result_KingState.Lost_SenteOh:   // 先手の王さまが将棋盤上にいないとき☆
            case Result_KingState.Lost_GoteOh:    // または、後手の王さまが将棋盤上にいないとき☆
            {
                //------------------------------------------------------------
                // 投了
                //------------------------------------------------------------
                //
                // 図.
                //
                //      log.txt
                //      ┌────────────────────────────────────────
                //      ~
                //      │2014/08/02 2:36:21< bestmove resign
                //      │
                //

                // この将棋エンジンは、後手とします。
                // 20手目、投了  を決め打ちで返します。
                Playing.Send("bestmove resign");        //投了
            }
            break;

            default:    // どちらの王さまも、まだまだ健在だぜ☆!
            {
                List <KifuNode> bestKifuNodeList = new List <KifuNode>();

                //------------------------------------------------------------
                // 指し手のチョイス
                //------------------------------------------------------------
                bool isHonshogi = true;



                //------------------------------------------------------------
                // MultiPV のテスト中☆
                //------------------------------------------------------------
                //
                // 指し手を決めます。
                // TODO: その指し手の評価値がいくらだったのか調べたい。
                //
                // FIXME: ログがMultiPV別になっていないので、混ざって、同じ手を2度指しているみたいに見えてしまう☆
                //
                int multiPV_Count = 1;        // 2;
                {
                    // 最善手、次善手、三次善手、四次善手、五次善手
                    for (int iMultiPV = 0; iMultiPV < multiPV_Count; iMultiPV++)
                    {
                        bestKifuNodeList.Add(this.WA_Bestmove(
                                                 isHonshogi,
                                                 this.Game.Kifu)
                                             );
                    }


#if DEBUG
                    //// 内容をログ出力
                    //// 最善手、次善手、三次善手、四次善手、五次善手
                    //StringBuilder sb = new StringBuilder();
                    //for (int iMultiPV = 0; iMultiPV < 5; iMultiPV++)
                    //{
                    //    string sfenText = Util_Sky.ToSfenMoveText(bestMoveList[iMultiPV]);
                    //    sb.AppendLine($"[{iMultiPV}]{sfenText}");
                    //}
                    //System.Windows.Forms.MessageBox.Show(sb.ToString());
#endif
                }

                KifuNode bestKifuNode = null;
                // 最善手、次善手、三次善手、四次善手、五次善手
                float bestScore = float.MinValue;
                for (int iMultiPV = 0; iMultiPV < bestKifuNodeList.Count; iMultiPV++)
                {
                    KifuNode node = bestKifuNodeList[iMultiPV];

                    if (null != node && null != node.KyHyokaSheet_Mutable && bestScore <= node.Score)
                    {
                        bestScore    = node.Score;
                        bestKifuNode = node;
                    }
                }

                IMove bestMove2;
                if (null == bestKifuNode)
                {
                    // 投了
                    bestMove2 = Util_Sky258A.NullObjectMove;
                }
                else
                {
                    bestMove2 = bestKifuNode.Key;
                }

                if (Util_Sky_BoolQuery.isEnableSfen(bestMove2))
                {
                    string sfenText = ConvMoveStrSfen.ToMoveStrSfen(bestMove2);

                    // ログが重過ぎる☆!
                    //Logger.Trace($"(Warabe)指し手のチョイス: bestmove=[{sfenText}] 棋譜={KirokuGakari.ToJsaKifuText(this.Kifu)}");

                    //----------------------------------------
                    // スコア 試し
                    //----------------------------------------
                    {
                        //int hyojiScore = (int)(bestScore / 100.0d);//FIXME:適当に調整した。
                        int hyojiScore = (int)bestScore;
                        if (this.Game.Kifu.CurNode.Value.KyokumenConst.KaisiPside == Playerside.P2)
                        {
                            // 符号を逆転
                            hyojiScore = -hyojiScore;
                        }
                        Playing.Send($"info time 1 depth 1 nodes 1 score cp {hyojiScore.ToString()} pv ");        //FIXME:
                        //+ " pv 3a3b L*4h 4c4d"
                    }


                    //----------------------------------------
                    // 指し手を送ります。
                    //----------------------------------------
                    Playing.Send($"bestmove {sfenText}");
                }
                else         // 指し手がないときは、SFENが書けない☆ 投了だぜ☆
                {
                    // ログが重過ぎる☆!
                    //Logger.Trace($"(Warabe)指し手のチョイス: 指し手がないときは、SFENが書けない☆ 投了だぜ☆ww(>_<) 棋譜={KirokuGakari.ToJsaKifuText(this.Kifu)}");

                    //----------------------------------------
                    // 投了w!
                    //----------------------------------------
                    Playing.Send("bestmove resign");
                }

                //------------------------------------------------------------
                // 以前の手カッター
                //------------------------------------------------------------
                UtilKifuTree282.IzennoHenkaCutter(this.Game.Kifu);
            }
            break;
            }
            // ┗━━━━プログラム━━━━┛

            // Logger.Trace();

            //throw new Exception("デバッグだぜ☆! エラーはキャッチできたかな~☆?(^▽^)");
        }
Ejemplo n.º 4
0
        public void UsiOk(string engineName, string engineAuthor)
        {
            //------------------------------------------------------------
            // あなたは USI ですか?
            //------------------------------------------------------------
            //
            // 図.
            //
            //      log.txt
            //      ┌────────────────────────────────────────
            //      ~
            //      │2014/08/02 1:31:35> usi
            //      │
            //
            //
            // 将棋所で [対局(G)]-[エンジン管理...]-[追加...] でファイルを選んだときに、
            // 送られてくる文字が usi です。


            //------------------------------------------------------------
            // エンジン設定ダイアログボックスを作ります
            //------------------------------------------------------------
            //
            // 図.
            //
            //      log.txt
            //      ┌────────────────────────────────────────
            //      ~
            //      │2014/08/02 23:40:15< option name 子 type check default true
            //      │2014/08/02 23:40:15< option name USI type spin default 2 min 1 max 13
            //      │2014/08/02 23:40:15< option name 寅 type combo default tiger var マウス var うし var tiger var ウー var 龍 var へび var 馬 var ひつじ var モンキー var バード var ドッグ var うりぼー
            //      │2014/08/02 23:40:15< option name 卯 type button default うさぎ
            //      │2014/08/02 23:40:15< option name 辰 type string default DRAGON
            //      │2014/08/02 23:40:15< option name 巳 type filename default スネーク.html
            //      │
            //
            //
            // 将棋所で [エンジン設定] ボタンを押したときに出てくるダイアログボックスに、
            //      ・チェックボックス
            //      ・スピン
            //      ・コンボボックス
            //      ・ボタン
            //      ・テキストボックス
            //      ・ファイル選択テキストボックス
            // を置くことができます。
            //

            //------------------------------------------------------------
            // USI です!!
            //------------------------------------------------------------
            //
            // 図.
            //
            //      log.txt
            //      ┌────────────────────────────────────────
            //      ~
            //      │2014/08/02 2:03:33< id name fugafuga 1.00.0
            //      │2014/08/02 2:03:33< id author hogehoge
            //      │2014/08/02 2:03:33< usiok
            //      │
            //
            // プログラム名と、作者名を送り返す必要があります。
            // オプションも送り返せば、受け取ってくれます。
            // usi を受け取ってから、5秒以内に usiok を送り返して完了です。

            Playing.Send($@"option name 子 type check default true
option name USI type spin default 2 min 1 max 13
option name 寅 type combo default tiger var マウス var うし var tiger var ウー var 龍 var へび var 馬 var ひつじ var モンキー var バード var ドッグ var うりぼー
option name 卯 type button default うさぎ
option name 辰 type string default DRAGON
option name 巳 type filename default スネーク.html
id name {engineName}
id author {engineAuthor}
usiok");
        }