Altıgen bir ızgara üzerinde en kısa yolu bulma


14

Bazı simülasyon öğeleri olan sıra tabanlı bir oyun yazıyorum. Şu anda takıldığım görevlerden biri yol bulmak. Yapmak istediğim şey şu anki x, y ve hedefi x, y'yi kullanarak bir AI maceraperestini bir karo hedefine bir kata yaklaştırmak.

Bunu kendim anlamaya çalışırken, 4 yönü kullanarak problem belirleyebilirim

dx = currentX - targetY
dy = currentY - targetY

ancak 6 yönden hangisinin aslında "en iyi" veya "en kısa" rota olduğunu nasıl belirleyeceğimi bilmiyorum.

Örneğin, şu anda kurulum şekli olarak, Doğu, Batı, NE, NW, SE, SW kullanıyorum, ancak NE döşemesine ulaşmak için sadece NW'yi hareket ettirmek yerine önce Doğu'ya sonra NW'ye geçiyorum.

Umarım bunların hepsi başıboş değildir. Beni başlatmak için sadece bir veya iki bağlantı bile iyi olurdu. Bulduğum bilgilerin çoğu, ızgaraları çizmek ve gerekli garip koordinat sistemini tıkamaktır.


5
A * grafiğinizin şekline bakılmaksızın size en kısa yolu verir (ızgara, altıgen, serbest biçimli ..)
Jari Komppa

Yanıtlar:


21

Birkaç cevap!

Altıgen tabanlı çapraz geçiş için en sık gördüğüm koordinat sistemi, oyuncunun her normal NSEW yönünde, NW ve SE'de hareket edebildiği bir sistemdir. Sonra her satırı yarım kare ofseti oluşturursunuz. Örnek olarak, (2,7) konumu (1,7), (3,7), (2,6), (2,8) ve garip olanlara bitişik kabul edilir: (1,6) ve (3,8). Bu arada, (2,7) 'nin ekranın ortasında işlendiğini varsayarsak, (2,6) yukarı ve sağa, (2,8) aşağı ve yukarı doğru işlenir -sol, (1,7) ve (3,7) sırasıyla sola ve sağa parantez içerecek ve (1,6) ve (3,8) kendilerini sırasıyla sol-üst ve sağ-alt olarak yerleştirecektir.

Ne demek istediğimin bir diyagramı:

resim açıklamasını buraya girin

Bunu bu şekilde yapıyorsanız, en kısa doğrudan yolu bulmak zor değildir - hedefinizi kardinal bir eksen boyunca aşmadan maksimum KB / GD mesafesine gidin, ardından doğrudan bu eksen boyunca hedefe gidin.

Ama elbette bu sizi doğruca dağlardan veya diğer geçilmez arazilerden geçirecek. Henüz sormadığınız bir soruyu cevaplamak için: A * Arama Algoritması , yol bulma için yaygın ve makul derecede iyi bir yaklaşımdır. Sadece garip ızgara olmayan düzenleri ele almakla kalmayacak, aynı zamanda engellerle ve hatta engelli / yavaş zeminle mutlu bir şekilde başa çıkacaktır.


A * arama algoritmasına bağlantı için teşekkürler. Iwew ve nw / se arasında geçiş yapabildiğini hayal edebildiğim tek yol eğik bir hex. Bu kafamda garip görünüyor. Beni bunun bir örneğine bağlayabilir misin?
Timothy Mayes

4
Oluşturduğunuz görüntünün iç yapıya çok fazla benzemesi gerekmediğini söylüyorum. Dahili olarak NSEW ve NW / SE kullandığınızı, ancak kullanıcıya bir ızgaramış gibi görüntülediğinizi öneriyorum . Orijinal
yanıta

2
Onaltılık bir ızgara için ilginç temsil. Genellikle pürüzlü bir desen yaparım, bu yüzden bitişiklik tek ve çift sıralar için farklıdır. Bu, yol aramada ek bir minimum karmaşıklık getirir, ancak bir boyutlu diziyi daha verimli bir şekilde kullanır (tüm oyun alanının bir dikdörtgen olduğunu varsayalım.
Panda Pyjama 8

2
@PandaPajama: pürüzlü dikdörtgen haritaları verimli bir şekilde saklamak için daha iyi çalışır; pürüzlü olmayan koordinatların bu hile
sağlayabilirsiniz

2
@PandaPajama, kullanabileceğiniz başka bir ilginç numara var - koordinatlar için tırtıklı olmayan temsili kullanabilirsiniz, ardından "jagged" yöntemini kullanan bir şeyin arkasında veri depolama desteğini soyutlayabilirsiniz. Pürüzlü olmayan koordinat sistemi ile başa çıkmak çok daha kolay olduğunu gördüm ama elbette soyutlandıktan sonra, arka uç işleri verimli hale getirmek için ne isterse yapabilir :)
ZorbaTHut

5

Ben sadece burada CodePlex.com onaltılık ızgara faydaları bir kütüphane postd var: https://hexgridutilities.codeplex.com/ Kütüphane yol bulma içerir (A- * a la Eric Lippert kullanarak) ve arasında otomatik dönüşüm için yararları içerir tırtıklı (Kullanıcı olarak adlandırılan) kordinler ve tırtıklı olmayan (Kanonik olarak adlandırılan) koordinatlar. Yol bulma algoritması, her bir düğüm için adım maliyetinin hem hex hem te altıgen girişine göre değişmesine izin verir (sağlanan örnek daha basit olsa da). Ayrıca, gölge yayınlama kullanılarak yükseltilmiş görüş alanı sağlanmıştır, [değiştir: kelimeler kaldırıldı].

