我想在elm中的两个值之间生成一个随机int.像这样的东西:
nb = random(0, 10)
我已经阅读了doc和多篇文章.最好的答案来自这个stackoverflow 帖子
gen = Random.int 0 10
seed0 = Random.initialSeed 123456
Random.generate gen seed0
Run Code Online (Sandbox Code Playgroud)
但问题是它总是返回相同的值,它甚至不是一个int,它是这样的:
(7,Seed { state = State 645041272 40692, next = <function>, split = <function>, range = <function> })
: ( Int, Random.Seed )
Run Code Online (Sandbox Code Playgroud)
因此,从文档中,最好使用当前时间的种子.但我怎么得到它?我必须使用信号吗?是不是有一个简单的方法来获取时间戳?
我很困惑,我需要为种子生成一个随机int,这样我就可以生成一个随机的int.如果不是,则生成的随机int不是随机的.我想我误解了一些事情......
编辑:我也发现了这篇文章,但我并不了解一切.
它总是返回相同的值
这就是纯随机数生成器的工作原理。你传递一个种子,然后你得到另一个种子。
它甚至不是一个 int 它是这样的[疯狂的代码片段]
这是一对值。第一个是您要寻找的 int 。第二个是生成随机值的新种子。不要担心种子到底是什么;它只是种子。它应该是不透明的。您可以使用 获取该对中的 int fst,但如果您想要更多随机数,则需要新的种子。
因此,从文档来看,最好使用当前时间作为种子。
这个文档是错误的,错误的,错误的。正如您所发现的,没有一种简单的方法可以获取当前时间戳。如果您从 JS 传递它,就像 Simon 建议的那样,只需使用Math.floor(Math.random()*0xFFFFFFFF)即可。这为您提供了在可能的输入空间上更好地采样的种子。
这非常重要,因为随机数生成器将为相似的种子输出相似的值。例如,如果您使用任何小于 53668 的种子并生成一个布尔值,则它将是True. 这是因为所使用的算法存在缺陷。
更好的解决方案: -->使用这个库<-- . 它的工作方式与核心库相同,但算法要好得多,而且关于种子的文档也没有明显错误。
已更新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 }
Run Code Online (Sandbox Code Playgroud)
的index.html
<script type="text/javascript">
var yourPgm = Elm.fullscreen(Elm.Main, {startTime: Date.now()});
</script>
Run Code Online (Sandbox Code Playgroud)
原始答案
随机数在纯程序中很复杂,但这就是我在我的一个游戏中使用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
Run Code Online (Sandbox Code Playgroud)
的index.html
<script type="text/javascript">
var yourPgm = Elm.fullscreen(Elm.Main, {startTime: Date.now()});
</script>
Run Code Online (Sandbox Code Playgroud)
换句话说,当你开始游戏时,通过端口传递时间戳