Genera regioni uguali in una mappa esadecimale


13

Prendendo ad esempio una grande mappa esadecimale (X per Y), come posso dividerla in N regioni di esagoni collegati per simulare i paesi?

L'obiettivo è generare una mappa esadecimale che assomigli a una vera mappa della vita con paesi con forme diverse ma dimensioni uguali.

Risposte:


13

Hai provato l'algoritmo di Lloyd ? La procedura è piuttosto semplice e genererà regioni dall'aspetto abbastanza regolare (a seconda di quante iterazioni si eseguono).

  1. Affianca la mappa con esagoni vuoti per iniziare.
  2. Scegli N esagoni a caso. Questi rappresenteranno il "centro di massa" per ciascun paese.
  3. Contrassegna ogni esagono con l'esagono centrale a cui è più vicino ( diagramma di Voronoi ). Il Paese i è l'insieme di tutti gli esagoni più vicini all'i esimo centro.
  4. Calcola il nuovo centro di massa per ogni paese.
  5. Ripetere i passaggi 3 e 4 tutte le volte che si desidera appianare le regioni generate.

Non devi correre molto a lungo per produrre una bella mappa. Questo esempio richiede solo tre iterazioni.


Molto bello, e +1 per avere un esempio in particolare, ma sarei un po 'preoccupato che siano un po' troppo regolari! Detto questo, i risultati sembrano davvero meravigliosi in particolare su quella scala, ed è anche un modo eccellente di seminare altri metodi.
Steven Stadnicki,

1
Il mio esempio è stato ispirato da un post sul blog sulla generazione di mappe poligonali . L'autore ha aggiunto del rumore ai bordi di ogni regione per dare un aspetto più frastagliato (scorrere verso il basso per vederlo). Dovresti usare molti più esagoni di me per renderlo un'opzione praticabile, ma è certamente fattibile.
Michael Kristofik,

3

Un modo semplice per provare.

  1. Seleziona casualmente gli nesagoni. Ognuno inizierà un gruppo.
  2. Per ogni gruppo prova ad espandere l'esagono iniziale in una direzione casuale.
  3. Se tutti gli esagoni attorno all'esagono scelto sono occupati, segna come toccato, cambia esagono.
  4. Ripeti fino a quando ciascun gruppo è lungo 20 esagoni o non ha più spazio per espandersi (tutti gli esagoni toccati).

Non ho provato ma questo dovrebbe generare isole ed evitare in qualche modo parentesi graffe lunghe e sottili. Inoltre, molto probabilmente ci saranno i confini dei vicini, ma non necessariamente ognuno sarà in contatto con l'altro, che la densità dipenderà dal valore di n.
Alcuni gruppi potrebbero anche essere messi in curva da altri e raggiungere dimensioni inferiori a 20, puoi assicurare lo spazio cresciuto generando gli esagoni di avviamento ad una distanza minima l'uno dall'altro.
Prova e modifica se necessario.


Inoltre, non correlato a questo problema ma molto, molto utile per lavorare con gli esagoni, visita questa pagina: http://www.redblobgames.com/grids/hexagons/#basics
Aggrega un sacco di informazioni esadecimali in un unico posto con una bella vista.


Probabilmente dovrebbe includere un meccanico per il gruppo A per dare nodi al gruppo B, se il gruppo B confina con il gruppo A e non ha altro posto dove andare. Finché il gruppo A ha spazio vuoto in cui espandersi per sostituire i nodi persi. Quindi non importa da dove abbiano iniziato. Dal momento che questo si comporta come un "ritiro".
MichaelHouse

Sto forse pensando di iniziare un paese alla volta, formare prima i gruppi d'angolo, poi quelli che danno i bordi darebbero quello che voglio. Lo proverò quando torno a casa.
MadCatPT,

@ Byte56 Sì, in realtà ho pensato a qualcosa del genere un po 'durante il mio pranzo. Se il gruppo alle spalle non ha un posto dove crescere, basta prendere un esagono di un altro gruppo e lasciare che quel gruppo trovi uno spazio vuoto alla prossima iterazione. Dovrebbe avere una certa sicurezza per evitare che 2 gruppi con le spalle al muro si oppongano all'infinito.
Petervaz,

I paesi reali hanno spesso confini su fiumi o montagne. Mentre ti stai espandendo in una direzione casuale, potresti provare a diminuire la probabilità di espandersi se l'esagono successivo si trova sull'altro lato di un fiume o di una cresta montuosa.
entro il

@amitp Se l'OP si aspettasse che quei fattori fossero contabilizzati, probabilmente li avrebbe menzionati. Non sto assumendo, sto solo lavorando all'interno delle premesse originali.
Petervaz,

2

Penso sicuramente che un qualche tipo di struttura grafica lo renderebbe possibile. Fondamentalmente creare un bordo tra due nodi esadecimali se sono uno accanto all'altro per simulare l'intera mappa. Tuttavia, non sono sicuro dell'algoritmo esatto per generare un "paese" all'interno di quella mappa. Il fatto è che, a seconda di come si desidera "guardare" il paese, sarebbero necessari diversi algoritmi.

