Altıgen ızgarayı n oyuncu arasında eşit olarak nasıl bölebilirim?


15

Basit bir altıgen ızgara tabanlı oyun yapıyorum ve haritanın oyuncular arasında eşit olarak bölünmesini istiyorum. Harita rastgele oluşturuldu ve oyuncuların nispeten küçük alanlara sahip yaklaşık eşit miktarda hücreye sahip olmasını istiyorum. Örneğin, haritada dört oyuncu ve 80 hücre varsa, her bir oyuncunun yaklaşık 20 hücresi olurdu (tam doğru olması gerekmez). Ayrıca, her oyuncu dörtten fazla komşu hücreye sahip olmamalıdır. Yani, harita oluşturulduğunda, en büyük "parçalar" her biri dört hücreden fazla olamaz.

Bunun iki veya üç oyuncu için her zaman mümkün olmadığını biliyorum (bu "haritayı renklendirme" problemine benziyor) ve bunun için başka çözümler (sorun yerine çözen haritalar oluşturmak gibi) yapmakta sorun yok. Ancak, dört ila sekiz oyuncu için bu soruna nasıl yaklaşabilirim?


Yanıtlar:


3

Ben bunu yapardım:

  1. Tüm hücreleri rastgele oyunculara atayın. Büyük haritalarda bu, tüm oyuncular için oldukça eşit sayıda karo üretme olasılığı yüksek olmalıdır, daha küçük haritalarda muhtemelen bazı düzeltmeler yapmanız gerekecektir.
  2. Çok büyük parçalar ayırın. Yapılacak en kolay şey, tüm döşemeleri parçalar halinde almak ve her döşemeyi rastgele atamak olacaktır.
  3. Dengesiz sayıda hücre olması durumunda (örneğin A oyuncusu 24 hücreye, B oyuncusu 16'ya sahiptir), fazla temsil edilen oyunculardan az temsil edilen oyunculara birkaç hücreyi yeniden atayın.
  4. Parçalar için tekrar kontrol edin. Adım 3 yeni parçalar getirdiyse, adım 2'ye geri dönün. Değilse, güzel harita!

PS Bu sorunun imkansız olduğunu düşünmüyorum, harita renklendirme problemi oldukça farklı (bir şey için tersi, şekiller-> renkler yerine renkler-> döşeme atamaları).
Junuxx

Bu yaklaşımı biraz seviyorum, ancak alan boyutlarını dengelemeye çalışarak uzun süre çalışması mümkün değil mi?
manabreak

1
@manabreak: Denemek için bir şey yaptım . 2. adıma küçük bir değişiklik yapıldığında (rastgele yeniden atamak yerine tüm oyuncular arasında geçiş yaparak yeniden ata) oldukça iyi çalışır. Zamanım olduğunda yazmaya çalışacağım.
Junuxx

1
Tam da aradığım şey bu. :)
manabreak

1

Varsayarsak bir hexmap sahip ntoplam hücreleri ve poyuncuların, p <= nbu mücadele için en iyi yol geçer, döner turnuva dağıtımı yoluyla hücresel otomat (CA).

Bafllatma

Rastgele (ve / veya harita merkezinden uzaklık gibi bir veya başka buluşsal yöntemler kullanarak) her oyuncu için bir başlangıç ​​hücresi seçin. Çünkü p <= nbu bir problem olmamalı.

Hücresel otomata

Altıgen hücreleriniz arasında tam bağlantıya ihtiyacınız vardır. Hücre başına 6 komşu dizi öneririm:

class Cell
{
   //... other members...
   Cell[6] neighbours = new Cell[6];
}

Sabit boyutlu dizilerin kullanılması, bir liste veya vektörün olmayacağı hücreler arasında topografik yönler kavramının var olmasını sağlar. Belirli gezinme işlemlerini kolaylaştırabileceği için bunu öneriyorum.

Ayrıca, hexmap'inizi satır başına ofsetleri olan bir 2D dizide saklayabilirsiniz. Bununla birlikte, bu, her diğer satırdaki geometrik ofset nedeniyle, hücre başına bir komşu dizi depolamaktan biraz daha az sezgisel olabilir.

