その32017.10.03Unityゲームアルゴリズムシミュレーションゲームスキル賀好昭仁Tweetここのところワーッと一気に仕事が舞い込んできて、嬉しい悲鳴(?)を上げている筆者です。忙しい時はついつい情報収集や勉強がおろそかになりがちです。1日10分でも良いから勉強に充てる時間を作らなきゃいけないなーと思いつつも、納期が迫っている案件も放っとけないというジレンマを抱えちゃうんですよね。実務は間違いなく技術力の向上に役立ちますが、実務だけでは視野が狭くなって時代に取り残されていっちゃうのが悩ましいところです。今回もUnityで遊んじゃいましょう。前回は戦略シミュレーションの戦闘を作りましたね。ついでにターン制の仕組みも実装したりなど、筆者自身エンジョイしつつサンプルプログラムを書いておりました(笑)。戦略シミュレーションのAIゲームのAIといえば、本連載の第3回でリバーシのAIを作ったことがありました。戦略シミュレーションのAIは、やること自体はリバーシのAIと似ています。実装の難しさには大きな差がありまして、リバーシは「石が置けるマスに石を置く」という唯一のアクションしか無かったため、実装がとても簡単でした。強弱を考えなければ、石をランダムに置くだけでも一応ゲームとしては成り立つというわけです。戦略シミュレーションではリバーシに比べてアクションのパターンが格段に多いです。今回作っているシンプルな戦略シミュレーションでさえも、「どのユニット」が「どこに移動」して「誰に攻撃」するかを考えると、組み合わせは相当な数となり、どう制御するかが悩ましいというわけです。そこで、まずは戦略シミュレーションにありがちなAIを思い浮かべながら、そのAIを実装するためにどのような制御をすれば良いかを考えていくことにしましょう。得られる情報を考えてみる私たち人間が戦略シミュレーションをプレイしているとき、画面を見るだけでどのユニットがどこに居るかが把握できます。当たり前のようにも思えますが、人間の認知能力ってスバラシイのです。AIがユニットを知ろうとした場合は、目で見て直接把握するというわけにはいきません。画像処理の分野を極めればそのような実装も可能でしょうけれども、明らかにオーバースペックです(笑)。いうことで、AI側で処理しやすいデータとして伝えてあげることにしましょう。ユニットの位置を知らせるとなると、真っ先に思い浮かぶのは各ユニットの居るマスの座標データです。座標データはすぐに引っ張ってこられますし、「位置データ」という面では申し分無いデータです。仮に数マスしか離れていないところに敵ユニットが居たとしても、そこまでの間に障害物がある場合は回り道をする必要があります。いった意味で、座標データだけでは不十分と言えるでしょう。そこで活躍するのが、ユニットの座標データとマップから敵までの移動コストを計算し、経路探索をするアルゴリズムです。移動コスト計算のアルゴリズム前々回に移動可能範囲の計算アルゴリズムを実装しましたよね。移動可能範囲の計算アルゴリズムではユニットが持つ移動力をベースにマスの移動コストを減算する処理を行っていました。対象マスまでの移動コストを知りたい場合は、自身の居る場所を「0」とし、マスの移動コストを加算しながら計算を行います。下の図は自ユニットと敵ユニットとの間に移動不可能な山が挟まっている場合のサンプルです。左はマスの必要移動コスト、右は該当のマスまで移動するのに必要な移動コストです。「自」から「敵」に隣接するマスに移動する場合、最短で移動力9が必要であることがわかります。計算時に注意すべき点として、移動不可マス(山)の移動コストがあります。前々回にユニットの移動可能範囲を調べる際は山の移動コストを「9」として計算していましたが、今回のアルゴリズムでは「9」のままですと進入できるマスとして扱われてしまいます。進入不可のマスには移動不可フラグを立てるなどして。移動先から完全に除外してしまった方が良いでしょう。行動の重み付け上記アルゴリズムでは「敵ユニットまでの最短ルート」がわかりました。常に最短ルートで移動するだけでは敵の行動パターンが乏しくなってしまいます。リバーシのAIを作る際に説明したことがありましたが、「AIが何を重要と見なすか」を指定できるようにすることで、AIの行動パターンに個性を持たせることができるようになります。「AIが何を重要と見なすか」は、ゲームの各局面で人間がどのように考えて行動を決めるかをイメージすると良いでしょう。目的地点の選び方は・敵ユニットを攻撃可能なマス・反撃を受けないマス・高い地形効果が得られるマス・味方のサポートを得られるマスなどが考えられます。ユニットの状態や他の条件を加味することもあるでしょう。・敵ユニットを一撃で倒せるか・敵ユニットの反撃に耐えられるか・その敵ユニットを倒すことで、味方が有効な行動をできるようになるかなどなど。実装の際、これらの条件を数値化して重み付けをします。ユニットが移動可能なマスのうち、「敵ユニットを攻撃可能なマス」は50ポイント、「高い地形効果が得られるマス」は30ポイントが与えられるものとします。80ポイントとなります。AIはポイントの高いマスを移動先として選ぶだけで最適な行動がとれるというわけです。AIは強けりゃいいってものでもない戦いを有利に進めるためのさまざまな条件を考えて実装を進めれば、きっと強いAIができあがることでしょう。難しいのが「AIは強けりゃいいってものでもない」という点です。ゲームの熟練者は手応えを求めるかもしれませんが、ゲームを始めたばかりで勝てないくらい強力なAIと戦うことになると、きっとストレスを感じるプレイヤーは多いでしょう。重み付けによってAIに個性をつけられるという話は先ほど述べた通りですが、これをうまく利用することで、AIの強さを調整することが可能です。具体的には、一番重みのある行動(最適な行動)ばかりを選択せず、2番目や3番目の行動も選択するようにします。することで、AIが少し弱くなります。(常に最適な行動をするわけではないというのは、ちょっと人間っぽいですね)作ってみた今回は、各パラメータに数値を指定することである程度行動が制御可能なAIを作ってみました。ベタにAIを作るよりも少し手間はかかりますが、数値を変えるだけでさまざまなパターンのAIが簡単につくれますよ。サンプルプロジェクトはこちらからどうぞ。https://github.com/akako/gamealgorithm-war-simulation/releases/tag/for_algorithm12(あまり賢くないAIですので、ぜひソースをいじって賢くしてあげてください)まとめ3回にわたって戦略シミュレーションのアルゴリズムを作ってきましたが、シンプルかつ面白いですね。ゲームの土台さえ作ってしまえば、あとはコンテンツを色々と作って延々と遊ぶことができますし、マップエディタ機能を作ってプレイヤーにコンテンツを作ってもらうのも面白そうです。次回予告さて、次回は今までとはちょっと毛色を変えて、音ゲーのアルゴリズムを作ってみることにします。昭仁qnoteスマホアプリ開発チーム技術主任。PHP・Android・iOS・Unityなど複数のプラットフォームでの開発を行う。7匹の先輩猫社員たちにイスを占領される。Corporation。