2016-02-06 4 views
9

Voglio generare un int casuale tra due valori in elm. Qualcosa di simile a questo:elm genera un numero casuale

nb = random(0, 10)

Ho letto il documento e post multipla. La migliore risposta è stata da questo StackOverflow post

gen = Random.int 0 10 
seed0 = Random.initialSeed 123456 
Random.generate gen seed0 

Ma il problema è che è sempre restituire lo stesso valore e non è nemmeno un int è qualcosa di simile:

(7,Seed { state = State 645041272 40692, next = <function>, split = <function>, range = <function> }) 
: (Int, Random.Seed) 

Quindi dal doc, è meglio utilizzare l'ora corrente per il seme. Ma come ottengo? Devo usare il segnale per questo? non c'è un modo semplice per ottenere un timestamp?

Sono molto confuso, ho bisogno di generare un int random per il seme in modo da poter generare un int casuale. Se non l'int casuale generato non è casuale. Penso di aver frainteso qualcosa ...

modifica: Ho anche trovato questo post ma non ho capito tutto.

+1

Possibile duplicato di [Qual è il modo corretto di inizializzare un'applicazione di elm] (http://stackoverflow.com/questions/28606248/questo-è-la-corretta-di-inizializzazione-an-mappa-applicativo –

risposta

5

aggiornato per 0,18

app = 
    Html.programWithFlags 
    { init = init 
    , update = update 
    , view = view 
    , subscriptions = always Sub.none 
    } 

init : {startTime : Float} -> Model 
init {startTime} = 
    { blankModel | randomSeed = Random.initialSeed <| round startTime } 

index.html

<script type="text/javascript"> 
    var yourPgm = Elm.fullscreen(Elm.Main, {startTime: Date.now()}); 
</script> 

risposta originale

I numeri casuali sono complessi nei programmi puri, ma questo è come mi fallo io n una delle mie games (usando Elm Architecture):

Main.elm

startTimeSeed : Seed 
startTimeSeed = Random.initialSeed <| round startTime 

app = 
    StartApp.start 
    { init = (init 8 8 startTimeSeed, Effects.none) 
    , update = update 
    , view = view 
    , inputs = [] 
    } 

port startTime : Float 

index.html

<script type="text/javascript"> 
    var yourPgm = Elm.fullscreen(Elm.Main, {startTime: Date.now()}); 
</script> 

In altre parole passano il timestamp tramite la porta quando si inizia il gioco

+0

Grazie, questo è molto più facile da comprendere come principiante rispetto ad altri approcci. – samspot

4

i t restituisce sempre [ing] lo stesso valore

Ecco come funzionano i generatori di numeri casuali puri. Tu passi in una Seed, e torni un'altra Seme.

e non è nemmeno un int è qualcosa di simile [frammento di codice pazzo]

Si tratta di una coppia di valori. Il primo è l'int che stai cercando. Il secondo è il nuovo seme per generare valori casuali. Non preoccuparti di cosa sia realmente un seme; dovrebbe essere opaco. Puoi estrarre la coppia usando fst, ma se vuoi più numeri casuali, avrai bisogno del nuovo seme.

Quindi dal documento, è meglio utilizzare l'ora corrente per il seme.

Questo documento è sbagliato, sbagliato, sbagliato . Come hai scoperto, non esiste un modo semplice per ottenere il timestamp corrente. E se lo fai passare da JS, come fa Simon, usa solo lo Math.floor(Math.random()*0xFFFFFFFF). Questo ti dà un seme che viene campionato meglio sul possibile spazio di input.

Questo è estremamente importante perché il generatore di numeri casuali emetterà valori simili per semi simili. Ad esempio, se si utilizza un seme inferiore a 53668 e si genera un valore bool, sarà True. Questo a causa di punti deboli nell'algoritmo utilizzato.

La soluzione migliore: ->use this library < -. Funziona allo stesso modo della libreria principale, ma l'algoritmo è molto migliore e i documenti sui semi non sono apertamente sbagliati.