Esempio n. 1
0
        /// <summary>
        /// "go mate"に対しては "bestmove"ではなく、"checkmate.."という文字列が返ってくる。
        /// これをparseする。
        /// </summary>
        /// <param name="scanner"></param>
        public void HandleCheckmate(Scanner scanner)
        {
            EvalValueEx eval = null;

            var moves = new List <Move>();

            if (scanner.PeekText("nomate"))
            {
                // 不詰を表現している(ことにする)
                moves.Add(Move.MATE_ENGINE_NO_MATE);
            }
            else if (scanner.PeekText("notimplemented"))
            {
                // 手番側が王手をされているとき、詰将棋エンジンが実装されていない。
                moves.Add(Move.MATE_ENGINE_NOT_IMPLEMENTED);
            }
            else if (scanner.PeekText("timeout"))
            {
                // 時間切れ
                moves.Add(Move.MATE_TIMEOUT);
            }
            else
            {
                // 詰みを発見した。

                while (!scanner.IsEof)
                {
                    var token = scanner.ParseText();
                    var move  = Core.Util.FromUsiMove(token);
                    if (move == Move.NONE)
                    {
                        break;
                    }
                    moves.Add(move);
                }

                // {moves.Count}手で詰み…とは限らないのでエンジンによってはこれあまり良くなかったり?
                eval = new EvalValueEx(EvalValue.Mate - moves.Count, ScoreBound.Exact);

                // 手数不明の詰み
                //eval = new EvalValueEx(EvalValue.MatePlus , ScoreBound.Exact);
            }

            // 次のThink()が呼び出されているなら、この読み筋は、無効化されなくてはならない。
            if (!ThinkingBridge.IsStopping)
            {
                ThinkReport = new UsiThinkReport()
                {
                    Moves       = moves,
                    Eval        = eval,
                    ElapsedTime = ThinkingBridge.ElapsedTime, // 消費時間はサーバー計測
                };
            }

            // 確定したので格納しておく。
            if (ThinkingBridge.BestMoveReceived(moves[0], Move.NONE))
            {
                ThinkReport = UsiEngineReportMessageType.UsiThinkEnd;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// infoコマンドを処理します。
        /// </summary>
        private void HandleInfo(Scanner scanner)
        {
            // あとで書く。
#if false
            var report = new UsiThinkReport(this);

            // reportの情報をエンジンにも設定する
            if (!report.Parse(CurrBoard, scanner, this))
            {
                return;
            }

            if ((report.PVSeq != null && report.PVSeq.Any()) ||
                report.InfoString != null)
            {
                AddThinkReport(report);
            }
#endif
        }
Esempio n. 3
0
        /// <summary>
        /// infoコマンドを処理します。
        /// </summary>
        private void HandleInfo(Scanner scanner)
        {
            try
            {
                var info     = new UsiThinkReport();
                var parseEnd = false;
                while (!scanner.IsEof && !parseEnd)
                {
                    switch (scanner.ParseText())
                    {
                    // hash使用率 1000分率返ってくるので10で割って100分率に変換して代入する。
                    case "hashfull":
                        info.HashPercentage = (float)scanner.ParseInt() / 10.0f;
                        break;

                    // nps
                    case "nps":
                        info.Nps = scanner.ParseInt();
                        break;

                    // 現在の探索手
                    case "currmove":
                        info.CurrentMove = scanner.ParseText();
                        break;

                    // 探索ノード数
                    case "nodes":
                        info.Nodes = scanner.ParseInt();
                        break;

                    // 探索深さ,選択探索深さ

                    // ここに文字が入っている可能性があるので(upperbound/lowerboundを表現するための"↑"など)文字列として扱う。
                    case "depth":
                        info.Depth = scanner.ParseText();
                        break;

                    case "seldepth":
                        info.SelDepth = scanner.ParseText();
                        break;

                    case "score":
                        info.Eval = HandleInfoScore(scanner);
                        break;

                    case "pv":
                        info.Moves = HandlePVSeq(scanner);
                        //parseEnd = true; // "pv"はそのあと末尾まで。

                        // ここから、解釈できない文字列はinfo.MovesSuffixに追加。
                        info.MovesSuffix = HandlePVSuffix(scanner);

                        break;

                    // リポート情報のみ更新
                    case "time":
                        info.ElapsedTime = TimeSpan.FromMilliseconds(scanner.ParseInt());
                        break;

                    case "multipv":
                        info.MultiPV = (int)scanner.ParseInt();
                        break;

                    case "string":
                        info.InfoString = scanner.LastText;     // 残り全部
                        parseEnd        = true;
                        break;
#if false
                    // なんかよくわからん。あとで考える。

                    case "count":
                        GodwhaleCount = scanner.ParseInt();
                        break;

                    case "ranking":
                        GodwhaleRank = scanner.ParseInt();
                        break;

                    // 無視
                    case "currmovenumber":
                    case "cpuload":
                    case "refutation":
                    case "currline":
                    case "id":     // クジラちゃん用
                        scanner.ParseText();
                        break;
#endif

                    // エラー
                    default:
                        throw new Exception();
                    }
                }

                // 次のThink()が呼び出されているなら、この読み筋は、無効化されなくてはならない。
                if (!ThinkingBridge.IsStopping)
                {
                    ThinkReport = info;
                }
            } catch
            {
                throw new UsiException("info 文字列の解析に失敗 : " + scanner.Text);
            }
        }