Bonanzaの駒の価値はどこに書かれているのか その5
それでは、make_moveでいつ駒割が変動するか考えてみましょう。
指し手を大別すると次の4つに分類されます。
1. 駒を取らない、成らない移動
2. 駒を取らない、成る移動
3. 駒を取る、成らない移動
4. 駒を取る、成る移動
1.は駒割は変動しません。
2.は、成り駒と非成り駒との価値の差の分だけ増えます。
これこそがp_value_pmであり、MT_PRO_XXX マクロが使えることはすでに説明しました。
3.は、相手の駒を自分の手駒にするのですから、交換値(駒の価値の2倍)の分だけ変動します。
これはp_value_exであり、MT_CAP_XXX マクロが使えることはすでに説明しました。
4. は、2.と3.の合わせ技ですね。
結局、make_moveのときは、MT_PRO_XXXとMT_CAP_XXXだけあればいいことがわかりました。
また、unmake_moveのときにこの逆の操作をしても良いのですが、探索時にmake_moveした場合はほぼ必ずunmake_moveで元の局面に戻ってきますから、make_moveする前の駒割の値をどこかに保存しておき、unmake_moveのときにはそれを復元することが考えられます。
駒割を保存するなら、それは探索深さごとに保存してやる必要があります。Bonanzaでは次のような配列を用意して現在の探索深さのところに保存してやる実装になっています。
// 駒割保存用の配列 shogi.h(735): short save_material[ PLY_MAX ]; // make_moveのときに駒割の値を保存する処理 makemove.c(70): ptree->save_material[ply] = (short)MATERIAL; // unmake_moveのときに元の値に戻す処理 unmake.c(29): MATERIAL = ptree->save_material[ply];
また、ここに出てきたMATERIALというマクロは、次のように定義されていて、実体は探索木(treeというstruct)のメンバー変数materialです。
shogi.h(173): #define MATERIAL (ptree->posi.material) shogi.h(658): int material;
このmaterialの型はintになっていて、save_materialのほうはshortの配列となっていますが、これについてはまたの機会に。