USI拡張コマンド - mizar/YaneuraOu GitHub Wiki

USI拡張コマンドとは何か?

⚠ 以下の情報は、開発者向けの情報です。思考エンジンで将棋の対局をさせたいだけならば、読む必要はありません。

思考エンジンは、GUI側(将棋所やShogiGUIなどのこと)と、USIプロトコルという仕様に基づいてやりとりを行います。

ところが、このUSIプロトコルだけでは機能が色々と不足しているため、やねうら王では独自にいくつかUSIプロトコルを拡張しています。

やねうら王では、おおよそは上位互換となる形で実装してあるので、通常のUSIプロトコル対応の思考エンジンとして振る舞えますが、それに留まらず、様々な便利機能を提供しています。

ここでは、やねうら王・ふかうら王で実装されている、USIプロトコルを拡張したコマンドをすべて紹介します。

⚠ ここで紹介するコマンドは、思考エンジン(やねうら王)をGUIから用いるのではなく、直接思考エンジンをWindowsのエクスプローラーから実行して使う時や、他のプログラムから思考エンジンを呼び出して使う時に用いるコマンドです。GUIから思考エンジンを使っている場合には使えません。

setoption簡略表現

USIでは、エンジンオプションをsetoptionというコマンドで設定します。

💡 エンジンオプションの一覧とその説明は、思考エンジンオプションにあります。

通常のsetoptionは

setoption name オプション名 value 設定したい値

のようにして設定します。

👉 Threadsというエンジンオプションを1に設定する場合なら、

setoption name Threads value 1

こう書きます。

ところが、こう書くのは、わりと面倒なので、この簡略表記としてやねうら王では、

Threads 1

と書くことができます。

🖋 setoptionの簡略表現として、エンジン名と設定したい値をスペースで区切って書けるということです。

USIのコマンドを拡張したもの

USIプロトコルで規定されているコマンド機能を拡張しています。 以下は、元あったものを拡張しているコマンドの説明です。

go

goコマンド(探索を開始するコマンド)が通常のUSIプロトコルからいくつかの点で拡張されています。

go depth 6

depth指定での思考。depth(探索深さ)が6になるまで探索をします。 探索深さは、エンジンオプションのDepthLimitでも指定できます。

go nodes 10000

探索node数を指定して思考します。あまり厳密にこのノード数を守るわけではありません。(探索ノード数をチェックする間隔が甘いので)

探索ノード数は、エンジンオプションのNodesLimitでも指定できます。

go movetime 100

1手の持ち時間固定のオプション。この場合、1手100 ms。

⚠ GUI側が普通対応していません。

💡 上記のgo depthとgo nodes、go movetimeは、USIプロトコルの原案となったUCIプロトコル(チェスの思考エンジン用のプロトコル)には存在します。将棋所は対応していません。ShogiGUIでは対応しているはず。

go rtime 100

今回の思考時間として、100~300 ms(ミリ秒)を使って思考する。(指定した値と、その3倍の時間との間の時間だけランダムに使う)

🖋 自己対局でレーティングを計測するときに指し手をバラけさせたかったので用意しました。

go perft 【探索させたいdepth】

パフォーマンステスト。perftはperformance testの略。

現在の局面(positionコマンドで与えられる)から深さdepthまで全合法手で進めるときの総node数を数えあげる。depthとして1以上の値を指定すること。positionコマンドと組み合わせて使う。

例) 初期局面から10手先に至るまでの全合法手の数を数え上げる。
position startpos
go perft 10

⚠ このperftは、ベンチマークの一種ですが、評価関数や通常探索部を用いないため、合法手の生成と局面を1手進める/戻すような速度を競うベンチマークにしかなっていません。

ponderhit

やねうら王では、"ponderhit"コマンドがGUI側から送られてきた時に、goコマンド同様に残り時間等を受け取れるようにUSIプロトコルを拡張しています。(従来通り、何も指定せずに"ponderhit"だけを送ることも可能)

具体的には、ponderhitの時にbtime,wtime,winc,binc,byoyomiを指定できます。

これによりgo ponder (残りパラメーターなし)でとりあえずponderさせといて、ponderhitで残り時間を渡すような方法が採れる。

これは、MultiPonder/PrePonderの実装などに使えます。

