探索木のvalidatorを書こう!! その1

Bonanzaのコードに致命的なバグが少ないのは、探索木のvalidatorがあることが理由に挙げられると思います。ここで言うvalidatorとは、正当性(状態が正しいかどうか)をチェックする関数のことです。


探索木で言えば、
・敵陣の1段目に成っていない歩・香が無いか
・敵陣の2段目に成っていない桂が無いか
・Bitboardの使っていないはずのbitが1になっていないか
・冗長に持っているbitboardの整合性
例) bb_hdk(馬+龍+王の場所を合成したBitboard)は本当に馬+龍+王になっているか
・ハッシュの値は正しい値か?
・駒割(MATERIAL)の値は正しい値か?
などです。


ハッシュと駒割については、実際の探索ではmake_move(指し手を進める)のときに差分計算していきますので、make_moveのどこかのコードにバグがあるとおかしい値になることがあるわけで、これをチェックすることによってそれを検出することが出来ます。


以前、Bonanza 4.1.2の3手詰め関数の改善案を私が保木さんにメールしたとき、保木さんは、その改善案を実際に実装して、実際に何度も対戦させてみて(もちろん対戦自体は自動化されている)、おかしい局面にならないかをvalidatorで調べて、そうしてその改善案が正しいらしきことを確信した上でBonanza 4.1.3に反映されました。


このことは非常に教訓的で、あるアイデアが正しいかどうかを試すときや、バグがないかを検出するためにvalidatorは非常に強力な役割を果たします。


バグの多い人のプログラムはassert自体が書かれていなかったり、validatorを書いていなかったり、UnitTestを省略していたりする傾向があります。まあ、コンピューター将棋では実際に探索しているうちに見つかるエラーが多いので、UnitTestはあまり意味がないかも知れませんが…。


それでは、どのようなvalidatorを書いていけばいいのかをBonanzaのvalid.cを見ながら具体的に考えてみましょう。


つづく