Bonanzaの駒の価値はどこに書かれているのか その4
p_value , p_value_ex , p_value_pmについて一通り説明が終わったところで、これらの変数がどう使われているかについて見ていきましょう。
基本的には、盤面初期化(CSA形式のファイルを読み込んだときや、平手盤面で初期化したときなど)に、ini_game関数(debug.cに書かれています)が呼び出されます。
このini_game関数のなかから、eval_material関数(evaluate.cに書かれています)が呼び出されます。この関数は、盤面の駒の数を数えて、p_valueの値を掛け算することで駒割を計算します。例えば、歩に関する駒割であれば次のように計算してあります。
itemp = PopuCount( BB_BPAWN ) + (int)I2HandPawn( HAND_B ); itemp -= PopuCount( BB_WPAWN ) + (int)I2HandPawn( HAND_W ); material = itemp * p_value[15+pawn];
PopuCountは1になっているbitの数を数える関数です。このブログではおなじみですね。
BB_BPAWNは先手側の歩を表現しているBitboard盤面です。BB_WPAWNは後手側。
HAND_Bは先手の手駒。HAND_Wは後手の手駒。
I2HandPawnは、手駒から歩の枚数を得るマクロです。
ここまで、難しいところはありませんね。
すべての駒種に対してこのような処理をしていけば、現在の盤面の駒割が確定します。これがeval_material関数です。
ところが、探索のときに各ノードでこの関数を呼び出すのはすこぶる無駄なので、Bonanzaでは、探索時にはmake_moveとunmake_moveのときに駒割の差分を計算するようになっています。
つづく