Altıgen ızgarada aralık gösteriliyor


10

Durum şu.

Altıgen tahta ve üzerinde bir birim var, hız veya hareket değeri ile 4.Farklı arazi farklı bir maliyete sahiptir.Birime tıkladığımda, oyun bana bir hareket aralığı göstermelidir.

Benim çözümüm, A * pathfinding ile 4 aralığında her hex kontrol etmekti ve yol maliyeti 4'ten az ise, bu hex aralıkta idi. Son olarak oyun bana bu ünitenin aralığını güzel bir şekilde gösterdi.

Sorum şu: Onaltılık ızgaralar veya kare ızgara üzerinde aralık aramak için başka bir çözüm var mı, çünkü benim çözümümde yaptığımla gerçekten gurur duysam bile, bence abartılı bir şey mi var :) :))

Bu soruyu bana sormak için ne yapmalıyım? Birim hızı 4 veya 6 veya 8 olduğunda, bilgisayarım için hesaplama aralığına zamanın gerçekten iyi olduğunu fark ettim, ancak hız 10 ve daha fazla olduğunda, hesaplamak için birkaç saniye beklemem gerektiğini fark ettim. .Well gerçek oyunlarda böyle bir şey görmüyorum ve benim A * pathfinding oldukça iyi optimize edilmiş, bu yüzden benim çözümümün yanlış olduğunu düşünüyorum.

Yanıtlarınız için teşekkürler.


1
Byte56 ile ilk genişlik arama algoritmasının iyi bir çözüm olduğu konusunda hemfikirim. Bu, yaratıcı olmaya çalışmamanız gerektiği anlamına gelmez, ancak iyi bilinen algoritmalar, iyi uygulanan bir yöntemdir.
theJollySin

Yanıtlar:


11

A * 'nın biraz abartı olduğunu, ancak çok fazla olmadığını doğru söylüyorsunuz. Sizin gibi gecikmeler görmemelisiniz. A * gerçekten sadece değiştirilmiş bir Dijikstra algoritmasıdır . Bir son konum kullanmadığınızdan (son konumunuz "gidebildiğiniz kadar uzak" olduğu için), ekli sezgisel yöntemle A * kullanmak gerekli değildir. Sadece Dijikstra veya basit bir genişlik kullanarak ilk arama yeterli olacaktır.

Örneğin, Dikikstra her yöne eşit olarak yayılacaktır:

resim açıklamasını buraya girin

(Basit bir ilk arama buna benzer görünecektir)

Her bir düğüme seyahat maliyetini takip edin. Bir düğüm maksimum seyahat maliyetine ulaştığında, bağlı düğümlerini daha fazla işlemeyin. (Düğümlerin aşağıdaki duvara girdiği yere benzer).

Yalnızca 10 düğümde performans sorunları yaşıyorsanız, düğümlere nasıl eriştiğinize bakmak istersiniz. Geniş bir ilk arama, gözle görülür bir gecikme olmadan yüzlerce düğümü gezebilmelidir (kesinlikle birkaç saniye değil). Hızlı geçiş için dünyanızın basit bir versiyonunu grafik formatında saklamayı düşünün.


BFS kullanarak ve engelleri / farklı ağırlıkları dikkate alarak iki düğüm arasındaki mesafeyi bulabilir misiniz?
Luke B.6

Düğümler arasında hareket etmenin maliyeti çoğunlukla önceden hesaplanmalıdır. Maliyet BFS kullanılarak hesaplanmaz, BFS düğümleri dolaşmak için bir algoritmadır. Bir düğümden diğerine seyahat etmenin maliyetini nasıl belirlediğiniz, düğümleri nasıl geçtiğinizden bağımsızdır.
MichaelHouse

Teşekkürler, şimdi neden düşüncelerimin yanlış olduğunu görüyorum, bunun anahtarı "Bu bir son konum kullanmamanızdan (son konumunuz" gidebildiğiniz kadar "olduğu için)" ifadesiydi. Bir son konumu vardı, bu birimdi. Sorunu yanlış yönden çözdüm.İlk önce sınırı belirledim ve oradan birimime geri döndüm, bu şekilde muhtemelen aynı düğümlerden birçok kez geçtim. Hızım arttığında, hesaplama sayısı da çok artar. Bana gösterdiğiniz şekilde, her zaman düğümü bir kez ziyaret edeceğim. Sadece yanlış bakış açım vardı, gerçekten teşekkürler, bu çok basitleştirin.
user23673

4

Amit Patel, sitesinde menzil elde etmek için mükemmel bir kaynak sağladı . Makalede, bir aralıktaki altıgen döşemeleri toplamak için aşağıdaki algoritmayı kullanır:

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

Bu, altıgen ızgarayla hizalanmış sınırlar oluşturur:

resim açıklamasını buraya girin

Bu, tüm altıgenleri merkez altıgenin belirli bir mesafesindeki bulacaksınız, eğer engelleri göz önünde bulundurmak istiyorsanız, önce diğer cevabımdan önce genişlik aramasını kullanın.


1

Herkes ihtiyacı varsa, İşte Patel algoritmasının C # uygulaması:

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;
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.