六角形グリッドに範囲を表示


10

これが状況です。

六角形のボードとその上にユニットがあり、速度または移動値があります。4。異なる地形には異なるコストがあります。ユニットをクリックすると、ゲームに移動範囲が表示されます。

私の解決策は、4の範囲内の各ヘクスをA *パスファインディングでチェックすることでした。パスコストが4未満の場合、このヘックスは範囲内にありました。最後に、ゲームでそのユニットの範囲をうまく表示しました。

私の質問は、私が自分のソリューションでやったことを本当に誇りに思っているので、六角グリッドまたは正方形グリッドで範囲を検索する他のソリューションはありますか?私は思う、それは少し誇張されていますか?:))

ユニットスピードが4または6または8の場合、コンピューターのコンピューティング範囲までの時間は本当に良いことに気づきましたが、スピードが10以上の場合、計算に数秒待つ必要があることに気付きました実際のゲームでは、私はこのようなものを見ることはなく、私のA *パスファインディングはかなり最適化されているので、私の解決策は間違っていると思います。

返信ありがとうございます。


1
幅優先検索アルゴリズムが優れたソリューションであるというByte56に同意します。これは、創造的になることを試みるべきではないということではありませんが、よく知られているアルゴリズムに関しては、それはうまく適用できる優れたアルゴリズムです。
theJollySin

回答:


11

A *は少しやり過ぎですが、それほど多くはないというのはあなたの言うとおりです。あなたがそうであるようにあなたは遅れを見ることはありません。A *は実際には、修正されたDijikstraのアルゴリズムです。終了位置を使用していないため(終了位置は「可能な限り」)、A *を追加のヒューリスティックで使用する必要はありません。Dijikstraを使用するか、単純な幅優先検索で十分です。

たとえば、ディキクストラはすべての方向に均等に広がります。

ここに画像の説明を入力してください

(単純な幅優先検索はこれに似ています)

各ノードに移動するためのコストを追跡します。ノードの移動コストが最大になった後は、接続されているノードをこれ以上処理しないでください。(ノードが下の壁に突き当たる場所に似ています)。

わずか10ノードでパフォーマンスの問題が発生している場合は、ノードへのアクセス方法を確認する必要があります。幅優先の検索では、数百のノードを大幅な遅延なしにナビゲートできるはずです(確かに数秒ではありません)。トラバースをすばやく行うために、世界の単純なバージョンをグラフ形式で保存することを検討してください。


BFSを使用して、障害物/異なる重みを考慮に入れて、2つのノード間の距離を見つけることができますか?
ルークB.

ノード間を移動するコストは、ほとんどの場合、事前に計算する必要があります。コストはBFSを使用して計算されません。BFSはノードをトラバースするためのアルゴリズムです。あるノードから別のノードに移動するためのコストを決定する方法は、ノードのトラバース方法とは無関係です。
MichaelHouse

おかげで、私の考えが間違っていた理由がわかります。そのための鍵は、「最終位置を使用していないため(最終位置が「できるだけ」なので)」という私の解決策でした。終了位置があり、それがユニットでした。私は問題を間違った方向から解決しました。最初に境界を決定し、次にそこから自分のユニットに戻ったので、おそらく同じノードを何度も通過しました。私の速度が上がると、計算の数も多くなります。あなたが見せてくれるように、私は常にノードを一度訪問します。私は間違った視点を持っていました、本当にありがとう、これはたくさん単純化しました。
user23673

4

アミットパテルは彼のサイトで範囲取得するための優れたリソースを提供しています。この記事では、彼は次のアルゴリズムを使用して、範囲内の16進タイルを収集します。

for each -N  Δx  N:
    for each max(-N, x-N)  Δy  min(N, x+N):
        Δz = xy
        results.append(H.add(Cubex, Δy, Δz)))

これにより、16進グリッドと位置合わせされた境界が作成されます。

ここに画像の説明を入力してください

これにより、中央のヘクスから一定の距離内にあるすべてのヘクスが検索されます。障害物を考慮したい場合は、他の回答から幅優先検索を使用してください。


1

誰かがそれを必要とする場合のために、ここにパテルのアルゴリズムのC#実装があります:

IEnumerable<Hex> GetRange(Hex center, int range)
    {
        var inRange = new List<Hex>();
        for (int q = -range; q <= range; q++)
        {
            int r1 = Math.Max(-range, -q - range);
            int r2 = Math.Min(range, -q + range);
            for (int r = r1; r <= r2; r++)
            {
                inRange.Add(center.Add(new Hex(q, r, -q - r)));
            }
        }

        return inRange;
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.