Hayanagi は、C++17 で実装した USI プロトコル対応の最小構成将棋エンジンです。
- USI の
id nameはHayanagi - CMake の生成実行ファイル名は
hayanagi - 合法手生成、終局判定、基本的な探索、
bench/perftをひととおり実装
GitHub 上で読みやすいように、ビルド手順と実装範囲を先にまとめています。内部構成の詳細は後半に記載しています。
- CMake 3.16 以上
- C++17 対応コンパイラ
- GCC / Clang / MSVC を想定
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build生成物は build/hayanagi に出力されます。
./build/hayanagiusi
isready
usinewgame
position startpos
perft depth 2 divide
bench nodes 10000
go nodes 5000
quit
usi に対しては少なくとも次のように応答します。
id name Hayanagi
id author OpenAI
option name MultiPV type spin default 1 min 1 max 32
option name Threads type spin default 1 min 1 max 128
usiok
- 成り
- 打ち駒
- 二歩
- 行き所のない駒の打ち / 移動の禁止
- 打ち歩詰めの禁止
- 王手回避、両王手、ピンされた駒の移動制限を直接生成
- 千日手
- 連続王手の千日手
- 持将棋の点数判定
- 手数上限による引き分け判定(
MaxMovesToDraw) - 入玉ルール切り替え(
EnteringKingRule)
usiisreadyusinewgameposition startpos moves ...position sfen ... moves ...go depth Ngo movetime Ngo nodes Ngo ponder ...go wtime ... btime ... byoyomi ...setoption name USI_OwnBook value <bool>setoption name BookDir value <path>setoption name BookFile value <file>setoption name USI_Ponder value <bool>setoption name MultiPV value Nsetoption name Threads value Nsetoption name MinimumThinkingTime value Nsetoption name NetworkDelay value Nsetoption name NetworkDelay2 value Nsetoption name SlowMover value Nsetoption name ResignValue value Nsetoption name MaxMovesToDraw value Nsetoption name EnteringKingRule value <rule>setoption name GenerateAllLegalMoves value <bool>stopponderhitquitbench depth Nbench nodes Nbench current depth Nperft Nperft depth N divide
実装済みの主要オプションは次のとおりです。
USI_OwnBookBookDirBookFileMultiPVThreadsHashUSI_PonderMinimumThinkingTimeNetworkDelayNetworkDelay2SlowMoverResignValueMaxMovesToDrawEnteringKingRuleGenerateAllLegalMoves
USI_OwnBook を有効にすると(デフォルトで有効)、go 時に定跡ファイルを参照し、現局面にヒットすれば探索せずに定跡手を返します。定跡ファイルはやねうら王の DB2016 フォーマット(#YANEURAOU-DB2016 1.00)に対応しています。BookDir で定跡フォルダ(デフォルトは実行ファイルからの相対パス book)、BookFile で定跡ファイル名(デフォルトは standard_book.db)を指定します。BookFile に no_book を指定すると定跡を無効にできます。
MultiPV を有効にすると、info ... multipv N pv ... を順位ごとに出力します。GenerateAllLegalMoves は互換性維持のため残していますが、現在は探索強度を落とさないよう no-op です。
通常探索の info には depth / score cp / nodes / time / nps / pv を出力します。
USI_Ponder を有効にすると、通常探索の bestmove は bestmove <move> ponder <move> を返します。go ponder で始めた探索は ponderhit または stop を受けるまで bestmove を返しません。
- 9x9 盤面、持ち駒、手番を保持します。
startpos/sfenの読み込み、USI 指し手の適用、合法手生成を担当します。- 盤面配列に加えて色別・駒種別ビットボードを持ち、王手検出、ピン判定、合法手生成をビットボード主導で行います。
- 玉の回避手、単王手時の合駒・駒取り制限、ピンされた駒の移動制限を、局面全体の後段フィルタではなく直接生成で処理します。
- 1 手ごとの合法性確認で局面コピーを多用しないよう、玉移動の被攻撃判定は専用の軽量経路に分けています。
- 反復深化付きの
negamax + alpha-beta探索を行います。 Threads > 1のときは root move 単位で並列探索します。Hashオプションでサイズ変更できる lockless 共有置換表、PVS、quiescence search、SEE ベースの着手順序、killer/history heuristic、LMR、null-move pruning を使って探索効率を上げています。- 短手数の詰みは専用の王手限定探索で先に検出します。
- 評価関数は駒得に加え、駒の前進度、利きの広さ、敵陣進出、手駒価値、玉の安全度を見ます。
- やねうら王の定跡フォーマット(
#YANEURAOU-DB2016 1.00)を読み込みます。 - SFEN 文字列をキーとして定跡手を検索します。
usi/isready/position/go/stop/quitを処理します。- 探索はワーカースレッドで実行し、
stopに反応できる構成にしています。 isready時に定跡ファイルを読み込み、go時に定跡を参照します。benchとperftを内蔵しており、GUI 接続前の自己確認にも使えます。
- 探索は最小構成で、評価関数も簡易です。
- USI には引き分けを返す専用の
bestmoveがないため、千日手・持将棋など現在局面でゲーム終了と判定した場合はinfo string terminal ...を出した上でbestmove resignを返します。 perftはnodesに加えてcaptures/promotions/checks/matesを出力します。benchは各局面と合計についてnodes/time/nps/hashfullを出力し、nodes N指定で固定ノード数ベンチとして使えます。