終章 残された課題とヒント

さて、一通りプログラムが出来たわけだが、感想はどうだろうか。おそらく、不満な点がいっぱいあるはずである。また、そうであってほしいと筆者は願っている。

とりあえず、これから強くするためのヒントを筆者の分かる範囲でいろいろと書いてみる。

評価関数の問題

まず、駒得を中心にした評価関数と、その問題点である。これには、以下のようなものが挙げられる。

・終盤で、と金や飛車角がそっぽに行って駒得を図る手
・そっぽに金を打ったりして、桂馬や香車など守る手

これは、はっきり言って「評価関数を根本的に直す」「読みを非常に深くする」「そもそもそんな手は読まない」などの対策をしないとどうすることもできない。

評価関数で評価しているのが駒得中心なのが問題なのである。評価関数の形を、たとえば、「(駒得)×(序盤度)+(駒の働き)×(中盤度)+(攻め駒・守り駒の働き)×(終盤度)」のような形に思いっきり変更することなどが考えられる。

もっとも、こうなると、おそらく評価関数を差分で計算するのは難しいので、「駒得」「駒の働き」「攻め駒・守り駒の働き」などだけ差分計算しておき、探索の末端のノードで序盤度・中盤度・終盤度を計算して一気に評価値を決める、などの手法が必要になってくると思う。

「そもそもそんな手は読まない」手法や「読みを深くする」手法については、将棋プログラム「激指」の方法が参考になる。

これは、「実現確率に基づく探索」という方法で、最近多くのプログラムで採用されている、ある意味、流行になっている方法である。

大雑把に説明すると、探索の深さを固定せず、ある局面である指し手が指される確率を事前に求めておき、その確率を掛け算していって、ある値以下になるまで探索する、という方法である。

これによって、「ありそうな指し手は深く読む」「なさそうな指し手は浅くしか読まない」ということが起きる。実際には、「なさそうな指し手が高い評価を返してくるときには、その指し手をさらに深く読んでみる」などの工夫が必要になってくる。

この手法については、「激指」のホームページ「コンピュータ将棋の進歩4」(共立出版)などを参照して、理解を深めてみてほしい。

序盤の問題

次に、序盤の下手さ加減に対する対処であるが、たとえば拙作の「うさぴょん」では、以下のような方法をとっている。

盤面を「5×9」の領域(「右半分」「下半分」「左半分」「上半分」のように)に分けてしまう。先手なら、「左半分」「右半分」「下半分」が一致しているなら、そこで定跡データで指された指し手にボーナスを与えて先読みをしてみる。

どうしても大差がつかないような局面であれば、定跡データ中で指された指し手にボーナスを与えているため、定跡データにある指し手が優先的に指されるという仕掛けである。

さらに、うさぴょんでは、玉の周り「5×5」の領域を見て、囲いの形を作成するなどの工夫も行なっている。

本文中でも示したが、序盤定跡データを工夫し、序盤で定跡から外れた際に、その定跡での戦形をきちんと把握できるように序盤定跡データ中にデータをもたせておき、「対四間飛車4三銀型」「対四間飛車3二銀型」などなど、データの多さとそれに対応する駒組み表をたくさんもたせる方法で解決するという方法もある。

また、序盤では、「四間飛車に特化する」「三間飛車穴熊にいつも組む」「居飛車しか指さない」「相手が居飛車なら必ず振り飛車、相手が振り飛車なら必ず居飛車」などの決め打ちも有効になる(現実的な問題として、「戦法を決め打ってしまえば、より細かい駒組みデータを同じ手間でもたせることができる」ということもある)。

2015年 10月 追記:機械学習により、大量の棋譜から評価関数を作成できるようになったため、「評価関数の問題」「序盤の問題」共にある程度解決されている。

詰め将棋の強化

「詰め将棋ルーチン」だが、現在では手数による反復深化に変わり、「証明数」という概念を用いた反復深化が主流である。

証明数を用いた反復深化については、「背尾のアルゴリズム」、さらに反証明数を用いた反復深化として、PDSや「コンピュータ将棋の進歩4」では「df-pn」などが提案されている。これらのアルゴリズムにより、いまや600手長の詰め将棋でも5分もあれば回答が得られるようになってきている(手数による反復深化では、とても及ばない世界である)。

さらに、「詰め将棋ルーチン」では、「ハッシュ値」を積極的に利用することで、「類似局面では同じ手順で詰む」ことを利用した、高速な「詰めろ逃れ判定」も提案されている。

これは、詰むことが分かっている局面の最初のハッシュ値を記憶しておき、現在の局面のハッシュ値と「XOR」(排他的論理和)をとった値をヒント変数として使う方法である。

詰める側の局面で、「ヒント変数」と何手か進めていった現在の局面の「ハッシュ値」でXORをとり、詰め将棋の局面表を引くと、先ほど詰めた際の詰めた手が記憶されているため、何もヒントがないよりも高速に詰め将棋を解くことができる、という方法である。実装の詳細は考えてみてほしい(これは、実際に、「うさぴょん」のソースにも実装されているので、参照してみるのもよいだろう)。

2015年 10月 追記:うさぴょんでの実験では、ヒントの効果は限定的だった…orz

水平線効果対策

最後になったが、「水平線効果」は対策がいちばん難しい。結局、水平線効果は、「水平線効果が起きていることをコンピュータに理解させる」ことで対策するかない。

そのための方法の一つとしては、水平線効果が起きていると思しき怪しい局面で、深さを2手余分に読むことで(読みの量が膨大になるが)、水平線効果を起こした手順が実際の手順より損をしているという結果を得る方法(「うさぴょん」ではこれを実装している)や、ハッシュ値を利用することで、最善手順を局面表から得て、水平線効果と思しき手を指した後、最善手順で進めたときに評価値が下がっていることを確認してみる方法、などが提案されている。

本書のプログラムでも、改良の余地は残っている。たとえば、「ただで取られる駒を打ったときは読みを2手延長する」「ただで取られる位置に駒を進めたときも、読みを2手延長する」ような処理を追加すると、見違えるように効果があるはずである(ただし、読みが多くなるぶん、遅くなるので、良し悪しについてはよくバランスを考えてほしい)。


結び

筆者から読者に伝えられることは、これですべて伝えた。

2015年 10月 追記:現在では、BitBoardとか、機械学習とかも教えられる?レベルにあるかも知れない…。実装は出来るんだけど、教えられるかなぁ…。

これに加えて、本文中の「参考文献」「参考URL」、「うさぴょんのソース」などをあたれば、少なくとも、「うさぴょん」と同じかそれ以上のプログラムを作るだけの知識を読者は得られるはずである。

世界コンピュータ将棋選手権で読者のプログラムにお会いできることを楽しみにしている。


前ページ
付録:CSAプロトコルによる通信
索引ページへ