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

少し話が脱線してしまいました。


だいたいにして、大学の輪講や、勉強会なんかでは1時間ぐらいでやっちゃうようなことをこのブログでは10回ぐらいに細切れに分けてお送りしております。スローペースすぎてすみません。


毎日10分〜15分程度、こうやって少しずつ記事を書くことによって私は自分のコンピューター将棋開発のためのモチベーション維持などに役立てております。


原則的にこのブログの記事は書きなぐり状態なので読み返してもいませんし、誤字脱字はもとより、内容的な間違いも多々あるでしょうけども、まあ誰かのお役に立てていればと思い、公開しています。(内容的な間違いはコメント欄で教えていただけると幸いです。)



それでは今回はexam_tree (valid.cのなかに書かれています) 関数をざっと見ていきます。


この関数は、探索木の正当性をチェックするための関数です。


駒の枚数を数えたりするのですが、飛車のトータルの枚数は2とは限りません。飛車落ちのような場合1になります。足りない1枚はどこに行くのかというと、駒箱であります。


ということは、駒落ちに対してもきちんと正当性をチェックする関数を書こうと思うと、盤面の初期化時に事前に手合いを確認して、駒箱に何枚の駒が入っているのかをカウントして記録しておく必要があります。

npawn_max ← 駒箱の駒を含めた歩の枚数(4)
npawn_box ← 現在、駒箱に入っている歩の枚数


※ "pawn"のところには、駒の名前が入ります。銀ならsilver、金ならgoldと言った感じです。

盤面初期化時(ini.c)にて、npawn_boxを更新しているのは、そういう理由によるものです。


しかしexam_treeのほうでは、アバウトなチェックしか行なっていません。これは先にも申しましたように、exam_bbのほうが指し手生成などのバグをチェックするためのvalidatorで、exam_treeは、外部から読み込んだファイルなど、外部要因による不正な盤面をチェックするためのvalidatorという性格から来るものだと思います。


よって、exam_treeのほうでは、npawn_maxを超えていないことはチェックするのですが、そのときnpawn_boxは考慮されていません。つまり飛車落ちで飛車が2枚あっても、exam_treeのチェックには引っかからないということです。


あとnpawn_boxはグローバル変数になっています。


本当は、ここをグローバル変数にしてしまうと思考ルーチンを複数同じプロセス空間で走らせるときに問題になったりするのですが、「まあそんなことはしないからどうでもいいや」ということなんだと思います。気になる人は、Treeクラスに含めればいいと思いますが、その分速度が犠牲になります。


私はnpawn_boxなどは盤面クラスのメンバー変数に持たせていますが、リリース時には、その部分のコードはコメントアウトされるように #ifdef で書いています。


ともかくexam_treeで行なっているチェックは
1) 手駒の歩+盤上の歩が npawn_maxを超えないか。
というようなチェックをそれぞれの駒種に対して。
2) 2歩になっていないか。
3) 行き場のないところに駒がないか。1段目の歩、1,2段目の不成の桂
4) 手番側が相手の玉を取れる(直前の指し手が非合法手であったということになる)
の4つです。


また、exam_treeは探索中に呼び出すためのものではなく、局面読み込み時にしか呼び出してありません。


デバッグしたいときにexam_treeを明示的に呼び出すことはあるとは思うのですが、しかし上記4)のチェックのために次のコードが書かれていて、

  if ( InCheck( Flip(root_turn) ) )
    {
      str_error = str_king_hang;
      return -2;
    }

このコードですと、root_turnは探索開始局面を意味しますから、root_turnが適切に設定されている状況、すなわち、探索開始局面からしか呼び出せないことになります。(探索中は、Bonanzaは明示的には手番を持っておらず、先手用のコードと後手用のコードが分かれているので現在プログラムのどこを走っているかという状態が、現在の探索ノードの手番を表現していることになります。)


もし探索ノードでのデバッグのためにexam_treeを呼び出したいならば、
1) exam_treeを先手用と後手用のコードを用意するか
2) root_turnを一時的に書き換えてからexam_treeを呼び出すか
3) あるいはexam_bbで我慢するか
という3択になります。


まあ… 3) で我慢してください。だいたいはそれで事足ります。


exam_treeの解説は以上ですべてです。

次回はexam_bbの解説をします。