A *戦術RPGのアルゴリズム?


15

私はC ++で非常に貧弱な戦術RPGを書くことに手を出しました。これまでのところ、2Dタイルマップがあり、ウィキペディアの擬似コードに基づいて機能するA *アルゴリズムを取得しまし

しかし、実際の戦術RPGは、平面上で最適なパスを見つけてそこに移動するだけではありません。通常、移動範囲は限られているため、登り降りする必要があります。Final Fantasy Tacticsをプレイしたことがある場合、これらはMoveとJumpの統計の影響を受けます。これは私が迷子になる場所です。ターゲットへの最適なパスを見つけるようにA *アルゴリズムを変更する方法はありますが、パスは非常に多くのタイルだけです。高さの違いを考慮して統計をジャンプするにはどうすればよいですか?ギャップを飛び越える方法を実装するにはどうすればよいですか?

役立つ場合は、現在、私のマップはタイルオブジェクトのベクターで表されています。各タイルには、北、南、東、および西のタイルへのポインターがあり、マップの端に沿ってタイルが存在しない場合、またはタイルが非通過可能に設定されている場合、nullptrに設定されます。


5
なぜ移動範囲が問題なのかわかりません。最短経路を見つけ、その後、その経路に沿って「速度」の正方形を移動します。
Mooingダック

回答:


33

登山とギャップは、単に異なるコスト関数です。ギャップをジャンプできるユニットの場合、通常の(?)コストがかかりますが、ジャンプしないユニットの場合は、任意に高いコストになります。困難な地形などと同様に、登山には追加費用がかかります。A*アルゴリズムは費用関数を十分に処理できるため、実装でまだ実行していない場合は、費用関数を使用してA *を実装する方法をグーグルで検索してください。

しかし、そうは言っても、A *は戦術RPGにとって特に良いアプローチではないと思います。より正確には、完全なストーリーではありません。ユニットが目標に向かって盲目的に失敗するのは望ましくなく、究極の目標に向かって前進し、敵を側面から追い求めるなどしながら、カバー、ハイグラウンドなどを活用するようにユニットを配置する必要があります。そのため、各移動の終点の戦術的価値は、それが目標にどれだけ近いかではなく、非常に重要です。これには、単なる経路探索よりも詳細な問題解決が必要です。


10
「戦術的ポジショニング」についての良い点ですが、それらの決定は、基本的な経路探索よりも高いレベルで適用される可能性があります。一方、ある種の戦術アナライザーによって生成される経路探索アルゴリズムのノードにコストを適用することは、良い選択肢かもしれません。たとえば、敵が地形に沿って見通し線を持っている場合、その地形上のノードのコストが非常に高くなります。
DrMcCleod

1
@DrMcCleod:確かに、それは私が「もっと正確に言えば、完全な物語ではない」という意味です。確かにA *または別のアルゴリズムを使用して処理の一部を行うこともできますが、ユニットが攻撃を受ける可能性のある地形を移動することは、より適切に処理されるため、移動コストを通じて監視対象ノードを回避しようとするなどのアプローチを避けると思いますリスク/報酬計算、IMO。
ジャックエイドリー

13

ユニットのすべての可能な移動オプションが必要な場合は、ダイクストラのアルゴリズムを使用します。

A *とダイクストラの違いは、ダイクストラが与えられたコストで達成可能なすべての最短ルートを提供し、それらのいずれもまだ目的地に到達しない場合、コストを1つ増やして続行することです。一方、A *は、目的地に到達する可能性が高いルートを最初に計算することを好みます。

したがって、ポイントAからポイントBへの最短パスが必要な場合は、A *が適切な選択です。しかし、すべての可能な移動オプションとそれらのそれぞれへの最短経路が必要な場合、ダイクストラはまさにあなたが望むものです。

必要なのは、特定の宛先ノードなしでダイクスタのアルゴリズムを実行することですが、最大コスト(ユニットの移動範囲)を超えてはなりません。ノードへの移動が最大コストを超える場合は、アクセスしないでください。訪問されていないエッジがないためにアルゴリズムが終了すると、訪問されたセットの各ノードが宛先になり、ノードの以前のノードマーカーが最初のノードに戻るパスを表すリンクリストを形成します。

ジャンプに関して:それらは、A *とダイクストラの両方でさらに別のエッジとして表すことができます。通常のエッジまたは別のエッジをトラバースするのと同じコストになる場合があります。「jump_height」パラメータをアルゴリズムに渡すこともできます。これは、指定された高さを超えるジャンプエッジを無視するようにアルゴリズムに指示します。


9
ここで言及する価値があるのA*は、実際にはダイクストラの単なる一般化であるため、一方を理解すれば、もう一方を理解するのはそれほど難しくないはずです。
キュービック

8
実際、A *アルゴリズムで0を返すだけのヒューリスティックがある場合、おめでとうございます!ダイクストラのアルゴリズムを書いたところです。
ヤン

