以下のドキュメントですが
現状、やねうら王で遊ぼう というコンテンツを確認しつつ備忘やら別途確認な諸々を列挙している所です。
random player
- ランダムプレーヤー大事
- 探索部以外はランダムプレーヤーでテストするべき、とのこと
- CheckInfo について別途掘削
- CheckInfo は StateInfo で保持
ランダムプレーヤーの実装
10 日目 (正確には 9 日目) あたりで一旦止めておいて別途確認なナニを色々穿ってみたいと思います。
pext, popcnt
Bit Manipulation Instruction Sets というナニがある模様。
pext は Parallel bits EXTract らしい。popcnt は POPulation CouNT みたい。たってる bit の数を数えるのかな。CPU な命令らしいのでレジスタ演算なのかどうか。
engine 配下
以下なディレクトリがありました。
- 2016-mid-engine
- classic-engine
- classic-tce-engine
- help-mate-engine
- local-game-server
- mate-engine
- mini-engine
- nano-engine
- nano-plus-engine
- random-player-engine
- user-engine
これ、random-player-engine は 10 日めの例示されたナニですね。
nano-engine
「このあと改造していくためのベースとなる教育的なコードを目指す」とコメントにあります。行数はトータルで 561 行みたい。確認する前に random_player_search.cpp にて実装というか定義されている手続きを以下に列挙しておきます。
- USI::extra_option
- Search::init()
- Search::clear()
- MainThread::think()
- Thread::search()
上記、10 日目に解説があります。それは良いとして nano_search.cpp 確認を。ざくっと見てみたところでは
- 先頭あたりで YaneuraOuNano な namespace 定義
- MovePicker という構造体が定義されている (指し手オーダリング、というコメントあり
- NodeType という enum 定義あり (探索用の定数というコメントあり
- qsearch という手続きなテンプレ定義
- search という手続きなテンプレ定義
- あとは init, clear, think, search の定義という形
なので掘削メインは MainThread::think() の定義ですね。
掘削
なんとなく、な流れを以下に列挙してみます。
- 合法手がない (rootMoves.size() がゼロ値) なら投了
- book から定石な手があるかどうかを確認してあればその手を選択
- 定石な手がなければ指し手を検討
上記三つのブロックで終了な条件にあてはまる場合は ID_END なラベルの goto して bestMove を cout (?) に出力している模様。sync_cout が標準出力にあたるのかどうかも確認必要。
rootMoves
定義は以下らしい。
source/thread.h: std::vector<Search::RootMove> rootMoves;
ええと、RootMove は search.h で定義、なのかな定義な部分のコメントが以下。
// root(探索開始局面)での指し手として使われる。それぞれのroot moveに対して、
// その指し手で進めたときのscore(評価値)とPVを持っている。(PVはfail lowしたときには信用できない)
// scoreはnon-pvの指し手では-VALUE_INFINITEで初期化される。
ええと pv は Move 型の vector みたいなのですが pv て何の略だろ。
と言いつつ
探してたら、Stockfish 完全解析、ってナニがやねうらおさんの所にあるのを発見している次第です。
先にこっち見てみた方が良さげ感ありますね。つうかこれ、chess の実装なのか。