Elm生成随机数

9
我希望在 Elm 中生成两个值之间的随机整数。就像这样: nb = random(0, 10) 我已经阅读了文档和多篇文章。最好的答案来自于这个 stackoverflow 的帖子
gen = Random.int 0 10
seed0 = Random.initialSeed 123456
Random.generate gen seed0

但问题在于它总是返回相同的值,而且它甚至不是一个整数,而是像这样的东西:

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

文档中得知,最好使用当前时间作为种子。但是我该如何获得它?我必须使用信号吗?没有更简单的方法来获取时间戳吗?
我有点困惑,我需要生成一个随机整数作为种子,以便我可以生成一个随机整数。如果不是这样的话,生成的随机数就不是真正的随机数。我认为我误解了什么...
编辑:我还发现了这个帖子,但我没有完全理解。

1
可能是如何正确初始化 Elm 应用程序的重复问题。 - Chad Gilbert
2个回答

5
更新至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>

原始答案

在纯程序中,随机数是很复杂的,但这是我在我的一个游戏中使用 Elm 架构时所做的:

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>

换句话说,在游戏开始时,通过端口传递时间戳。

谢谢,对于新手来说,这比其他方法容易理解得多。 - samspot

4

它总是返回相同的值

这就是纯随机数生成器的工作方式。你提供一个种子,然后得到另一个种子。

而且它甚至不是一个int,而是像这样的一对值[crazy code snippet]

这是一对值。第一个是你要找的int。第二个是新的种子来生成随机值。不要担心种子实际上是什么; 它应该是不透明的。你可以使用fst从对中获取int,但如果你想要更多的随机数,你需要新的种子。

所以根据文档,最好使用当前时间作为种子。

这份文档是错误的、错误的、错误的。正如你已经发现的那样,没有简单的方法来获得当前时间戳。如果你像Simon建议的那样从JS中传递它,只需使用Math.floor(Math.random()*0xFFFFFFFF)。这会给你一个更好地采样可能输入空间的种子。

这非常重要,因为随机数生成器将为类似的种子输出类似的值。例如,如果你使用任何小于53668的种子并生成一个bool,则为True。这是由于所使用的算法的弱点。

更好的解决方案:--> 使用这个库<--。它与核心库的工作方式相同,但算法要好得多,并且关于种子的文档不是明显错误的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接