9
「ダイクストラは、与えられたコストで達成可能なすべての最短ルートを提供し、それらのいずれもまだ目的地に到達しない場合、コストを1つ増やして継続します」 -それは動作も出力もしません。実際には、幅優先検索の重み付きグラフへの一般化にすぎません。単一の最短パスを見つけます。A *は、距離ヒューリスティックが利用可能な場合の一般化です。
BlueRaja-ダニーPflughoeft

1
これがなぜそれほど支持されているのかはわかりません。実用的な観点から、ダイクストラは時代遅れです。教育的および歴史的な理由でCSで教えられています。A *でさえ、真面目な仕事のために時代遅れです。Google Mapsは確かにそれを使用しません。最近では、ArcGraphのバリアントを見ることになります。
–MSalters

2
@MSalters DijkstraおよびA *は、戦術RPGなどの単純な問題に対する完全に優れたアルゴリズムです。有効な動き(タイル)の範囲は非常に狭く、タイル(直交、場合によっては斜め)を移動する方法は非常に限られており、通常は最大パスがかなり短くなっています:SQRT(ArenaWidth²*ArenaHeight²)。計算上、かなり小さな値になる可能性が高いので、現代のマシンでは違いは無視できるほど小さいので、単純な実装でここで説明する目的に十分なのに、なぜより複雑な実装に煩わされるのでしょうか?
ヴァルテク

2

他の回答には良い情報がありますので、必ず読んでください。

ただし、質問に答えるには、リンクした擬似コードに基づいて、heuristic_cost_estimatetileAからtileBまでのコストを計算する何らかの種類の関数があります(隣接している場合)。そのコストにフラット(1)を使用する代わりに、タイルの統計とユニットの統計、および場合によってはエッジの統計を含めるように調整する必要があります。

例えば:

if (edge == JUMP && !unit.canJump()) 
    return INF;
if (tile.Type == Forest && unit.moveType == HORSE) 
    return 2;
//Other cases here
//-----
else 
    return 1;

これはあなたにあなたの道を与えます。次に、移動ポイントを消費しながらユニットをパスに沿って移動し、remainPoints <edgeCostのときにユニットを停止します。remainingPoints = 1になった場合、これは完全に最適ではない可能性がありますが、RPGの練習には十分なはずです。現実には、ジャック・エイドリーが指摘したように、より戦術的にしたいでしょう!

課題:
より高度になりたい場合は、提案されたようにDjikstrasを使用してX距離内のすべてのスペースを検索し、ターゲット、防衛、およびパワー、その位置から攻撃できるかどうかなど。その情報に基づいて、タイルを選択し、ジクストラを使用して計算したパスに従ってタイルを移動します。


1

クライミングとギャップはコストを変更するだけなので、非常に簡単です。パスファインディング(および戦術AIのほとんど)は、すべての訪問予定ノードのコストを合計し、最小化することです。通行不可能な崖には無限の(非常に、非常に高い)コストがあり、斜面には通常よりも高いコストがかかります。

ただし、実際の敵は通常、最適なパスを見つけられないため、これは、最適なソリューションではないグローバルに最適なパスを見つけます。それは非常に非現実的で、時にはプレイヤーにとって明らかな点まであり、迷惑です(特に、AIが基本的に無敵である場合は、それも最適なものを選択するためです)。

良いシミュレーションでは、意図的に最適なパスが見つかりません。はるかに優れたアルゴリズムは、階層パス検索を実行することです。他に何もない場合は、マップ上に直線を描画し、4〜5のウェイポイントを取得してから、あるウェイポイントから次のウェイポイントまでパス検索します。既知であり、他のすべてのノードの重みを「無関心」に設定します。または、最初に粗いグリッドでA *を実行し、次に1つの大きなノードから次のノードへのパスファインディングを実行できます(ただし、マップ上に線を描くことでも問題ないと思います)。

これははるかに現実的です(また、グラフがはるかに小さいため、処理能力の一部を消費します)。はい、それはユニットが崖に向かって移動することを意味します。それは問題ありません、実際の敵にも起こります。次回は、再び発生することはありません(現在、無限のコストがわかっているため)。


1
「単純な階層パス検索」はかなり馬鹿げているように見えるかもしれません。ユニットが山の尾根に向かってまっすぐに歩いていくと、そこに通路が塞がれていることがわかります。その後、彼らはmountainを経由して次のウェイポイントに行き、そこから目的地に行きます-後者のウェイポイントが彼らにとってコースから外れていてもです。前処理により、山道が前にあり、そこを通り抜けていることがわかります。しかし、そうしなくても、計画されたコースから離れすぎたら、残りを再計画する必要があります。
–MSalters

@MSalters:はい 粗いグリッド階層方式では、複数回発生することはほとんどありません(たとえば、ノードの平均、中央値、または最大コスト値を取得します)。それは人間の敵がどのようにプレイするかとほぼ同じです - あなたが知っているか、遠くから見ることができる大きな障害物山の鎖のように避け、そうでなければ粗いほとんどまっすぐなルートを計画し、あなたの道をかみます。山があることを知らない限り、まっすぐ歩いてください。
デイモン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.