
マイケル
みなさんこんにちは!
マイケルです!
マイケルです!

エレキベア
こんにちクマ〜〜〜

マイケル
今日は引き続き オセロAIの作成 を進めていこうと思います!

エレキベア
確か前回はminimax法を使ってAIを作成したクマね
↑前回までの記事

マイケル
今回は簡単に実装できて割と強いと言われている、
モンテカルロ法を使ってAIを実装してみるよ!
モンテカルロ法を使ってAIを実装してみるよ!

エレキベア
モンテカルロ・・・
難しそうクマ〜〜〜
難しそうクマ〜〜〜

マイケル
やってることは単純だからすぐに理解できると思うよ!
早速やってみよう!!
早速やってみよう!!
参考書籍

マイケル
実装するにあたり、下記書籍をチラ見させていただきました!
リバーシにモンテカルロ法を活用しているサンプルが載っていて大変参考になりました!
リバーシにモンテカルロ法を活用しているサンプルが載っていて大変参考になりました!

エレキベア
Pythonで作るゲームシリーズは分かりやすいクマね
モンテカルロ法とは

マイケル
それでは本題に入っていきましょう!
モンテカルロ法は下記のような手法になります!
モンテカルロ法は下記のような手法になります!
モンテカルロ法とは
- 乱数を用いた試行を繰り返すことによって近似値を求める方法。

エレキベア
乱数を用いた試行・・・
ピンとこないクマね〜〜
ピンとこないクマね〜〜

マイケル
実例で見た方が分かりやすいから、
一つ見てみよう!
一つ見てみよう!
モンテカルロ法を用いて円周率を求める

マイケル
モンテカルロ法の有名な活用法として、
「ランダムに点を打ちまくって円周率を求める方法」があります!
「ランダムに点を打ちまくって円周率を求める方法」があります!

エレキベア
ランダムに打つだけでそんなことが可能なのクマ・・・?

マイケル
円の中に入った点の数と全体の点の数の比率 から簡単に求めることができるんだ!
まず点の数は面積比に比例しているはずだから、下記のような式で表すことができるね。
まず点の数は面積比に比例しているはずだから、下記のような式で表すことができるね。

エレキベア
全体を四角(2r*2r)として面積比を求めているわけクマね

マイケル
その通り!
そしてこの式を変形すると下記のようになります。
そしてこの式を変形すると下記のようになります。

マイケル
つまり円の中に入った点の数/全体の点の数に4をかける
ことで円周率を求めることができるんだ!
ことで円周率を求めることができるんだ!

エレキベア
そういうことクマか!

マイケル
半径を1とした円の中に入ったかどうかは、下記式で求めることができるよ!
ここまでくれば実装できそうだね!
ここまでくれば実装できそうだね!

エレキベア
これならイメージが湧いてきたクマ〜〜〜

マイケル
以上を踏まえて実装したコード、シミュレータは下記になります!
回数を多くするほど近似値(円周率)に近づくので是非試してみてください!
回数を多くするほど近似値(円周率)に近づくので是非試してみてください!
↑モンテカルロ法で円周率を求めるシミュレータ(※最大数は100000回)

エレキベア
たったこれだけのコードで書けてしまうクマね
解したクマ〜〜〜〜〜
解したクマ〜〜〜〜〜
オセロAIの実装

マイケル
モンテカルロ法の概要が分かったところで、オセロAIを作ってみよう!
どのように活かせばいいか分かるかな?
どのように活かせばいいか分かるかな?

エレキベア
あまり思い浮かばないクマね〜〜
ひたすら打ちまくるクマ?
ひたすら打ちまくるクマ?

マイケル
おぉ!だいぶ近いね!!
打てる手から「ゲーム終了までランダムに打つ」のを数回試行して各手の勝率を求める
ことで決める方法があるよ!!
打てる手から「ゲーム終了までランダムに打つ」のを数回試行して各手の勝率を求める
ことで決める方法があるよ!!
↑各手の勝率から選ぶ(100回試行した例)

エレキベア
なるほどクマ〜〜〜!!
それなら試行回数をそれなりに設ければ有利な手が分かりそうクマ
それなら試行回数をそれなりに設ければ有利な手が分かりそうクマ

マイケル
この考えで実装してみよう!!
今回実装したコードはGitHubにも上げているのでご参照ください!
今回実装したコードはGitHubにも上げているのでご参照ください!
GitHub – unity-reversi-game-scripts v0.2.0

エレキベア
やってやるクマ〜〜
置いた手から勝利した回数を調べる

マイケル
まずは 置いた手から指定回数ゲームを行い勝った数を返す 関数から!
ゲーム終了までランダムな手を打った結果から算出 するようにしています。
ゲーム終了までランダムな手を打った結果から算出 するようにしています。
↑指定回数バトルして勝利回数をカウントする

エレキベア
ゲーム終了まで適当に打ちまくればいいわけクマね
勝利した回数から手を選ぶ

マイケル
あとはこの関数を使って、
最も勝利回数が多い手を選択すれば実装は完了です!
最も勝利回数が多い手を選択すれば実装は完了です!
↑置ける手からゲーム終了までプレイして最も勝率が高い手を選ぶ

