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

is_move_validを見ていて思い出したのですが、以前も少し書いたようにCSA読み込み中で合法手かどうかをテストするためにすべての指し手を生成してそのなかの指し手に含まれるかをチェックしているのですが、あの部分、速度的な観点からは、この is_move_validを呼び出すように変更したほうがいいように思います。


棋譜からの学習のときに何度もCSAファイルから読み込むので棋譜読み込みは少しでも速いほうが嬉しいかも知れませんので。


ところで、Bonanzaの指し手ルーチンは、自殺手も含んでいまして(玉を取られるところに移動させる、ピンされている駒を動かして王手を素抜かれる等)、is_move_validも自殺手でも合法と判定されます。打ち歩詰めは指し手生成のときも除外されていますし、このis_move_validでも打ち歩詰めは不法と判定されます。


killer moveの場合、合法だと判定されれば即座にその指し手で進めることが多いと思うので[要検証]、もしかしたらkiller moveから使う場合は、自殺手はis_move_validのなかで弾いたほうがいいのかも知れません。


ところで、合法な指し手かどうかを正しく判定するルーチンがないとCSA読み込みに使うのはまずいように思えますが、BonanzaのCSA読み込み部では次のようにして解決しています。


1) すべての指し手を生成(自玉に王手がかかっていようと、かかっていまいと。)
2) 棋譜(CSAファイル)の指し手が1)に含まれていなければ打ち歩詰めだったのかも知れないので、棋譜の指し手が敵玉の頭に歩を打つ指し手かどうか確認する。もしそうであれば、打ち歩詰めエラー。
3) 棋譜の指し手が1)に含まれていたので局面をmake_move_root(探索開始局面自体を進めるmake_move)で進める。
4) このmake_move_rootのなかでInCheckという王手がかかっているかを判定する関数を呼び出し、敵の手番なのに敵からの王手がかかっている(=敵にこちらの玉を取られる=直前の指し手は非合法手)ならリタイアする(エラーのため状態を元に戻してリターンすること)ので、CSA読み込み部ではmake_move_rootがリタイアしたならその指し手は不正な指し手であったと知ることが出来ます。


ゆえに、1)ですべての指し手を生成する代わりに、is_move_valid(打ち歩詰めは正しく判定される。自殺手も合法と判定される)で判定しても問題ないはずです。


つづく