🕊 ponderhitコマンド時に、goコマンド同様に残り時間等を指定できるように拡張

例)
ponderhit btime 100000 wtime 100000 winc 5000 binc 5000

USIプロトコルに新たに追加したコマンド

USIプロトコルのコマンドだけでは足りないので、やねうら王では役に立つコマンドをいくつか独自に追加しています。以下は、そのような独自に追加されたコマンドの説明です。

getoption

setoptionの逆。オプション名を指定して、その現在の値を取得する。

使い方)
getoption [オプション名]

オプション名は大文字小文字の違いは無視します。 オプション名を省略するとすべてのオプション項目の現在の値を出力します。

setoptionできちんと設定できているかなどを確認したい時に用います。

compiler

コンパイルに使用したコンパイラ情報が表示される。

💡 このコマンドはStockfishに存在します。Stockfishを参考にして書かれている将棋ソフトだと使える可能性大。

config

config.hで設定した値などについて出力します。

思考エンジンの実行ファイルがどういう設定でコンパイルされているかを調べたい時に使います。

log

このコマンドを実行すると、そこ以降のGUI側とのやりとりをファイル"io_log.txt"に書き出します。

💡 このコマンドはStockfishに存在します。Stockfishを参考にして書かれている将棋ソフトだと使える可能性大。

💡 GUI側とのやりとりを起動時からすべて書き出したいのであれば、エンジンオプションのWriteDebugLogを用いると良いでしょう。

bench

ベンチマーク用のコマンド。

💡 このコマンドはStockfishに存在します。Stockfishを参考にして書かれている将棋ソフトだと使える可能性大。

書式)
bench 【置換表サイズ】 【スレッド数】 【LimitTypeの設定値】 【局面の指定】 【LimitType】
  • 置換表サイズはMB(メガバイト)単位で指定します。

  • スレッド数は並列で思考させたい数。

  • LimitTypeは、何で制限するか。"depth"(深さ),"nodes"(探索ノード数),"time"(時間)のいずれか。

  • 【局面の指定】は、"default"=デフォルトの局面、"current"=現在の局面、それ以外 = ファイル名とみなしてそのsfenファイルを読み込む。

この時のファイルの内部形式はテキストファイルで、その書式は、positionコマンドの、"position"より右側の羅列。

例)
    sfen XXX
    startpos
    startpos moves XXX XXX ...
例)
    bench 1024 1 10 default depth
    ※ パラメーター省略時は上記の設定

    置換表サイズ 1024 MB
    スレッド数 1
    制限 : depth(深さ) 10
    局面 : default(最初から備わっている4局面)

⚠ ふかうら王は、LimitType == depthは非対応。

例) 1024MB USI_Hash , 1スレッド , デフォルト局面 , 深さ10で探索したい場合。
    bench 1024 1 10 default depth
例) 1024MB USI_Hash , 1スレッド , デフォルト局面 , 10万ノードまで探索したい場合。
	bench 1024 1 100000 default nodes

💡 やねうら王の独自拡張として、以下のように引数名を指定できます。

例)
	bench 1024 4 3000 default nodes
	↓こう書けます。
	benchmark hash 1024 threads 4 limit 3000 type nodes file sfen.txt
例)
特定の引数だけ変更できる。

	benchmark type nodes limit 3000
	// 3000 nodesで探索

benchコマンドで集計の時の表示について。

⚠ NNUE系とふかうら王とでは計測する基準が異なるので注意すること。

nodes_searched :
	探索したノード数。局面を進めた回数。
	(Position::do_move()の呼び出し回数)

nodes_visited :
	局面を評価した回数。(evaluate()を呼び出した回数)
	// nodes_visitedが出力されるのはいまのところふかうら王だけです。

f

テキストファイルからUSIコマンドを読み込み、それを入力したかのように扱う。

例えば

f 1

とすると、"1.txt"というUSIコマンドが書かれたファイルの内容を実行します。 ファイルのなかにはコマンドが複数書かれていても構いません。

💡 コマンド名は、fileのfから。

デバッグの時に毎回、"isready","position ...","go ..."のようなものをコピペするのが面倒なので、この機能を用意しました。どんなコマンドにしていたか忘れるので、startup_info.txtにメモを書いておくと良いでしょう。

