2015-04-10 5 views
5

Sto lavorando a un gioco piccolo e semplice (principalmente per imparare le novità in Java 8 e JavaFX). Una delle caratteristiche che ho è la capacità di seme generatore di numeri casuali del gioco in modo da poter riprodurre più o meno lo stesso gioco di un amico su un sistema differente (pensare Minecraft Maps o The Binding of Isaac giochi).Serializing java.util.Random

Vorrei aggiungere la possibilità di salvare il gioco per riprenderlo in un secondo momento. Dopo aver esaminato la documentazione della classe java.util.Random, non riesco a trovare un modo per ottenere il seed corrente del generatore di numeri casuali. L'unico modo in cui mi sono inventato per ripristinare il generatore di numeri casuali dopo aver salvato il gioco è quello di accedere al seme tramite riflessione al momento del salvataggio e usarlo, o di seminare il seme iniziale al momento del caricamento e chiamare semplicemente nextInt() ancora e ancora fino a quando non avremo spostato in avanti il ​​generatore di numeri casuali quanto bastava prima che il gioco venisse salvato.

+2

È 'Serializable'. Sarebbe abbastanza? – user2357112

risposta

5

Innanzitutto, come @ user2357112 sottolinea, Random implementa Serializable, e lo fa scrivendo il seed campo (insieme con i campi nextNextGaussian e haveNextNextGaussian). Hai provato semplicemente a serializzarlo? Questo dovrebbe "funzionare" ™. Anche altri serializzatori, come Gson, funzionano. gson.fromJson(gson.toJson(r), Random.class); restituisce un oggetto identico.

Non è necessaria la stessa istanza Random, solo una coerente. Potresti semplicemente chiamare nextLong() e scrivere quel valore sul tuo file di salvataggio come random_seed o qualsiasi altra cosa. Quindi inizializza solo un'istanza Random con quel seme e ora tutte le esecuzioni caricate da quel file si comportano allo stesso modo. Se lo si desidera, è anche possibile reimpostare l'istanza Random nel gioco attualmente in esecuzione sullo stesso seme.

D'altra parte se stai generando mappe o altri contenuti apparentemente costanti in modo casuale e vuoi che persistano tra un caricamento e l'altro, penso che farebbe meglio seminare il tuo Random all'inizio e salvare quello valore come descrivi. Per risparmiare sul calcolo, puoi farlo a pezzi più piccoli di un intero livello. Ad esempio, dividi ogni livello in decimi, e usa (e salva) un seme diverso per ogni decimo. Quindi devi solo generare la porzione su cui l'utente si trova ora, e non le parti che hanno già attraversato. Se si dovesse salvare solo lo stato corrente come si propone, l'utente non può tornare indietro nella mappa (il che potrebbe non essere un problema per il gioco in particolare, ma non sarebbe una buona pratica in generale).


Avvertenza UX: salvare la casualità del tuo gioco sembra potenzialmente eccessivamente ingegnerizzato. Come utente, generalmente non mi aspetto che un file di salvataggio mantenga la casualità. Infatti, a volte i giocatori ne approfittano, ad esempio se muoiono in un incontro casuale subito dopo averli salvati, ricaricando il gioco non li rinvia immediatamente nello stesso incontro. Prenderò in considerazione la possibilità di lasciare il proprio numero di gioco Random e lasciare che ogni gioco sia leggermente unico.

+1

Questo produrrà un seme coerente attraverso i giochi caricati dallo stesso file di salvataggio, ma non sarà coerente con i giochi caricati da un precedente file di salvataggio e riprodotto attraverso il punto in cui il file successivo è stato salvato. Questo potrebbe essere importante. – user2357112

+0

Un buon punto, i requisiti dell'OP potrebbero rendere inaccettabile il mio primo suggerimento. Speriamo che l'opzione due abbia più senso in questo caso. – dimo414

Problemi correlati