Her hücrenin komşu olan her şeye bağlı olduğundan emin olun. Tam hexmap'i oluştururken bu satır satır, hücre hücre yapabilirsiniz. PS Sonuçta dikdörtgen olmayan bir şekilde sınırlanmış bir hexmap istiyorsanız, negatif boşluklar oluşturmak ve böylece organik harita taslağı oluşturmanıza izin vermek için tek tek hücreleri ve bu hücrelere referansları kaldırabilirsiniz.

Round-robin dağılımı

pseudocode:

count number of neutral cells in entire map, minus those starting cells taken by players
while neutral cells remain (or while true)
   for each player
      if player has not yet reached expected territory size in cells
         for each cell already constituting this player's territory
           if territory can grow by one cell into a neutral neighbour
              grow into neighbour
              reduce neutral cell count for entire map by one
              if no more neutral cells remain in map
                 break out of outermost while loop immediately
              else
                 continue to next player immediately
begin game

Bu algoritma, oyuncunun topraklarının hala geçerli büyüme alanına sahip olması şartıyla, her oyuncuya toprağını birer teker artarak yetiştirme şansı verecektir . Belirli oyuncular ayrıca büyüyen engellenir ise, algoritma buna rağmen oyuncuların toprakları büyümeye devam edecektir yapmak hala geçerli büyüyen alana sahip. Bir oyuncu bir sınıra ulaştığında her oyuncuyu aynı sayıda hücreyle kolayca kısıtlayabilirsiniz, ancak istenirse bunu anlamanız için yeterince kolay olmalıdır.

Bu, her oyuncu için maksimum boyutta "ev bölgeleri" sağlayacaktır. Ek olarak "ada" bölgelerine sahip olmak istiyorsanız, o oyuncu için hücre sayım kotasını yerine getirmek için, bir oyuncu büyümek için yerel alan tükendiğinde, nötr hücreler listesinden yeni bir başlangıç ​​hücresi seçebilir ve aynı "büyüme" süreci ile devam edin. Bu şekilde, her oyuncu için rastgele gürültü yerine güzel boyutlu, tutarlı adalar kümesiyle sonuçlanacaksınız.


Algoritmanız için mükemmel belgeler ve sözde kod sağlarken, bunun sorucının sorduğu soruya uyduğundan emin değilim. Soru 'en büyük' ​​parçalar 'dan her biri dört hücreden fazla olamaz', oysa algoritmanız mümkün olduğunca büyük bir bağlı grup oluşturur.
fnord

@fnord Hayır, değil. Cevabımı düzgün okumadın. Açıkçası pseudocode: "oyuncu henüz hücrelerde beklenen bölge boyutuna ulaşmamışsa" bir sınır koymak. Lütfen downvote'unuzu kaldırın. Yorum ve aşağı oylamadan önce durumun böyle olduğunu kendiniz tatmin etmek için sorudaki düzeltme geçmişini kontrol etmekten çekinmeyin.
Mühendis

Soru, "her bir kullanıcı için haritanın beklenen bir kısmına sahip olmak için" en fazla dört bitişik hücre "olmasını ister. Bu, benim için, e, Risk oyunlarının haritayı tüm oyuncular için rastgele nasıl dağıttığına benzeyen bir şey yapacağını ima ediyor. Cevabınız haritayı "maksimum büyüklükteki" ana bölgeler "e böler. Doğru, beklenen bölge boyutu sınırına ulaşıldığında algoritmanız durur, ancak daha sonra metinde bahsettiğiniz halde, bu oyuncunun yeni "adalar" alması için bir yol göremiyorum.
fnord

@fnord Mantığınız hatalı. Son cümlede, algoritmamın ada boyutunda durduğunu itiraf edersiniz nve daha sonra "bir yol görmüyorsunuz" diyerek yine de kendimi ile çelişirsiniz, ancak ben "daha sonraki metinde [adaları nasıl edinebilirim" den bahsederim ". Soruyu cevapladım mı yoksa cevaplamadım mı? Bu genelleştirilmiş algoritma, hücreleri ( n1 ile sınırlayarak ) saçmak veya adalar oluşturmak için (n> 1 ayarlanarak) kullanılabilir. Yani, tek bir algoritmada, sadece saçılma yeteneğine değil, aynı zamanda gruplama yeteneğine de sahipsiniz. Bu nasıl yok değil OP'ın soruya cevap? Bir aşağı oy nasıl olur?
Mühendis