d

(debugのd) デバッグ用に現在の局面を表示する。

💡 このコマンドはStockfishに存在します。Stockfishを参考にして書かれている将棋ソフトだと使える可能性大。

例
isready ← isreadyで初期化後にしかdコマンドは使えません。
d
^香^桂^銀^金^玉^金^銀^桂^香
 口^飛 口 口 口 口 口^角 口
^歩^歩^歩^歩^歩^歩^歩^歩^歩
 口 口 口 口 口 口 口 口 口
 口 口 口 口 口 口 口 口 口
 口 口 口 口 口 口 口 口 口
 歩 歩 歩 歩 歩 歩 歩 歩 歩
 口 角 口 口 口 口 口 飛 口
 香 桂 銀 金 玉 金 銀 桂 香
先手 手駒 :  , 後手 手駒 :
手番 = 先手
sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1

💡 もし上のように表示されずに文字化けして表示されるとしたら、ターミナルのコードページ(文字のエンコード)がutf-8になっていないからです。

例えば、Windowsのコマンドプロンプトであれば、

chcp 65001

のようにすれば、コードページをutf-8に変更できます。

💡 コンパイルする時に、config.hで以下の行をコメントアウトすれば、このコマンドで局面を表示する時に日本語文字は使いません。

#define PRETTY_JP

sfen

"position sfen"の略として機能する。

"d"コマンドで表示されたsfen文字列をコピペするときに便利。

side

現在の局面の手番を返します。

先手なら "black" 、後手なら "white"と出力されます。

moves

現在の局面の合法手(LEGAL_ALL)をすべて出力します。

💡 出力形式は、USIプロトコルの指し手形式です。

key

現在の局面に対して局面のhash keyを全桁16進数で出力します。

例)
isready
key
> ed019431e97df2a8

eval

現在の局面に対して評価関数を呼び出してその値(評価値)を出力します。

matsuri

指し手生成祭りの局面を現在の局面としてセットする。

💡 指し手生成祭りとは、2014年ぐらいに開発者の間で指し手生成の速度を競うに流行った。その時に用いられていた局面が以下の局面。

position sfen l6nl/5+P1gk/2np1S3/p1p4Pp/3P2Sp1/1PPb2P1P/P5GS1/R8/LN4bKL w GR5pnsg 1

wait

"go"コマンドでの探索終了を待つ。

💡 コマンドラインから"go"コマンドを流す時に便利。 

⚠ このコマンドを実行しても"stop"は送りません。時間が来て探索が終了するのを待機するだけです。

sleep

"quit"の前に一定時間待ちたい時などに用います。

待機時間の指定はms(ミリ秒)単位。

例)
sleep 1000
なら、1秒待ちます。

💡 コマンドラインからコマンドを流して、"quit"の前で待機したい時に便利。 

mated

現在の局面に対して詰み判定を呼び出します。

詰んでいれば1、さもなくば0が出力されます。

mate1

現在の局面に対してmate1ply() (一手詰め判定を行う関数)を呼び出します。

1手詰め判定の外部からの検証やデバッグに用います。

matedebug

MateEngineのデバッグ用コマンドです。

詰将棋の特定の変化に対する解析を効率的に行うことが出来ます。 👉 pull request #115

qsearch

現在の局面に対してLearner::qsearch()(静止探索)を直接呼び出して評価値と読み筋を表示します。

⚠ デバッグ用 , EVAL_LEARNを有効にしてコンパイルした実行ファイルのみ使えます。NNUEのLEARN版など。ふかうら王は不可。

search

現在の局面に対してLearner::search()(通常探索部)を直接呼び出して評価値と読み筋を表示します。

⚠ デバッグ用 , EVAL_LEARNを有効にしてコンパイルした実行ファイルのみ使えます。NNUEのLEARN版など。ふかうら王は不可。

unittest

UnitTest用のコマンドです。(開発用)

やねうら王の各モジュール(指し手生成や、局面管理classなど)に対して、モジュール単位でのテストを実施します。

何かやねうら王の基本的な部分を書き換えた時に、機能を壊していないかを調べることができます。

makebook

定跡関係のコマンドです。

定跡の生成、マージ、局面の抽出など、定跡に関するさまざまなことができます。