Dalla parte superiore della mia testa, consiglierei di scegliere un punto e di spostarmi verso l'esterno da lì, scegliendo una tessera casuale all'interno del tuo "paese in crescita" che ha una tessera adiacente che non fa parte del paese.

Un modello di strategia potrebbe essere utilizzato per cambiare gli algoritmi a seconda del tipo di paese desiderato. http://en.wikipedia.org/wiki/Strategy_pattern ovvero vuoi un paese dalla costa sottile come il Cile? O vuoi qualcosa che sia più rotondo e contenuto?

Le proprietà del grafico possono anche permetterti di modificare l'aspetto del "paese" finale: http://it.wikipedia.org/wiki/Eccentricity_(graph_theory)

Vuoi un Paese grande? Modifica le proprietà del grafico e forza il Paese generato (che è solo un grafico) ad avere le proprietà che gli conferiscono un "aspetto" che desideri.

Ultimo ma non meno importante, i grafici saranno anche molto utili per definire i confini tra i paesi. È possibile creare un grafico con una connessione tra due nodi se i paesi confinano tra loro. Questo potrebbe essere utile per qualche tipo di partizionamento nel tuo gioco e ti permetterà di ottimizzare alcune cose durante lo sviluppo.


2

Una piccola nota: dici "sembra una vera mappa della vita con paesi di forme diverse ma di dimensioni uguali), ma i paesi" reali "hanno dimensioni molto diverse anche all'interno di determinate regioni - anche i paesi" grandi "d'Europa possono variare enormemente, con ad esempio la Francia che è più del doppio dell'Italia. Detto questo, ci sono ovviamente regioni di gioco in cui cercare di mantenere le dimensioni all'incirca uguali - basta essere consapevoli del fatto che una piccola variazione qui è probabilmente una buona cosa!

Il mio approccio iniziale al problema sarebbe quello di "evolvere" (piuttosto che "crescere") le tue regioni:

  • Inizia con una divisione concreta della mappa in blocchi di dimensioni approssimativamente uguali per linee rette (ad esempio, se volevi 6 paesi, potresti dividere la mappa in tre sezioni orizzontali, quindi dividere ciascuna di quelle sezioni "sulla diagonale" in due pezzi). Questo è ovviamente facile da fare a livello di codice, soprattutto perché non deve essere molto preciso (in effetti, probabilmente non dovrebbe essere molto preciso).
  • Effettua un passaggio iniziale sulla divisione, costruendo una struttura di dati "di confine": un insieme di esagoni che hanno un vicino che appartiene a un altro paese. Sarebbe anche un buon momento per calcolare il conteggio di quanti esagoni ci sono in ciascun paese.

Ora, per tutto il tempo che desideri, esegui il seguente pseudocodice:

Pick a random hex A from the boundary list;
Pick a random neighbor B of this hex from a different country;
if (A's country has more hexes than B's country has) {
  change hex A to belong to B's country;
} else if (B's country has more hexes than A's country has) {
  change hex B to belong to A's country;
} else {
  flip a coin to decide which to change;
}
if ( the changed hex's old country has become disconnected ) {
  undo and reject this move;
} else {
  update the boundary list around the changed hex and its neighbors;
}

Ciò manterrà un equilibrio approssimativo tra le dimensioni di due paesi vicini e il controllo "disconnesso" (che può essere effettuato con un semplice algoritmo di riempimento) assicura che nessun paese si divida mai in pezzi. L'aggiornamento dell'elenco dei limiti è un'operazione a tempo costante: l'esagono modificato ovviamente rimarrà sempre sul limite e puoi semplicemente controllare i suoi sei vicini per vedere se qualcuno di essi è diventato una cella di confine (perché il suo vicino è ora in un paese diverso) o ha smesso di essere una cella di confine (perché ora il suo vicino è nello stesso paese), modificando il confine impostato secondo necessità.

Per un perfezionamento di questo approccio, puoi persino rendere la condizione di quale esagono cambiare un po 'in modo casuale - piuttosto che "bilanciare" sempre i due paesi, puoi sempre effettuare lo swap con una certa probabilità e persino ridurre gradualmente tale probabilità tempo (simile al processo di raffreddamento in a ricottura simulata algoritmo di ) per iniziare a forzarli ad avere approssimativamente le stesse dimensioni.

Nota che questo non garantirà che tutte le aree abbiano esattamente le stesse dimensioni (il che è impossibile a meno che N non divida perfettamente le dimensioni della griglia), e non garantirà nemmeno che tutti i paesi si trovino entro un esagono l'uno dall'altro nell'area; esso dovrebbe garantire (correre per numero sufficiente di iterazioni) che ogni paese non più di un esagono più grande o più piccolo di ciascuno dei suoi immediati vicini è, però.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.