elm / core

Elm's core libraries
http://package.elm-lang.org/packages/elm/core/latest
BSD 3-Clause "New" or "Revised" License
2.8k stars 359 forks source link

Problem with small values in Random.int on init #635

Closed PezzA closed 8 years ago

PezzA commented 8 years ago

Raised this question on stack overflow and it was suggested to create a bug report here.

http://stackoverflow.com/questions/37522369/elm-random-number-on-init-strange-behaviour

I've been working through the examples here:

http://guide.elm-lang.org/architecture/effects/random.html

And what I'm trying to do with the dice is to get to generate a D6 when then component is created.


module Components.DiceRoller exposing (Model, Msg, init, update, view)

import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Random
import String exposing (..)

main =
    Html.program
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

-- MODEL

type alias Model =
    { dieFace : Int
    }

init : ( Model, Cmd Msg )
init =
    ( Model 0, (Random.generate NewFace (Random.int 1 6)) )

-- UPDATE

type Msg
    = NewFace Int

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        NewFace newFace ->
            ( Model newFace, Cmd.none )

-- SUBSCRIPTIONS

subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none

-- VIEW

dieFaceImage : Int -> String
dieFaceImage dieFace =
    concat [ "/src/img/40px-Dice-", (toString dieFace), ".svg.png" ]

view : Model -> Html Msg
view model =
    let
        imagePath =
            dieFaceImage model.dieFace
    in
        div []
            [ img [ src imagePath ] []
            , span [] [ text imagePath ]
            ]

However if I use 1 6 as the random min max, I only get 1 different value per minute. This only happens on init, it's fine in the orig example where it a UI action.

mariosangiorgio commented 8 years ago

As I mentioned on the StackOverflow answer, this behaviour is a bit odd but I am not sure if that's expected or not. What is happening is that, for this combination of parameters, there are quite big intervals of seeds that generate the same first value of the pseudo-random sequence.

It's worth noting that, if we exclude the first value, the sequence of the numbers produced look random enough.

I had another look at the implementation of the random number generator, comparing it both to the Haskell implementation and to the original paper. I found that one of the magic numbers might have a wrong value.

We have magicNum7 = 2137383399 but I think it should be magicNum7 = 2147483399. Updating it is not affecting this particular issue, but it's still worth amending the constant to the correct value.

jvoigtlaender commented 8 years ago

@PezzA, @mariosangiorgio, in case you are still wondering what the issue here is: It's not the "magic numbers" thing, it's the fact that the randome generator is seeded from the current time at program start. See https://github.com/elm-lang/core/issues/673 for more explanation.

evancz commented 8 years ago

Not sure exactly what's wrong here, but maybe @mgold does. In any case, added this to #724 for tracking anything related to Random.

mgold commented 8 years ago

This will almost certainly be resolved by the new RNG.

connec commented 7 years ago

I also encountered this working through the Random section in the guide.

I think it's interesting (though probably not valuable) to observe that if "Initialize the dice to a random value" was added as an exercise, it would probably have to be removed or else it would generate a lot of confusion.

seethroughdev commented 7 years ago

I've encountered this same issue. It seems if I use Random.Int with 3 or less. I will get repeated numbers in the same fashion as seen above. Anything over 3, and I get random as expected.

Like the above, this only occurs when triggered on init. Is there a workaround here?

I can create and provide an example to reproduce or versions if necessary.

lydell commented 7 years ago

@seethroughtrees http://package.elm-lang.org/packages/mgold/elm-random-pcg/5.0.0/Random-Pcg

mgold commented 7 years ago

BTW that new RNG is #778. Until it's merged and released, use my library linked just above.

seethroughdev commented 7 years ago

Perfect. Thanks for the update @lydell and @mgold . Good to have that link in this thread too.