エレキベア
何て手軽なんだクマ・・・!!
処理が重いため注意

マイケル
実装はこのようにとても簡単ですが、打つ回数がそれなりに必要なため処理が重くなりがちです・・・。
そのため非同期で別スレッドの処理として切り離しておいた方がよさそうです。
そのため非同期で別スレッドの処理として切り離しておいた方がよさそうです。
↑モンテカルロ法は重いので別スレッドにした方がよい

エレキベア
UniTaskも別スレッドに切り替える処理が用意されているクマね

マイケル
以上で実装は完了です!!
他のAIと対戦させる

マイケル
それでは早速強さを見ていきましょう!
前回作ったminimax法を使ったAI、ランダムに置くAIと対戦させてみます。
前回作ったminimax法を使ったAI、ランダムに置くAIと対戦させてみます。

エレキベア
これは結果が楽しみクマ〜〜〜〜

マイケル
ゲーム終了まで計算しているため、
序盤の判断が遅く、終盤の判断が早い のも面白いですね
序盤の判断が遅く、終盤の判断が早い のも面白いですね

マイケル
それでは対戦した結果は・・・
こちら!!
こちら!!
[対戦結果]
VS ランダムAI -> 30勝0敗
VS minimaxAI -> 15勝15敗

マイケル
ランダムに置くAIには圧勝しましたが、
minimax法を用いたAIとは互角 といった結果が出ました!
minimax法を用いたAIとは互角 といった結果が出ました!

エレキベア
適当に置きまくるだけで
minimax法と同等の力を得れるとは・・・
minimax法と同等の力を得れるとは・・・

マイケル
モンテカルロ法、恐るべし・・・
minimax法とミックスさせたら強くなる?

マイケル
どうすれば更に強くなるのか・・・?
そう考えた結果、序盤はminimax法で進めて終盤にモンテカルロ法を使用することでそれぞれのメリットが活かせるのでは?
といった案を思い付きました!
そう考えた結果、序盤はminimax法で進めて終盤にモンテカルロ法を使用することでそれぞれのメリットが活かせるのでは?
といった案を思い付きました!

エレキベア
確かに序盤はゲーム終了までが長いクマから
確率の精度も甘くなっていそうクマね
確率の精度も甘くなっていそうクマね

マイケル
うん、それに序盤は計算時間がかかってしまうという欠点も解消できそうだ!

マイケル
というわけで最後に、
下記のようなAIを作って対戦させてみます!
下記のようなAIを作って対戦させてみます!
↑終盤からモンテカルロ法を使用するAI

エレキベア
ゲームの進捗状況から使用するアルゴリズムを選択するわけクマね

マイケル
その通り!
このアルゴリズムを切り替えるタイミングを変えながら勝率がどう変わるか見てみよう!
このアルゴリズムを切り替えるタイミングを変えながら勝率がどう変わるか見てみよう!

マイケル
このAIとminimax法を使ったAIを対戦させてみた結果がこちら!
[対戦結果]
※minimax:モンテカルロ
2 : 8 -> 12勝18敗
5 : 5 -> 18勝12敗
8 : 2 -> 21勝9敗

エレキベア
これは・・・
想定通りクマ!!
想定通りクマ!!

マイケル
やはり基本はminimax法で進めて、終盤にモンテカルロ法で確実にしとめる方法が最も強いことが分かりました!
逆にモンテカルロ法に切り替えるタイミングが早すぎると弱くなってしまう傾向にあるようです。
逆にモンテカルロ法に切り替えるタイミングが早すぎると弱くなってしまう傾向にあるようです。

エレキベア
現時点で最強のAIが完成したクマね

マイケル
測定回数が少ないから断定はできないけれど、
こうやって数字に現れると面白いね!!
こうやって数字に現れると面白いね!!
おわりに

マイケル
というわけで、今回はモンテカルロ法を用いたAIの作成でした!
どうだったかな??
どうだったかな??

エレキベア
考えはシンプルなのにそれなりに強いAIが作れて感動したクマ〜〜〜

マイケル
確率で決めるから、処理の過程や中身のロジックについて気にしなくていい
のも汎用性が高くていいよね!
要は専門知識が無くても作れてしまうわけだ!
のも汎用性が高くていいよね!
要は専門知識が無くても作れてしまうわけだ!

エレキベア
これは今後作るゲームへの活用も期待できそうクマ

マイケル
手軽に使えるから今後も積極的に使ってみよう!!

マイケル
それでは今日はこの辺で!!
次回はML-Agentsを使ったAI作成に挑戦していく予定です!
お楽しみに〜〜!!
次回はML-Agentsを使ったAI作成に挑戦していく予定です!
お楽しみに〜〜!!

エレキベア
ついに機械学習に手を出すクマね
楽しみクマ〜〜〜〜
楽しみクマ〜〜〜〜
【Unity】第三回 オセロAI開発 〜モンテカルロ法を用いたAIの作成〜【ゲームAI】〜完〜
次回の記事はこちら!