将棋ぶらうざQで対局をしてみた
Gyazoというサービスがあるのでそれを使って対局の模様をGIFアニメにしてみた。
(このサービスすぐアップロードしてくれて便利。)
将棋ぶらうざQはGUIの完成度は高いし、Haskellの将棋プログラムも動かすことができたので、これで開発に専念できそうだ。
Haskell将棋の外観
第21回世界コンピュータ将棋選手権のアピール文書用のプログラム - ながとダイアリーをベースに書かれたHaskell将棋は今のところこのリンク先に掲載されているコードを整形してモジュールに分離して少々のリントエラーを修正した程度なので、ほぼロジックはいじっていない。 ロジックのコーディングに入る前に外観を捉えておこうと思う。
エントリポイントから順にたどる
プログラムのエントリポイントは当然Main.hsだ。Main.hs
はすぐに制御をUsi.hs
に渡す。ここがmain loopになっている。
usiLoop
という関数がmain loop関数で、positionコマンドでボードを作りgoコマンドで手の探索と評価を始める。
Search.hs
のminmax
関数が探索と評価のエントリポイントになっていて、探索結果とPVを返す。
PVはprincipal variation、主な変化のこと。日本語に直すと「読み筋」といったところか。感覚的には、あらゆる合法手が次の手としては考えられるけど、普通だったらそうはしないよね、というものを除いていった残りというか、普通だったらこう指すよね、というのは主な次の展開、principal variationになる。多分コンピュータチェス用語。
Search.hs
のminmax
がやっているのは引数dep
が0になるまですべての合法手を生成して、その手に対して次の合法手をすべて生成していって、最後にその合法手の末端局面(一番あとの局面の集合)のすべてをeval関数で評価する。
Eval.hs
は局面の評価戦略を実装したモジュール。呼ばれる関数はevalのみ。
evalは
eval :: Board.Bd -> Va eval bd = matVa bd + bonaVa bd
とあるように、小回りの評価とボナンザ評価の足し算になっている。ボナンザ型の評価をするためにfv.binを読み込むことができるようになっている。
小回りの評価関数は
matVa (Board.Bd _ hs co _ pcl) = co == Piece.B |-> negate $ sum [pcVa pc * hs ! pc | pc <- Board.bothHsRa] + sum[pcVa pc * length(pcl ! pc) | pc <- Piece.pcRa] pcVa :: Piece.Pc -> Va pcVa = (!) $ listArray Piece.pcBnd (a ++ negate `fmap` a) where a = [100, 430, 450, 640, 690, 890, 1040, 15000, 420, 530, 540, 670, -1, 1150, 1300, -1]
であり、Piece.hs
には
pcBnd = (Pc B Unp FU, Pc W Pro OU)
とある。ここを読み解くのを次回までの宿題としたい。