İşte üç altıgen ızgaralı koordinat sistemi arasında kolayca dönüşen bir kod örneği:

static readonly IntMatrix2D MatrixUserToCanon = new IntMatrix2D(2,1, 0,2, 0,0, 2);
IntVector2D VectorCanon {
  get { return !isCanonNull ? vectorCanon : VectorUser * MatrixUserToCanon / 2; }
  set { vectorCanon = value;  isUserNull = isCustomNull = true; }
} IntVector2D vectorCanon;
bool isCanonNull;

static readonly IntMatrix2D MatrixCanonToUser  = new IntMatrix2D(2,-1, 0,2, 0,1, 2);    
IntVector2D VectorUser {
  get { return !isUserNull  ? vectorUser 
             : !isCanonNull ? VectorCanon  * MatrixCanonToUser / 2
                            : VectorCustom * MatrixCustomToUser / 2; }
  set { vectorUser  = value;  isCustomNull = isCanonNull = true; }
} IntVector2D vectorUser;
bool isUserNull;

static IntMatrix2D MatrixCustomToUser = new IntMatrix2D(2,0, 0,-2, 0,(2*Height)-1, 2);
static IntMatrix2D MatrixUserToCustom = new IntMatrix2D(2,0, 0,-2, 0,(2*Height)-1, 2);
IntVector2D VectorCustom {
  get { return !isCustomNull ? vectorCustom : VectorUser * MatrixUserToCustom / 2; }
  set { vectorCustom  = value;  isCanonNull = isUserNull = true; }
} IntVector2D vectorCustom;
bool isCustomNull;

IntMatrix2D ve IntVector2D, affine2D Graphics Vector ve Matrix'in [edit: homojen] tamsayı uygulamalarıdır. Vektör uygulamalarında son olarak 2'ye bölünme, vektörlerin yeniden normalleştirilmesidir; bu IntMatrix2D uygulamasında gömülebilir, ancak daha sonra IntMatrix2D yapıcılarına yönelik 7. argümanın nedeni daha az belirgindir. Mevcut olmayan formülasyonların birleşik önbellekleme ve tembel değerlendirmesine dikkat edin.

Bu matrisler durum içindir:

  • Altıgen tane dikey;
  • Kanonik ve Kullanıcı koordinatları için sol üstte, Özel koordinatlar için sol altta;
  • Y ekseni dikey olarak aşağı;
  • Dikdörtgen X ekseni yatay olarak; ve
  • Kuzeydoğu'ya kanonik X ekseni (yani, yukarı ve sağa, Y ekseninden 120 derece CCW).

Yukarıda bahsedilen kod kütüphanesi, onaltılık toplama için benzer şekilde zarif bir mekanizma sağlar (yani, bir fare tıklaması ile seçilen altıgenin tanımlanması).

Kanonik koordinatlarda, 6 kardinal yön vektörü, pürüzlü koordinatların asimetrisi olmadan, (1,0), (0,1), (1,1) ve bunların tüm altıgenler için ters çevrilmesidir.


Vaov! OP tarafından sorulan soruya / soruna cevap veren bir çalışma kodu kitaplığı yayınlamak için örnekler ve belgeler içeren net bir aşağı oy.
Pieter Geerkens

5
Ben downvoter olmasaydım (ve görgü kuralları genellikle bir downvote açıklayan bir yorum bırakmayı önerdiğinde), downvote'un (a) yazı reklamın çalınması ve (b) bir cevabın büyük kısmını diğer bağlantının çürümeye eğilimi olduğu ve SE sitelerinin kendi içinde kalmaya çalıştığı için bağlantının bir tarafı genellikle kaşlarını çatır. Burada sağlanan bilgiler ilginçtir, ancak kullanıcının sorusuna cevap vermez ve soruyu cevaplayabilecek tek bilgi bağlantının diğer tarafındadır.
Steven Stadnicki

Güzel nokta; teşekkür ederim. Gönderiyi, çoklu altıgen ızgara koordinatlarının nasıl verimli bir şekilde sürdürüleceği sorusunu ele alan alıntılarla genişlettim. Gönderilen kod kütüphanesi ücretsiz
Pieter Geerkens

Hata! Böl-by-2 sadece pozitif tamsayılar fo çalışır. (Tekrar teşekkürler, K&R.) Bunun yerine IntVector2D'deki Normalize () yöntemine yapılan bir çağrı kullanılmalıdır:
Pieter Geerkens

public IntVector2D Normalize() { if (Z==1) return this; else { var x = (X >= 0) ? X : X - Z; var y = (Y >= 0) ? Y : Y - Z; return new IntVector2D(x/Z, y/Z); } }
Pieter Geerkens

0

Bu, çözülmesi gereken çok fazla literatürün olduğu çözülmüş bir sorundur. Bildiğim en iyi kaynak Red Blob Games'te: https://www.redblobgames.com/grids/hexagons/ .

Kısacası, en olası neden yanlış koordinat sistemi ile başlamanızdır. A * algoritmasını uygulayan bir Küp koordinat sistemi kullanmak oldukça basittir. Yukarıdaki linkten canlı demoya bakın.

Eğer varsa , gerçekten başka bir sistemi kullanmak istiyorum, sonra ve gerektiğinde dönüştürür.

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.