CSA形式のデータ読み込み部 解説 その1

今回からBonanzaのCSA形式のデータ読み込み部を解説していきます。


CSA形式のデータをファイルから読み込むとき、それは単なる局面図とき限らず、指し手をともなっており、局面が変化していきます。


そこでCSA形式のデータを読み込むためには、
1) 初期局面を読み込む
2) 指し手を1手進めて盤面を変化させる操作子
が必要になります。


2)のためには、指し手が合法かどうかを確認する必要があり、そのためには合法であるかを確認する専用のルーチンを用意しても良いのですが(BonanzaにはKillerMoveが合法手かどうかを確認するために、合法かどうかを確認するための関数is_move_validがあります)、BoannzaのCSA読み込み部はBonanzaの開発の初期に作られたもののようで、単にすべての指し手を生成して、そのなかに含まれるかどうかを確認するという方法になっています。


CSAファイルの読み込み自体はそれほどリアルタイム性を問われるものでもないのでこれでも特に問題はありません。


しかし指し手生成のために指し手生成バッファが必要になります。また、Bonanzaでは指し手生成にはBitboardを必要とします。


また、2)のためには、指し手に基づいて盤面を次の局面に出来なくてはなりません。Bonanzaでは、Bitboardに対して指し手を与えて次の局面にするための操作子はありますが、非Bitboardに対して指し手を与えて次の局面にするための操作子は用意されていません。


ゆえに、CSA読み込みのためにはBitboardとBitboardの指し手生成ルーチン一式が必要不可欠であり、また指し手生成には指し手生成バッファが必要になるので、これらすべてをCSA読み込みルーチンの呼び出し側で用意してやる必要があります。


BonanzaでCSAファイルの読み込みのときにTree*(探索木)を渡しているのはそのためです。


仮に、2)の合法手判定にis_move_validを使ったとすればどうでしょう?


このとき、指し手生成を行なう必要がなくなるので指し手生成バッファは不要になります。しかし、is_move_validはBitboardを用いるので、結局、Bitboardで表現された盤面自体は必要です。


つまり、is_move_validに変更すれば少し高速化が図れますが、
1) 依存関係がそれほどすっきりするわけではない
2) そもそもCSA読み込み部にそれほどの速度が要求されるわけではない
ので、この修正をするのはあまり意味のないことかも知れません。


何万棋譜もを繰り返し読み込む必要のある「棋譜からの学習」のときには、もしかしたら効果があるかも知れませんが、そもそも指し手生成は現在のマシンでも秒間100万局面分程度は十分可能ですから、100万手分CSAファイルから局面を読み進めたときに、最大で1秒早くなる程度ですね。1局が平均100手として1万局で100万手。1万局分のファイルを読み込むごとに最大1秒早くなっても…嬉しくありませんね。たぶん。


結果としてCSAの読み込み処理は結構大掛かりな(他のモジュールにかなり依存する)プログラムと言えそうです。ですのでCSA読み込み部分だけをBonanzaからソースを拝借しようと思っても、そう簡単ではないのです。


つづく