現在、戦略シミュレーションゲームを製作しています。
今現在、
・自ユニットの移動範囲を求める処理
・自ユニットの移動処理
・敵ユニットへの攻撃処理
が大方できており、
ユニットの情報として
・HP
・攻撃力
・他ユニットとの相性
・移動力
などがあり、
マップ(1チップ)の情報として
・移動コスト
などがあります。
今現在はゲームシステムとしての基盤の製作がほぼ終わり、
ゲームタイトル⇒ゲームメイン⇒{自分のターン⇔敵のターン}⇒終了
の流れが出来てきたので、
今度は敵AIを作ろうと考えているのですが・・
それの処理が全く思いつきません。
少なくとも、AIを作る上で必要な情報とは何なのでしょうか?
一応、マスの重み付けというものを行おうとして、
クラスを設計しているのですが、
敵AIは複数作ろうと考えているため、
各AIごとにマスの重みを計算していたら、時間がかかりすぎますし、
かといって一度計算してたものをデータとして入れて再利用しようとしても、
メモリの消費が大きすぎると思います。
まず最初に敵AIの移動処理から作っていこうと考えているんですが、
聞きたいことは次のようなことです。
・AIを作る上で必要な情報は何か
・AIはどのような設計にするのが良いか
(設計というか、どのようなクラスが必要か)
・そもそも、戦略SLGのAIとはどのようにして出来ているのか
ということです。
かなり曖昧な質問になってしまいましたが、回答をお願いします。
戦略ゲームについて
Re:戦略ゲームについて
今ひとつ質問の意味を正しく読み取れてるか自信がないのですが。
ここで言っている AIというのは移動処理だけの話ですか?
それとも、移動処理を含めた敵の思考アルゴリズム全般の話でしょうか?
とりあえず全般ということで話を進めます。
>AIを作る上で必要な情報とは何なのでしょうか?
AIを作る上で参照するパラメータのことでしょうか?
であれば、ざっくりと言うなれば、とるべき行動を決めるための判断基準になる
パラ-メータ全て、でしょうか。
まさに上で上げられている、各ユニットのHP、攻撃力、移動力、位置などなどです。
(勿論、他のユニットの情報をどこまで知ることができるか、の仕様によっては
制限する必要があります)
たとえば回復行動1つとっても、
・ 敵(といってもプレイヤー側のユニットのことですが)に囲まれていないときは
自分のHPが 1/4以下になったら回復
・ 0~1回の移動で攻撃圏内に自分が入ってしまう敵が周囲に1体いる場合、
自分のHPが 1/3以下になったら、複数居るようなら 1/2以下になったら回復
・ 特にやることがなく、1回で移動可能な周囲にHPの低い者がいたら、
そこまで移動して回復してあげる
のように、条件を複雑にすればするほど状況に合わせた行動がとれますが、
必要になるパラメータは増えていきます。
さらに言えば、その可視情報から導き出される確定した情報や
類推される情報(的外れであってもいい)とかも含まれます。
>各AIごとにマスの重みを計算していたら、時間がかかりすぎますし
重みというのが移動の話でしたら、移動パスを見つけるのには多少時間は
かかるのは仕方ありません。
メモリに関しては、その消費量を見てみないとなんとも言えませんが……。
>AIはどのような設計にするのが良いか
実装的な設計はゲーム毎に違うので、説明するのは難しいです。
しかしながら、戦略ものは長考になるのは避けがたいので、
スレッドを使って思考することになります。
>そもそも、戦略SLGのAIとはどのようにして出来ているのか
これもいろいろあるので、一概には言えないのですが、
よくあるタイプの SLGの一例を挙げてみます。
まずはチーム AIです。ステージの最初の段階で、
チームの戦略、目的、行動の傾向を決めます(ステージの途中で変わることもあります)。
そのチームの目的が特定目標物の撃破を行うのか、拠点などの防衛を行うのか、
或いは敵を全て殲滅させるのか、撤退するのか等です。
この何を優先するべきなのかは、チームに所属するユニット全体の優先的な
行動指針となり、各ユニットの判断基準に影響を与えます。
これを決めた上でキャラクタ AI……各ユニットの行動を決めるのですが、
ここはチーム AIの指針とも照らし合わせつつ、決めます。
決め方はこれもいろいろあるのですが、単純に優先順に条件チェックして決めてもいいですし、
その選択をとった場合の状況を評価(場全体か、周囲の対象だけを限定してもいいです)し
もっとも高い評価を得られるものを選択してもいいです
(難易度を下げる等の目的で必ずしもそうするとは限りませんが)。
移動という選択肢に関しては、移動後の攻撃、そして次のターンで受ける相手からの攻撃、
可能なら周囲の敵味方ユニットの状況(敵の射線を避けたり、味方の支援をうけられるかどうか)を
併せて評価値として出して、どこがベストなのか出した方がいいでしょうね。
後は単一なアクションだけで動いても十分かもしれませんが、
必要なら未行動の味方ユニットの行動を巻き込んでしまってもいい(連携)ですし、
もう一回り大きな指針を立てその指針に沿うように数ターンかけた複数の
アクションに分解して思考するのを混ぜるとよりいい AIになります。
他にも状況によっては特定の目的を持たせてひたすらそれしかしないのが
居てもいいですね。
と、まぁざっくりと書きましたが、ちゃんと動けばやればやるほど賢くなりますが、
下手するとドツボにもはまりかねないので、最初はこむずかしいことを考えないで、
もっとずっとシンプルなものを実装するのがいいかと思います。
ここで言っている AIというのは移動処理だけの話ですか?
それとも、移動処理を含めた敵の思考アルゴリズム全般の話でしょうか?
とりあえず全般ということで話を進めます。
>AIを作る上で必要な情報とは何なのでしょうか?
AIを作る上で参照するパラメータのことでしょうか?
であれば、ざっくりと言うなれば、とるべき行動を決めるための判断基準になる
パラ-メータ全て、でしょうか。
まさに上で上げられている、各ユニットのHP、攻撃力、移動力、位置などなどです。
(勿論、他のユニットの情報をどこまで知ることができるか、の仕様によっては
制限する必要があります)
たとえば回復行動1つとっても、
・ 敵(といってもプレイヤー側のユニットのことですが)に囲まれていないときは
自分のHPが 1/4以下になったら回復
・ 0~1回の移動で攻撃圏内に自分が入ってしまう敵が周囲に1体いる場合、
自分のHPが 1/3以下になったら、複数居るようなら 1/2以下になったら回復
・ 特にやることがなく、1回で移動可能な周囲にHPの低い者がいたら、
そこまで移動して回復してあげる
のように、条件を複雑にすればするほど状況に合わせた行動がとれますが、
必要になるパラメータは増えていきます。
さらに言えば、その可視情報から導き出される確定した情報や
類推される情報(的外れであってもいい)とかも含まれます。
>各AIごとにマスの重みを計算していたら、時間がかかりすぎますし
重みというのが移動の話でしたら、移動パスを見つけるのには多少時間は
かかるのは仕方ありません。
メモリに関しては、その消費量を見てみないとなんとも言えませんが……。
>AIはどのような設計にするのが良いか
実装的な設計はゲーム毎に違うので、説明するのは難しいです。
しかしながら、戦略ものは長考になるのは避けがたいので、
スレッドを使って思考することになります。
>そもそも、戦略SLGのAIとはどのようにして出来ているのか
これもいろいろあるので、一概には言えないのですが、
よくあるタイプの SLGの一例を挙げてみます。
まずはチーム AIです。ステージの最初の段階で、
チームの戦略、目的、行動の傾向を決めます(ステージの途中で変わることもあります)。
そのチームの目的が特定目標物の撃破を行うのか、拠点などの防衛を行うのか、
或いは敵を全て殲滅させるのか、撤退するのか等です。
この何を優先するべきなのかは、チームに所属するユニット全体の優先的な
行動指針となり、各ユニットの判断基準に影響を与えます。
これを決めた上でキャラクタ AI……各ユニットの行動を決めるのですが、
ここはチーム AIの指針とも照らし合わせつつ、決めます。
決め方はこれもいろいろあるのですが、単純に優先順に条件チェックして決めてもいいですし、
その選択をとった場合の状況を評価(場全体か、周囲の対象だけを限定してもいいです)し
もっとも高い評価を得られるものを選択してもいいです
(難易度を下げる等の目的で必ずしもそうするとは限りませんが)。
移動という選択肢に関しては、移動後の攻撃、そして次のターンで受ける相手からの攻撃、
可能なら周囲の敵味方ユニットの状況(敵の射線を避けたり、味方の支援をうけられるかどうか)を
併せて評価値として出して、どこがベストなのか出した方がいいでしょうね。
後は単一なアクションだけで動いても十分かもしれませんが、
必要なら未行動の味方ユニットの行動を巻き込んでしまってもいい(連携)ですし、
もう一回り大きな指針を立てその指針に沿うように数ターンかけた複数の
アクションに分解して思考するのを混ぜるとよりいい AIになります。
他にも状況によっては特定の目的を持たせてひたすらそれしかしないのが
居てもいいですね。
と、まぁざっくりと書きましたが、ちゃんと動けばやればやるほど賢くなりますが、
下手するとドツボにもはまりかねないので、最初はこむずかしいことを考えないで、
もっとずっとシンプルなものを実装するのがいいかと思います。
Re:戦略ゲームについて
>Justyさん
回答ありがとうございます。
はい、移動処理ではなく敵の思考ルーチンについてです。
必要な情報については、ユニットの情報だけで大丈夫と考えてよろしいのでしょうか?
(つまり、AIを設計するにあたり、ユニットに新たな情報を持たせる必要が無い、ということ)
私が知りたかったのは実装面の話なのですが、
私の質問自体、実装に関するものが何も書かれてませんでしたね。すいません。
例えば、Justyさんが言われている回復行動を挙げると、
・ 自ユニットの移動範囲を求める
・ 自ユニットの移動範囲に敵が存在しないか調べる
・ 敵ユニットの攻撃範囲を求め、自ユニットがその範囲に入っていないか調べる
・ 自ユニットの移動範囲に味方ユニットいないか調べ、
その味方ユニットが敵ユニットの攻撃範囲に入っていない場合、そのユニットを回復する
生真面目に自ユニット数または敵ユニット数×自ユニット数分の
計算をしていたら、莫大な時間がかかることは確かですよね。
私が知りたかった点は、この点を踏まえて、どのような設計にすべきか、ということです。
最初の投稿内容にも書いたとおり、最初はユニットの移動処理について実装しようとしたのですが、
ユニットには敵の攻撃範囲を避けながら移動して欲しいかったので、
各マスごとにコストを付けることが必要だと考えました。
私が考えた構造は次のようなものです。
ターン終了時に全ユニットの攻撃範囲を求め、
その攻撃範囲に入っていたマスのインデックスをキーとし、
コストを値としてstd::mapに入れておく。
ただ、これでは自ユニットの区別が付かないので、
コストを計算したユニットのチームナンバーなどとの構造体として入れることを考えました。
(つまり、チームナンバーが同じであったら、コストを計算しない)
もちろん、これでも攻撃範囲が重なった時に対応できませんし、
複数のターンを考慮したうえでの移動を行うことは不可です。
とりあえず、今はこの点に関しての良いアプローチが知りたいです。
(チームAIなどを考慮した場合であると尚良いのですが・・)
>やそさん
どうもありがとうございます。
少しレベルが高い気もするんですが、
参考にさせてもらいます。
回答ありがとうございます。
はい、移動処理ではなく敵の思考ルーチンについてです。
必要な情報については、ユニットの情報だけで大丈夫と考えてよろしいのでしょうか?
(つまり、AIを設計するにあたり、ユニットに新たな情報を持たせる必要が無い、ということ)
私が知りたかったのは実装面の話なのですが、
私の質問自体、実装に関するものが何も書かれてませんでしたね。すいません。
例えば、Justyさんが言われている回復行動を挙げると、
・ 自ユニットの移動範囲を求める
・ 自ユニットの移動範囲に敵が存在しないか調べる
・ 敵ユニットの攻撃範囲を求め、自ユニットがその範囲に入っていないか調べる
・ 自ユニットの移動範囲に味方ユニットいないか調べ、
その味方ユニットが敵ユニットの攻撃範囲に入っていない場合、そのユニットを回復する
生真面目に自ユニット数または敵ユニット数×自ユニット数分の
計算をしていたら、莫大な時間がかかることは確かですよね。
私が知りたかった点は、この点を踏まえて、どのような設計にすべきか、ということです。
最初の投稿内容にも書いたとおり、最初はユニットの移動処理について実装しようとしたのですが、
ユニットには敵の攻撃範囲を避けながら移動して欲しいかったので、
各マスごとにコストを付けることが必要だと考えました。
私が考えた構造は次のようなものです。
ターン終了時に全ユニットの攻撃範囲を求め、
その攻撃範囲に入っていたマスのインデックスをキーとし、
コストを値としてstd::mapに入れておく。
ただ、これでは自ユニットの区別が付かないので、
コストを計算したユニットのチームナンバーなどとの構造体として入れることを考えました。
(つまり、チームナンバーが同じであったら、コストを計算しない)
もちろん、これでも攻撃範囲が重なった時に対応できませんし、
複数のターンを考慮したうえでの移動を行うことは不可です。
とりあえず、今はこの点に関しての良いアプローチが知りたいです。
(チームAIなどを考慮した場合であると尚良いのですが・・)
>やそさん
どうもありがとうございます。
少しレベルが高い気もするんですが、
参考にさせてもらいます。
Re:戦略ゲームについて
>ユニットの情報だけで大丈夫と考えてよろしいのでしょうか
>AIを設計するにあたり、ユニットに新たな情報を持たせる必要が無い
その判断はこちらではできません。
でも現在のユニット情報に何があのかや AI仕様によっては
追加で何か持たせる必要は出てくると思いますよ。
>敵ユニット数×自ユニット数分の計算をしていたら
>莫大な時間がかかることは確かですよね
何百、何千体が一同に会しているような状況だとまともにやるのは
ちょっと辛いどころではなくなりますね。
でも、2,30体程度であれば、(よほどな AI仕様でもない限り)、
そんなに長大な時間はかからないような。
それに一気に全ユニットの行動を完全に決めて、表示を行うわけではなく、
どういう行動をとるかを1体1体演出を入れながら見せていくかと思うので、
その裏で次のユニットの行動をどんどん決めていけば、体感的に待たされている感を
軽減させることもできます。
このあたりは1体あたりの思考時間を調整して、うまくバランスをってあげる
必要がありますね。
>コストを値としてstd::mapに入れておく
>ただ、これでは自ユニットの区別が付かないので
影響マッピングを行うところまではいいのですが、なぜ両チーム混在データに
なっているのでしょうか?
別けておけば区別は直ぐですし、重なりも同チーム同士のものだけになります。
あと、位置から検索するなら mapより vectorの方が速そうな気がします。
というかこのコストって、地形コストにして加算して使うものではないのでしょうか?
Re:戦略ゲームについて
>Justy さん
もしかして、私の考えは根本的に間違ってますかね。
std::vectorではなくstd::mapを使ったのは、
std::vectorだとマップの高さ×マップの幅分の要素をとる必要があり、
これではメモリ消費が激しいと考えたからです。
チームごとに分けず、全チーム混在データかというと、
これも、チームごとにコストを分けていたら、
データ量が膨れ上がってメモリの消費が懸念されたから、なのですが
これは私の勝手な先入観なのでしょうか?
そこまで、メモリは消費しないものなのですか?
ユニット数も、多くて数百体になると思うんですが
全ユニット数×全ユニット数回のアクセスくらいは大した時間はかからないんでしょうか?
地形コストに加算するのはそうなんですが、
両チーム混在データだったので・・
もしかして、私の考えは根本的に間違ってますかね。
std::vectorではなくstd::mapを使ったのは、
std::vectorだとマップの高さ×マップの幅分の要素をとる必要があり、
これではメモリ消費が激しいと考えたからです。
チームごとに分けず、全チーム混在データかというと、
これも、チームごとにコストを分けていたら、
データ量が膨れ上がってメモリの消費が懸念されたから、なのですが
これは私の勝手な先入観なのでしょうか?
そこまで、メモリは消費しないものなのですか?
ユニット数も、多くて数百体になると思うんですが
全ユニット数×全ユニット数回のアクセスくらいは大した時間はかからないんでしょうか?
地形コストに加算するのはそうなんですが、
両チーム混在データだったので・・
Re:戦略ゲームについて
昔の8ビットパソコンとか携帯ゲーム機じゃなければメモリは気にしなくていいのでは
時間は作ってみなければわからないのでまず作ってみて遅ければ考え直すということではだめですか
時間は作ってみなければわからないのでまず作ってみて遅ければ考え直すということではだめですか
Re:戦略ゲームについて
そうですね。
とりあえず、処理速度やメモリ使用量は考えないで作ってみることにして、
そこで何か問題があったら、再び質問することにします。
どうもありがとうございました!
とりあえず、処理速度やメモリ使用量は考えないで作ってみることにして、
そこで何か問題があったら、再び質問することにします。
どうもありがとうございました!