2011/12/21
■ 先読みを考える
USIプロトコルの先読みは、
"go ponder btime [ミリ秒] wtime [ミリ秒] byoyomi [ミリ秒]"が送られてくる。
残り時間はあとで使うため保存しておく。
予想手が当たったら、"ponderhit"が送られてくる。ここからは通常探索に切り替える。残り時間は先の"go ponder"で送られてきたものを用いる。
予想手が当たらなかった時は、"stop"が送られてくるので、先読みを中止する。"stop"の仕様では即座に"bestmove"を返さないといけないが、先読み時は無視される。
次に本来の手による"position"が送られてくる。
"ponderhit"あるいは"stop"が送られてくるまでに"bestmove"を返すと、反則負け(2度指し)になるので注意。もし読みきって最善手が確定しているときは"ponderhit"あるいは"stop"が送られてくるまで待つことになる。
面倒な上に危なっかしい電文仕様だが、将棋所が標準GUI盤となっている以上はこれを使うしかない。惜しむべきは将棋所がソース非公開のため、電文のやり取りがどうなっているか分からない。
■ Glaurungの実装
USIプロトコル原案者であるTord Romstad氏のglaurung2.2のソースを見てみる。
先読み中、"ponderhit"を受信したときは、
if (Iteration >= 2 && (!InfiniteSearch && (StopOnPonderhit || t > AbsoluteMaxSearchTime || (RootMoveNumber == 1 && t > MaxSearchTime+ExtraSearchTime) || (!FailHigh && !fail_high_ply_1() && !Problem && t > 6*MaxSearchTime+ExtraSearchTime)))))
なる条件で、bestmoveを返す。この条件は反復深化を抜ける条件よりゆるそうなので"ponderhit"なら、よく読めていると見て、さっと読んで時間を節約する方針か。
一方、"stop"を受信したときは、探索を中止して即座に"bestmove"を返す。
もし、先読み中に反復深化を抜けたなら(相手より先に読みきった)、"ponderhit"あるいは"stop"受信まで待って"bestmove"を返している。
"ponderhit"受信時の時間節約は参考になる。