#26 AI使って弟をゲームでボコるんだ
どうも、まりなです。
ある休日の昼下がり、私が「小林さんちのメイドラゴンS」を見ながら「やっぱりメイドラゴンが京アニ作品の中で一番好きやなぁ...このトールちゃんと小林さんの夫婦感と言いますか…最高やな!」と思っていると弟が「マンカラをやろう」と言ってきました。
「は?マンカラ?なんだそのギリギリ下ネタじゃないラインみたいな名前の物は。こっちはメイドラ2期(二周目)で忙しいんやぞ」と思う私を他所に弟はルール説明を始めました。
※この動画を見てルールを把握していただけると以下の記事が読みやすくなります。弟もこの動画を見てマンカラを知ったらしいです。ローカルルールが色々あるらしいのですが本記事ではこの動画のルールに従います。
ほうわかったと。運の要素は一切絡まない、実力とかIQとか地頭の良さがものをいうタイプのゲームだ。おいおい待ってくれよと。こっちは現役旧帝大理系(情報工学科3年)、弟は普通の中学3年(野球部 4番 ピッチャー 県大会3位)。ハンデでもつけてやらないと勝負にならんぞと。たとえそっちは数戦やったことがあるとて。まあいい、やっぱり頭いいんやな な所を見せつけてSP(Sonkei Point)を稼いでやろうと。「まあ、わっかんねーけど。とりあえずやってみっか。(頭ポリポリ)」なんて言いながら勝負に乗ってやりました。
結果、三戦やって三敗しました。おい、やめろ。やっぱ勉強しかできひんねんなみたいな目で見るのは。そもそもこんなゲーム必勝法があってそれを知ってる方が勝つようになってるんやろ。こういうので地頭の良さを測ろうとしないでくれ…
悔しいですが、悔しいと思っていると思われたくありません。戦略をネットで調べて勉強などすれば「うわ悔しいからって勝とうと必死やん」と思われかねません。どうすればこの鬱憤を晴らせるんだ…
そうだ。ニューラルネットワークと遺伝的アルゴリズムで最強のAIを作ろう。別のベクトルから攻めることで奇襲を図ります。失われた威厳を取り戻してやります。
ニューラルネットワークとは?
機械学習の代表的な手法の一つです。人間の脳の働きを模倣したアルゴリズムで、各ノード(ニューロン)は下位層から入力を受け取り、それに「重み」をかけて和をとったものを活性化して(活性化関数fにかけて)出力します。
この「重み」w_iの列を「遺伝子」と呼びます。「遺伝子」を上手く定めることで期待する出力を出せるニューラルネットワークを作ります。
ここで「期待する出力」は何かというと「良い盤面ほど高く、悪い盤面ほど低い値」です。こういったゲームのAIに求められるのは「最も良い盤面にする手」を考えることです。マンカラの場合、プレイヤーの取れる手は大体いつも3通りです。
全ての手をとった場合の盤面を考え、それらをニューラルネットワークに入力し、出力が最も高い盤面になる手を選べば良いというわけです。
ではそのような上手いw_iをどうやって定めるのかというと色々やり方はあるのですが今回は遺伝的アルゴリズムを使うことにしました。
遺伝的アルゴリズムとは?
まず最初に乱数で遺伝子を100個作成します。
これらから二つ選んでゲームをさせます。勝ったものを残し、負けたものは捨てます。これを繰り返して50個の勝った遺伝子を得ます。
勝った遺伝子二つを親として次の世代の遺伝子を作ります。子はランダムにどちらかの親のw_iを受け継ぎます。
こうして子世代の遺伝子100個を得ます。次の世代の遺伝子でも同じことを行い、孫世代の遺伝子100個を得ます。これを繰り返し、後の世代になる程強い遺伝子になるという仮定にもとづくアルゴリズム、これが遺伝的アルゴリズムです。
しかしこれには後の世代になる程同じような遺伝子ばかり生まれるという問題点があります。そこで突然変異を実装します。ある確率でどちらの親からも遺伝せず乱数で数値を得ることにします。
これらのアルゴリズムをPythonで実装しました。
なおコードは上図のように汚く、コメントアウトもあんまりしてないので参考にならないと思うので全文は省略させていただきます。
VS弟
それでは対戦したいと思います。弟をAIでボコボコにします。100回の学習を行なった第100世代の遺伝子で挑みます。
対戦はこのようにリアルで行います。(プレイマットがまどマギのマミさんなのは気にしないでください)弟の打った手をターミナルに入力してAIの解答を得ます。
先手弟はまず左を選択しました。先手は左を選ぶことで必ず2回行動できます。「先手の初手左はマナー」だそうです。
弟は続けて右を選択しました。
AIのターンです。AIの弾き出した手は
「4」
プログラム上ではこのように各マスにインデックスを振って処理を行なっているので4は右を表します。
よってこのようになりました。対して弟は左を選択しました。
自陣の1マスでコインが多く固まっている方が有利なようです。
AIは左を選択しました。
相手の陣にコインをばらけさせる良い手なのではないでしょうか。しかも右端で終わったのでAIはもう一度行動できます。AIは真ん中を選択しました。
弟は真ん中を選択。
AIは右を選択。互角に戦っているように見えます。
弟は左を選択しました。右端で終わったのでもう一度行動できます。
右を選び自陣のコインを残り一枚にしました。
AI側にはまだコインがばらけており弟が有利に見えます。ここは私の感覚ではAIは相手側にコインを送れるよう真ん中か左を選択を選択すべきかと思いましたがAIは右を選択しました。
たしかにまだ次の番で弟は上がれないのでこの選択は正しいのかもしれません。弟は当然真ん中を選択。リーチをかけます。
AIは左を選択。また弟の陣にコインがばらけました。
弟は右を選択し2回行動します。
弟は左を選択。
枚数だけで見ると弟の方が有利に見えますが、このゲーム序盤から自陣のコインを減らしすぎると後半相手に攻撃しにくくなるのでそうとも限りません。AIは真ん中を選択します。弟の陣のコインがまた増えました。
弟は真ん中を選択しコインを送り返します。
互いの陣のコインが少なくなってきました。ここからは一手一手が重要になります。AIは左を選べば2回行動できます。しかしここでAIは真ん中を選びました。
これは完全に悪手だと思いました。弟は右を選ぶことで2回行動する権利を得ました。
続けて左を選択。
しかしここでAIが勝ち確であることに気づきました。AIは左を選択。左端で終わったので2回行動できます。
AIは続けて真ん中を選択し最後のコインを一マス進めます。
弟は勝利までにあと2手必要ですがAIは次の手で勝てる状況になりました。弟は真ん中を選択。
AIは左を選択しAIの陣のコインが0枚になりました。AIの勝利です。
まさか一試合目から勝てると思っていなかったので弟より私が驚いていました。時々想定外の手を打ったのも人間を超えてる感があってなんか怖かったです。
マンカラガチ勢の方から見れば弟のプレイにもAIのプレイにもガバがあったかもしれませんが目をつむっていただけるとありがたいです。
以上です。8月も終わりバイトも少なくなりそうなのでまた近いうちに更新できたらいいなと思います。最後まで読んでいただきありがとうございました。それでは。
この記事が気に入ったらサポートをしてみませんか?