Funzione seed casuale per la generazione di mappe?


28

Sto cercando una funzione per generare una mappa casuale basata su tessere quando i confini visivi della mappa cambiano (passando attraverso la mappa). Voglio che la mappa sia infinitamente grande e abbia una struttura simile a un labirinto.

Tuttavia, se il mondo è infinito, tornare al punto in cui un giocatore è già stato prima solleva un problema. Il gioco deve ricordare come appariva tutto ciò che c'era dietro.

Quindi, stavo pensando: "In che modo Minecraft risolve questo problema?" e ho pensato a me stesso che dovevano usare una sorta di funzione di numero casuale con un seme, che può sia andare avanti ma anche indietro, e in questo modo, rigenerare vecchie tessere esattamente come erano, ma in nuovi casi.

Cosa ne pensi di questo?


Com'è la mia risposta a +5 ma la domanda è solo a +2? Questa è una delle migliori domande in prima pagina in questo momento.

2
Minecraft non memorizza semplicemente i blocchi che hai già visitato / modificato?
FxIII,

@FxIII: Minecraft deve, perché puoi modificare il panorama. Se non puoi farlo, conservare i pezzi è probabilmente uno spreco, o almeno una complicanza eccessiva.

@Joe Wreschnig: Ok, Ok ... Temevo di aver perso qualcosa di veramente grande!
FxIII,

Risposte:


20

Quello che hai notato è la differenza tra un generatore di numeri casuali e una funzione di rumore . Un generatore di numeri casuali emette un numero diverso ogni volta che lo chiami. Una funzione noise prende alcuni argomenti - diciamo, una mappa xey - e sputa numeri con proprietà statistiche simili a casuali , ma lo stesso valore ogni volta per gli stessi argomenti , cioè è una funzione matematica appropriata.

I due sono strettamente correlati. Una funzione noise può simulare un generatore di numeri casuali, passando ogni volta un valore diverso noise(1), ad esempio noise(2), e così via. E un generatore di numeri casuali, scaricato in un tavolo gigante, può agire come una funzione di rumore. In entrambi i casi, tuttavia, stai utilizzando lo strumento sbagliato per il lavoro.

Minecraft in particolare usi Perlin rumore , un tipo di rumore che è a buon mercato per il calcolo, e ha una proprietà desiderabile di essere continuo nel maggior numero di dimensioni di cui hai bisogno - Se si rappresentano f(x)a f(x + 1), non ci sarà alcun salti improvvisi. Ciò lo rende molto utile per molte cose come la modulazione della trama, le nuvole e i gas volumetrici e la generazione del terreno.

Se stai cercando un'implementazione con cui iniziare a giocare, il migliorato generatore di rumore Perlin di Ken Perlin è una delle implementazioni più semplici.


3
Nota che molti generatori di numeri casuali usano un seme e genereranno lo stesso insieme di numeri dato lo stesso seme.
thedaian

3
@thedaian: che non è particolarmente utile in questo caso, a meno che non si desideri rigenerare ogni numero; una funzione noise ti consente di ottenere il 500 ° numero senza dover prima generare 499.

Dato l'algoritmo Perlin Noise, è possibile calibrarlo? Considera che voglio che l'algoritmo abbia più probabilità di generare un pacchetto di tessere da parete e quindi un pacchetto di tessere spazio.
Mathias Lykkegaard Lorenzen il

3
Non hai letto e capito i link che ti ho dato in sei minuti.

1
Questa risposta sarebbe stata completa con il post sul blog di Notch: notch.tumblr.com/post/3746989361/terrain-generation-part-1
deceleratedcaviar

3

Il modo in cui Minecraft controlla la sua generazione è creando un seed di livello che viene utilizzato per seminare tutta la generazione di numeri casuali per il gioco. Se un pezzo non esiste sul disco quando viene richiesto, verrà generato usando la funzione di generazione di Notch basata sul seme del livello; viene quindi salvato su disco per dopo.

Sembra che tu stia cercando di ottenere un comportamento simile, quindi è un modo sicuro di procedere.


2

Come ha sottolineato Joe, stai cercando una funzione hash. Generalmente, le funzioni casuali sono solo funzioni hash seminate con l'ultimo numero restituito. Quindi, se Random()restituito Hash(seed)=1234, Random()tornerebbe una seconda chiamata Hash(1234), e così via.

Se stai cercando una semplice funzione di hashing per numeri pseudo casuali, dai un'occhiata a MurMurHash . L'ho implementato in C # e posso pubblicarlo da qualche parte se sei interessato. Informazioni più dettagliate su Perlin Noise, che utilizza tale funzione hash, sono disponibili qui e un'implementazione in C # è disponibile qui .

Tutte queste informazioni provengono da una domanda che ho posto un anno fa qui su Stack Overflow. Quello che stai cercando è chiamato generazione di contenuti procedurali, quindi se hai bisogno di maggiori informazioni, cerca quello. Buona generazione di terreno!


-1. L'hash del rumore di Perlin, allo stato attuale, non ha alcuna somiglianza con le tecniche usate in MMH o altre routine di hash crittografiche; quel codice C # è spazzatura che sembra fare solo un'interpolazione lineare tra valori casuali; richiede molta più memoria del rumore Perlin corretto e probabilmente funziona più lentamente.

1
@Joe - Mi dispiace che ti senta così tanto per la tua implementazione di Perlin Noise. Perlin Noise è di per sé un concetto di trasformazione di una funzione hash in una funzione di rumore continuo. Ho generato molto Perlin Noise in modo molto efficace con MurMurHash. Per quanto riguarda il codice C #, è un esempio di come determinare a livello di codice il valore di un singolo punto in Perlin Noise 2D. Non lo userei mai in produzione, ma secondo me è più facile da consultare rispetto al codice che hai pubblicato.
dlras2,

1
L'OP non era a conoscenza del rumore o dell'hashish, quindi ho semplicemente cercato di fornire riferimenti nella speranza che indagassero ulteriormente e decidessero autonomamente come implementare tutto ciò di cui avevano bisogno.
dlras2,

"Perlin Noise è esso stesso un concetto di trasformare una funzione hash in una funzione di rumore continuo." No, il rumore Perlin è una delle funzioni di rumore continuo inventate da Ken Perlin (e non quella che ha chiamato "rumore simplex"). Non tutte le funzioni di rumore continuo sono rumore di Perlin; non tutte le funzioni di rumore continuo sono anche rumore di gradiente, di cui il rumore di Perlin ne è un esempio particolare; la cosa a cui ti sei collegato non è il rumore gradiente, ma il rumore di valore.

Il codice nel tuo link è "più facile da percorrere" perché non è il rumore di Perlin; non è così liscio; utilizza molte più risorse; in breve, è più facile attraversarlo perché è più stupido.
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.