Yukarıdaki yorumumu düzenlerdim, ama artık çok geç. " Algoritmanızda bir yol göremiyorum ". yine de sonraki metinde bu kavramdan bahsediyorsun.
fnord

0

Başka bir yaklaşım, 'adil' ama düzenli bir dağıtımla başlamak ve daha sonra adaleti kaybetmeden düzenliliği bozmak için Simüle Tavlama'ya benzer bir yaklaşım kullanmak olacaktır:

  • Izgaranızın tüm hücrelerine düzenli bir düzende renkler atayarak başlayın (örn. İlk satırda tekrar eden bir '123412341234' kalıbı, ardından bir sonraki bölümde '341234123412' kalıbı bulun). Bu harita, özellikle şekli bozuk ise renklerin dengesiz dağılımına yol açabilir, ancak bulmak mümkün olmalıdır yüzden, sabit bir harita ile başlıyoruz 'Küstah bazı bunun equidistributed düzenli renklendirme.
  • Ardından, istediğiniz kadar adım için aşağıdakileri tekrarlayın (gerçek bir 'doneness' kriteri yoktur, bu nedenle deneme size minimum makul adım sayısının ne olduğunu söyleyecektir):
    • Izgaranın iki öğesini rastgele seçin
    • Aynı renge sahiplerse, tekrar deneyin (aksi halde bir anlamı yoktur, çünkü o zaman takas yapmak bir opsiyonu olmayacaktır. Sadece aynı renge çarpma şansınızın 1 / 4'ü ve aynı renge çarpma şansı 1 / 16'dır. arka arkaya iki kez, bu yüzden asla çok fazla yeniden denemek zorunda değilsiniz)
    • Bu iki öğenin renklerini geçici olarak değiştirin
    • Takastan sonra elemanların konumlarında yeni oluşan bölgelerin boyutlarını test edin:
      • takasın o rengin bir bölgesinin ne kadar büyük olacağını belirlemek için her bir öğenin yeni noktasından dışarıya basit bir sel doldurun.
    • Bu iki bölgeden herhangi biri eşik değerinizden daha büyükse, geçici değişimi geri alın; aksi takdirde, iki öğenin renklerini 'sonlandırın'.

Buradaki anahtarlar, iki noktayı değiştirdiğiniz gerçeğinin, renkleri asla dengesizleştirmemeniz ve benzer şekilde takasınızı sonlandırmadan önce yaptığınız testin asla çok büyük bölgeler oluşturmamanızı sağlamasıdır. Izgarayı görüntülemek için bazı araçlarınız varsa, tekrarlanan takaslarla bölgelerini nasıl 'inşa ettiğini' izlemek için bu işlemi görselleştirebilirsiniz.

Eşzamanlı olarak eşit dağıtılmış bir normal renklendirme ile başlayamıyorsanız, yine de renklendirmeyi eşit dağıtmaya benzer bir şey yapabilmeniz gerekir: renklendirmeniz eşit dağıtılmamışken, rastgele bir öğe seçin; daha fazla temsil edilen renklerden biriyse, rengini geçici olarak temsil edilen renklerden birine ayarlayın ve ardından yeni rengin çok büyük bir bölgesi oluşturmadığından emin olun.


Stokastik yaklaşımlar yetersizdir. Benim gibi düşünülmüş adımlar atan bir yaklaşım için çalışma zamanı n harita hücresi için O (n) 'ye yaklaşır. Algoritmanız için, O (n * m), burada m ada başına istenen hücre sayısıdır (aslında her potansiyel ada için). Kolayca tahmin edilebilir bir çalışma süresine sahip algoritmaları hedeflemek her zaman en iyisidir. Gelişigüzel üretilen bir haritayı düzeltmek yerine, ilk etapta kırılmayan veya gelişigüzel olmayan bir haritayı n adımda oluşturmak daha iyi, böylece kontrollü, verimli bir süreç sürdürmek.
Mühendis
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.