/// <summary> /// bestmove コマンドを処理します。 /// </summary> private void HandleBestMove(Scanner scanner) { try { Move move = Move.NONE, ponder = Move.NONE; var moveSfen = scanner.ParseText(); // まず、特殊な指し手を調べます。 switch (moveSfen) { case "resign": move = Move.RESIGN; break; case "win": move = Move.WIN; break; } // 上記に該当しなかった。 if (move == Move.NONE) { move = Core.Util.FromUsiMove(moveSfen); if (move == Move.NONE) { // 解釈できない文字列 throw new UsiException( moveSfen + ": SFEN形式の指し手が正しくありません。"); } } // 後続があって、"ponder"と書いてある。 if (!scanner.IsEof) { if (scanner.ParseText() != "ponder") { // "ponder"以外はこれないはずなのに…。 throw new UsiException( "invalid command: " + scanner.Text); } // ponderの指し手は'(null)'などが指定されることもあるので、 // 指せなくてもエラーにはしません。 var ponderSfen = scanner.ParseText(); ponder = Core.Util.FromUsiMove(ponderSfen); } // 確定したので格納しておく。 ThinkingBridge.BestMoveReceived(move, ponder); } catch (UsiException ex) { // 例外を出力しておく。 Log.Write(LogInfoType.UsiParseError, $"例外が発生しました。: {ex.Message}"); } }
/// <summary> /// エンジンに思考させる。 /// Thinkingの時に呼び出された場合、現在のThinkに対してstopを呼び出して、 /// bestmoveが返ってきてから次のthinkを行う。 /// 現在の /// </summary> /// <param name="usiPositionString"></param> public void Think(string usiPositionString, UsiThinkLimit limit, Color sideToMove) { if (IsMateSearch) { ThinkingBridge.Think($"position {usiPositionString}", $"go mate {limit.ToUsiString(sideToMove)}"); } else { ThinkingBridge.Think($"position {usiPositionString}", $"go {limit.ToUsiString(sideToMove)}"); } }
/// <summary> /// エンジンに思考させる。 /// Thinkingの時に呼び出された場合、現在のThinkに対してstopを呼び出して、 /// bestmoveが返ってきてから次のthinkを行う。 /// </summary> /// <param name="usiPositionString"></param> public void Think(Kifu.KifuNode node, string usiPositionString, UsiThinkLimit limit, Color sideToMove) { if (State != UsiEngineState.InTheGame) { // ゲーム中以外でThinkを呼び出している。 // 駒を持ち上げて、その状態で検討ボタンを押すとNotifyTurnChanged()が呼び出されて、 // エンジン側が未初期化なのにこのメソッドが呼び出されるなど…。 // このあと、エンジンの初期化が終わったタイミングで再度、NotifyTurnChanged()から // このメソッドが呼び出されるはずなので、今回は単に無視しておくだけで良い。 Log.Write(LogInfoType.UsiServer, "InTheGameではないのにThink()を呼び出している。"); return; } if (IsMateSearch) { ThinkingBridge.Think(node, $"position {usiPositionString}", $"go {limit.ToUsiMateString(sideToMove)}"); } else { ThinkingBridge.Think(node, $"position {usiPositionString}", $"go {limit.ToUsiString(sideToMove)}"); } }
/// <summary> /// いますぐに指させる。 /// go ponderに対して bestmoveが欲しいときにもこれを用いる。 /// </summary> public void MoveNow() { // 思考中であれば、stopコマンドを送信することで思考を中断できる(はず) ThinkingBridge.Stop(); }
/// <summary> /// エンジンに思考させる。 /// Thinkingの時に呼び出された場合、現在のThinkに対してstopを呼び出して、 /// bestmoveが返ってきてから次のthinkを行う。 /// 現在の /// </summary> /// <param name="usiPositionString"></param> public void Think(string usiPositionString, UsiThinkLimit limit) { ThinkingBridge.Think($"position {usiPositionString}", $"go {limit.ToUsiString()}"); }