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

今回はexam_bb(debug.cのなかに書かれている)を見ていきます。

exam_bbのbbとはBitboardのことで、Bonanzaの保持しているBitboard盤面の正当性をチェックする関数です。


チェックしている項目は以下のものです。
1) 手番が0か1であること
2) 持ち駒の使っていないビットが0であること
3) 盤面を表現するBitboardにおいて、使っていないビットが0であること
4) 先手の歩が1段目(後手なら9段目)にないこと
5) 先手の桂が1,2段目(後手なら8,9段目)にないこと
6) 駒数のチェック。盤上のX + 手駒のX = 駒Xの最大数 - 駒箱のなかのX が成り立つか。
7) 冗長に持っているBitboardの内容が正しいか。例えば、BB_HDK(馬+龍+王のBitboard)は、それぞれのBitboardを合成(bitwise or)したものに等しいか。
8) Board[sq] (81マスそれぞれの駒を格納している配列)の値は、Bitboardの内容と矛盾していないか。
9) 駒割が正しいか。
10) 局面のハッシュ値は正しいか。



4),5)だと香が1段目(後手なら9段目)にないかというチェックが抜けているようですが、実際抜けています。書き忘れだと思います。


6)は、次のように書かれていて、PopuCount(1になっているbitの数を数える)を使ってあるのでそこそこ高速です。このようにexam_bbはそこそこ高速性を意識した書き方になっていて、デバッグ時に、全探索ノードから呼び出すことも視野に入っています。

  /* number of pieces */
  BBOr( bb, BB_BPAWN, BB_WPAWN );
  BBOr( bb, BB_BPRO_PAWN, bb );
  BBOr( bb, BB_WPRO_PAWN, bb );
  npawn = I2HandPawn(HAND_B) + I2HandPawn(HAND_W) + PopuCount(bb);
  CheckNum( pawn );

9)の駒割は、Bonanzaではmake_moveのときについでに駒割も差分更新しているので、9)では駒割を再計算したものと一致するかを確認しています。10)についても同様です。

exam_bbで行なっている処理は以上ですべてです。


さて問題。


配列 Board[sq] 上に先手玉が二つあるとき、1)〜10)のどのチェックに引っかかるでしょうか。