sakurapyon’s blog

sakurapyon’s blog

Seeing a Capture と MVV-LVA

sakurapyon-27まで使っていたSEEはchessprogramming - Static Exchange Evaluationにある Seeing a Caputure のような実装でした。ある地点に対して双方が取り合いをするのだけど 「取れる駒は必ず取る」という実装。取るときは価値の小さな駒から使ったりの工夫(将棋プログラムの作り方の「大きい駒を小さい駒で取る手ほど評価が高くする」)はしていたけど、「取れる駒は必ず取る」。
(Seeing is Caputure って Seeing is believing から来てる?)


SEE導入してから、Rが上がって満足してたんだけど、先日、たまたま見た対局のオーダリングが妙なのに気づいた。

こんな局面で8六金打ちに正の評価が付いてる。え? って思ったけど、Seeing is Captureなら当然で、▲8六金打△同歩▲同歩△同飛!▲同銀で、飛車金交換で得、という計算…orz 普通に考えれば△同飛はありえない。先の英語ページにあるように「must not allow the option of standing pat 」なのがまずそう。まずいのは承知の上で速度を取ってるんだけど。

さてどうするか。損する手は指さない(standing patを選ぶ)のが一番マトモ。実はれさぴょんのKyokumen::Eval関数がそうなってる。なので、Evalに戻しても良かったんだけど、試してみるとちょっと重い感じだ。オーダリング部分はノード数*生成した手数だけ回るので、ここが重たくなるとがくんと速度が落ちる(指し手の部分生成するとか、対策はいろいろあると思いますが)。


そもそも、SEEで頑張ってオーダリングしても、本当にその通りに取り合いが進行するかは謎である。先まで探索しないと本当の評価はわからない。ただ、良さそうな手を先に探索したいから近似としてSEEなりなんなりで点数をつけているわけだ。もちろん良い近似であるに越したことはない。だとしたら、ざっくりな近似で軽いものを試してもいいかなと思って、MVV-LVAにしてみた。


chessprogramming - MVV-LVAに書かれてるけど、「Most Valuable Victim - Least Valuable Aggressor」で、価値の高い駒を価値の低い駒で取れ、ということ。角で歩を取る手よりも歩で飛車を取る手を先に読め、というだけの話。桂馬で金を取るのと香車で銀を取るのはどっちがいいのか、とか悩ましいけど、取られる駒の価値が優先っぽい (このへんはいろいろ流儀があるようです)。 今は、素直に「取られる駒の価値-取る駒の価値」を計算してる。
追記:sakurapyonは れさぴょんと同じく利きを持っていますので、相手の利きがない(取り返されない)時は引き算しないようにしています。

ということで、移動する手のオーダリング部分に使ってたSEEをMVV-LVAに置き換えたのがsakurapyon-29。打つ手は上記の問題があるんだけど、MVV-LVAでどう判断すればいいか悩んでてまだ変更してない。オーダリングが軽くなった分だけ多く読めるようになったせいか、元々のSeeing a Captureがまずかったのか、Rは少し上がってるので、これはこれで良しかな?


SEEをマトモにして、指し手の部分生成をするかSEEの遅延評価をするのが本筋だとは思うけど。でも、なんでも試してみるもんだと思いました。