前回のオセロをつくる コンピューターをもっと強くするでは、過去に作成したオセロゲームを強くする方法を考えました。相手に角を取られるようなところに置かないようにすることで少しは強くなりました。

今回はもうちょっと改良を加えます。

オセロをつくる コンピューターをもっと強くするのアルゴリズムはコンピュータが発見した複数の候補手のなかから「次のターン」でプレイヤーに角を取られる手は一旦候補から排除したのですが、もっと先を読ませます。「次のターン」だけでなく「さらに次のターン」でプレイヤーに角を取られる場合がないかも考えます。もっと数手先も読ませてみたいんですよね。

それからコンピュータの手番で角を取れるときは角をとります。とはいえ実際にはオセロは角さえとってしまえば勝てるという単純なゲームではありません。「オセロはルールを覚えるのにかかる時間は1分、極めるまでにかかる時間は一生」といわれています。単純なルールであるがゆえに奥が深いゲームなのです。

でははじめてみましょう。基本的にオセロをつくる コンピューターをもっと強くするにかかれているコードを手直してつくります。

そして手直しする部分といえばコンピュータが次の一手を考える部分、EnemyThink()メソッドです。長くなってしまったので機能ごとに分割しました。

やっていることは「もし角を取れるのであれば角をとる」。そして前回同様にコンピュータは角を取られない場所を探して着手するのですが、さらにもう一手余分に読むことにしました。

ある本に関数は50行内にまとめよ、100行を超えたら恥ずかしいと思え、と書いていたのですが、あれこれ付け加えて100行を超えてしまい、以下のコードも50行をちょっと超えてしまいました(説明のためのコメントを消せば50行以内におさまっているからいいかな)。

コンピュータに角をとれるときは角をとらせるための処理を示します。四隅に置いてみてひっくり返せる石があるかどうかを調べています。そして複数の角を取れるときはひっくり返せる石が多いほうを選んでいます。

自分の手番なら角を取れるかだけなら以下のように短く書けます。

試しに石を置くときの処理です。何回も使うのでメソッドとして独立させました。

これが本日の主役である角を取らせないように石を置く場所を調べるメソッドです。コンピュータが着手したあとだけでなく、そのあとプレイヤーがどこかに着手した場合、どうやってもコンピュータが角を取られてしまう場合を事前に見つけ出して候補手からはずしています。

さらにもうひとつ深く読みを入れたいのですが、組み合わせ爆発がおきるからなのか極端に処理が遅くなってしまうので、ここで読みを打ち切っています。

読みの結果、どうやっても角を取られる場合は適当に選びます。

最後にコンピュータが着手したあとプレイヤーの手番になるのですが、ほんとうにプレイヤーの次の手は存在するのかと双方がパスをしてゲーム終了になるときの判定をする処理を示します。

実際にやってみると最初より強くなり負かされることも多くなりました。私が下手なだけかもしれませんが・・・・