👉 詳しくは、定跡の作成をご覧ください。

test

test用のコマンドです。(開発用)

⚠  testコマンドは実験的に実装してあるコマンドで、突然無くなることがあります。

test genmoves

指し手生成のスピードテストを行ないます。王手がかかっているときはEVASIONS(王手の回避手のみの生成ルーチン),かかっていないときはNON_EVASIONS(王手のかかっていない時の指し手生成ルーチン)を用います。

    loop X : 繰り返す回数X

    例)
    isready
    position sfen l6nl/5+P1gk/2np1S3/p1p4Pp/3P2Sp1/1PPb2P1P/P5GS1/R8/LN4bKL w GR5pnsg 1
    test genmoves
    // positionコマンドはisreadyしてからでないと使えないのでisreadyを入れてからpositionコマンドを
    // 送って、そのあとにtest genmovesを実行する。

    // ↓のような結果が返ってくる。
    sfen l6nl/5+P1gk/2np1S3/p1p4Pp/3P2Sp1/1PPb2P1P/P5GS1/R8/LN4bKL w RGgsn5p 1
    1d1e 2e2f 6c6d 7d7e 9d9e 9a9b 9a9c 2a1c 2a3c 7c6e 7c8e 3i1g+ 3i2h+ 3i4h+ 3i5g+ 6f4h+ 6f5g+ 6f7g+ 6f8h+ 6f9i+ 6f3c 6f4d 6f5e 6f7e 6f8d 6f9c 1b1c 1b2c 2b1c 2b2c 2b3b 2b3c P*3a P*3b P*3c P*3d P*3h P*4a P*4d P*4e P*4f P*4g P*4h P*5a P*5b P*5c P*5d P*5e P*5f P*5g P*5h P*8a P*8b P*8c P*8d P*8e P*8g P*8h S*4i G*4i S*5i G*5i S*6i G*6i S*7i G*7i S*1h G*1h S*2h G*2h S*3h G*3h S*4h G*4h S*5h G*5h S*6h G*6h S*7h G*7h S*8h G*8h N*1c S*1c G*1c N*1e S*1e G*1e N*1g S*1g G*1g N*2c S*2c G*2c N*2f S*2f G*2f N*3a S*3a G*3a N*3b S*3b G*3b N*3c S*3c G*3c N*3d S*3d G*3d N*4a S*4a G*4a N*4d S*4d G*4d N*4e S*4e G*4e N*4f S*4f G*4f N*4g S*4g G*4g N*5a S*5a G*5a N*5b S*5b G*5b N*5c S*5c G*5c N*5d S*5d G*5d N*5e S*5e G*5e N*5f S*5f G*5f N*5g S*5g G*5g N*6a S*6a G*6a N*6b S*6b G*6b N*6d S*6d G*6d N*6g S*6g G*6g N*7a S*7a G*7a N*7b S*7b G*7b N*7e S*7e G*7e N*7g S*7g G*7g N*8a S*8a G*8a N*8b S*8b G*8b N*8c S*8c G*8c N*8d S*8d G*8d N*8e S*8e G*8e N*8g S*8g G*8g N*9b S*9b G*9b N*9c S*9c G*9c N*9e S*9e G*9e N*9f S*9f G*9f
    2957121 times per second.

test autoplay

自己対局テストコマンドです。探索部や指し手生成にバグがないかを調べる時に用います。

    // ASSERT_LV 5とかに設定してコンパイルして、連続自己対局させれば、探索や指し手生成のバグがあれば
    // どこかでASSERTに引っかかるという考え。

    loop X     : 連続自己対局の回数X
    movetime N : 1手あたりの思考時間がN[ms]になる。default 100[ms]
    verbose    : 詳細な出力。対局棋譜を"position startpos moves ..."の形式で出力する。
    nodes N    : 1手あたりのノード数。default 0(制限なし)。

    勝敗の出力
        B  先手勝ち
        b  先手宣言勝ち
        W  後手勝ち
        w  後手宣言勝ち
        .  引き分け
        M  最大手数(512手)に到達

test evalsave

現在の評価関数パラメーターを保存します。

⚠ このコマンドはLEARN版でないと使えません。

このコマンドを用いた応用例として、ゼロ初期化された評価関数ファイルを作るというのがあります。