Anzeige des Bereichs auf dem sechseckigen Gitter

10

Hier ist die Situation.

Ich habe ein sechseckiges Brett und eine Einheit mit Geschwindigkeit oder Bewegungswert. 4. Unterschiedliches Gelände hat unterschiedliche Kosten. Wenn ich auf die Einheit klicke, sollte mir das Spiel eine Bewegungsreichweite anzeigen.

Meine Lösung bestand darin, jedes Hex im Bereich von 4 mit A * -Pfadfindung zu überprüfen. Wenn die Pfadkosten weniger als 4 betrugen, befand sich dieses Hex im Bereich. Das Spiel zeigt mir schließlich die Reichweite dieser Einheit.

Meine Frage ist: Gibt es eine andere Lösung, um auf Hex- oder Quadratgittern nach Reichweite zu suchen, denn selbst wenn ich wirklich stolz auf das bin, was ich in meiner Lösung getan habe, denke ich, ist es ein wenig übertrieben? :))

Was hat mich dazu gebracht, diese Frage zu stellen? Ich bemerkte, dass bei einer Geschwindigkeit von 4 oder 6 oder sogar 8 die Zeit bis zur Rechenreichweite für meinen Computer wirklich gut war, aber bei einer Geschwindigkeit von 10 und mehr bemerkte ich, dass ich einige Sekunden warten musste, um zu berechnen Nun, in echten Spielen sehe ich so etwas eher nicht und meine A * -Pfadfindung ist ziemlich gut optimiert, also denke ich, dass meine Lösung falsch ist.

Vielen Dank für alle Antworten.

user23673
quelle
1
Ich stimme Byte56 zu, dass ein breiter erster Suchalgorithmus eine gute Lösung ist. Das soll nicht heißen, dass Sie nicht versuchen sollten, kreativ zu sein, aber was bekannte Algorithmen angeht, ist es ein guter, der gut zutrifft.
TheJollySin

Antworten:

11

Sie haben Recht, dass A * ein wenig übertrieben ist, aber nicht viel. Sie sollten keine Verzögerungen wie Sie sehen. A * ist wirklich nur ein modifizierter Dijikstra-Algorithmus . Da Sie keine Endposition verwenden (da Ihre Endposition nur "so weit wie möglich" ist), ist die Verwendung von A * mit der hinzugefügten Heuristik nicht erforderlich. Es reicht aus, nur Dijikstra oder eine einfache Breitensuche zu verwenden.

Zum Beispiel wird sich Dikikstra gleichmäßig in alle Richtungen ausbreiten:

Geben Sie hier die Bildbeschreibung ein

(Eine einfache erste Suche sieht ähnlich aus.)

Behalten Sie die Kosten für die Fahrt zu jedem Knoten im Auge. Sobald ein Knoten die maximalen Reisekosten erreicht hat, verarbeiten Sie seine verbundenen Knoten nicht weiter. (Ähnlich wie dort, wo die Knoten in die Wand darunter laufen).

Wenn bei nur 10 Knoten Leistungsprobleme auftreten, sollten Sie sich ansehen, wie Sie auf die Knoten zugreifen. Eine umfassende erste Suche sollte in der Lage sein, Hunderte von Knoten ohne merkliche Verzögerung (sicherlich nicht einige Sekunden) zu navigieren. Speichern Sie eine einfache Version Ihrer Welt in einem Diagrammformat, um sie schnell zu durchlaufen.

MichaelHouse
quelle
Können Sie den Abstand zwischen zwei Knoten mithilfe von BFS unter Berücksichtigung von Hindernissen / unterschiedlichen Gewichten ermitteln?
Luke B.
Die Kosten für das Verschieben zwischen Knoten sollten größtenteils vorberechnet werden. Die Kosten werden nicht mit BFS berechnet, BFS ist ein Algorithmus zum Durchlaufen der Knoten. Wie Sie die Kosten für das Reisen von einem Knoten zum anderen bestimmen, hängt davon ab, wie Sie die Knoten durchqueren.
MichaelHouse
Danke, jetzt verstehe ich, warum mein Denken falsch war. Der Schlüssel dafür war die Aussage "Da Sie keine Endposition verwenden (da Ihre Endposition nur" so weit wie möglich "ist)). In meiner Lösung i hatte eine Endposition, es war die Einheit. Ich habe das Problem nur aus der falschen Richtung gelöst. Zuerst habe ich die Grenze bestimmt und bin dann von dort zu meiner Einheit zurückgekehrt, auf diese Weise bin ich wahrscheinlich viele Male durch dieselben Knoten gegangen Wenn sich meine Geschwindigkeit erhöht, steigt auch die Anzahl der Berechnungen erheblich. So wie Sie es mir zeigen, werde ich den Knoten immer einmal besuchen. Ich hatte nur eine falsche Sichtweise, wirklich danke, dies vereinfacht viel.
user23673
4

Amit Patel hat eine hervorragende Ressource bereitgestellt , um Reichweiten auf seiner Website zu erhalten . In dem Artikel verwendet er den folgenden Algorithmus zum Sammeln von Hex-Kacheln innerhalb eines Bereichs:

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)))

Dadurch werden Grenzen erstellt, die am Hex-Raster ausgerichtet sind:

Geben Sie hier die Bildbeschreibung ein

Dadurch werden alle Felder in einem bestimmten Abstand vom mittleren Feld gefunden. Wenn Sie Hindernisse berücksichtigen möchten, verwenden Sie die breiteste erste Suche aus meiner anderen Antwort.

MichaelHouse
quelle
1

Falls jemand es braucht, hier ist die C # -Implementierung des Patel-Algorithmus:

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;
    }
Allan Haugsted
quelle