GitHub開発の動機Ruby用のGUI開発ツールShoesを使って一通り機能を備えた将棋ソフトを作ってみたのですが、思っていた以上に弱い。大昔にオセロのソフトを作ったことがあるのですが、min-max法とαβ法を使えば普通の人では勝てないぐらいのものが簡単に作れました。オセロでは四隅を取ると有利になるので、隅のコマは点数を高くして、その隣の位置は点数を低くするという、コマを置く盤面の位置に重み付けすることで局面を評価するよくある評価関数を使えば十分でした。将棋の場合もそれぞれの駒に重み付けをして評価関数を作れば、オセロに比べると読む局面の数が多くなるとはいえ、それなりに強いものが出来ると思っていたのにあまりにも弱かったのです。そこで評価関数は置いといて局面の先読み部分がうまくいってるのか確認するために、まずはより単純なゲームである三目並べで確認しようと思ったのが作成のきっかけです。三目並べ(tictactoe)なら初手からゲーム終了まで読みきれるので先読み関数に問題がないかどうか判断しやすいと思ったからです。endend※min-max法に僅かなコードを追加しただけで素晴らしい効果が得られました。(VGN-P90S)という非力なPCで比較したところ、単なるmin-max法で完全読み切りに30秒ほどかかったのに、αβ法なら5秒で完了しました。評価関数が、勝ち、負け、引き分けの3値しかない単純なものだったせいもありますがすごいです。検証と意外だったこと先読みがうまく機能しているかは、初手をどこに打ってゲーム開始しても引き分けという結果が返ってくることや、先手・後手でそれぞれ何度か三目並べで遊んでみて確認した程度ですが、それで十分でしょう。作ってみて意外だったのは初手から完全読み切りするわけだから、ソフトに初手を指させたら当然真ん中に×をつける(打つ?指す?)と思っていたのに真ん中には打ってこなかったことです。人間ならすぐに一番勝つ可能性が高い真ん中を取るはずですが、ソフトは双方が最善手を指せば引き分けになることを読み切っているので、結局どこに打っても同じと判断するわけです。評価関数が勝ち、負け、引き分けの三値しか返さない関数なので、初手に真ん中に打てばラインを揃える可能性が一番高いとはいえ、引き分けには違いないので区別しないのだと一応納得しました。念の為、真ん中は2点、隅は1点、その他は0点という場所による重み付けをしてその点数による評価関数を作って、それを使えば真ん中に打つことは確認しましたが、そんな評価関数では当然弱いソフトになりました。それ以外にも何とか初手に真ん中を選択しながら、強い評価関数はどうすればいいか考えてみましたが、シンプルでいい方法は思いつきませんでした。結局オセロでも将棋でもそうですが、局面の形成判断をする評価関数と読み切り用の評価関数は分けて作るのがいいのかもしれません。