如何在Elm中的给定列表中获取随机元素?

时间:2015-10-25 11:29:03

标签: random elm

我正在构建滑动益智游戏:

enter image description here

从这个初始位置开始,我想把这个谜题洗牌,比如100步。

我希望每次都能以不同方式改组拼图。

这可能意味着我每次都需要使用不同的号码来呼叫Random.initialSeed,这意味着我需要使用类似当前时间的内容。

不幸的是,我无法找到如何获得当前时间。

在每个给定的状态中,我都列出了可能的动作。例如,在上面的初始位置:[MoveRight, MoveDown]

所以,基本上,我的问题是:如何在给定的List中获取随机元素?

share-elm示例将不胜感激。

3 个答案:

答案 0 :(得分:6)

这是对pdamoc答案的修订。它更紧密地遵循榆树建筑,但更重要的是,它保存了从按压到印刷的随机种子。如果你继续使用初始种子,你就不会获得随机性。我只得到了其他版本的偶数或奇数(得到了均衡,刷新,得分)。在程序中只调用一次Random.initialSeed非常重要,通常是在初始模型的定义中。

还有a library(我写过)处理Arrays上的随机操作。

import Html exposing (..) 
import Html.Events exposing (onClick) 
import Random exposing (initialSeed, int, generate, Seed)

type alias Model = 
  { list : List Int , currentElement : Maybe Int, seed : Seed}

init : Model 
init = {list = [1..10], currentElement = Nothing, seed = initialSeed 42 } 

type Action = NoOp | Click

actions : Signal.Mailbox Action
actions = Signal.mailbox NoOp

update : Action -> Model -> Model
update action model =
  case action of
    NoOp -> model
    Click ->
      let gen = Random.int 0 (List.length model.list - 1)
          -- since we know the list is constant we don't have to
          -- redefine the generator every time, but we will anyway
          (i, seed) = Random.generate gen model.seed
          elem = List.drop i model.list |> List.head
      in {model| currentElement <- elem, seed <- seed}

model : Signal Model
model = Signal.foldp update init actions.signal

view : Signal.Address Action -> Model -> Html
view address model = 
  let 
    current = model.currentElement
              |> Maybe.map toString
              |> Maybe.withDefault "NONE"
  in 
    div [] 
      [ text  <| toString model.list
      , br [] []
      , text  <| "Current Element: " ++ current
      , br [] []
      , button [onClick address Click ] [text "Click for Random Element"]
      ]

main = Signal.map (view actions.address) model

答案 1 :(得分:2)

粗略答案(目前不在编译器附近):

如果您想根据当前时间更改种子,请在信号图中添加Time.every

http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Time#every

保持模型中最后一次显示的时间戳,然后,当您需要随机播放时,使用它来随机播种。生成[1,长度列表]范围内的整数,然后选择该索引的元素。

希望这有足够的暗示,如果不是,请大喊大叫,我会在有机会的时候详细说明。

答案 2 :(得分:0)

我已经创建了Elm的StartApp示例的变体,其中包括每个事件的时间,仅在事件发生时。

https://gist.github.com/z5h/41ca436679591b6c3e51

您的更新功能现在如下所示:

update : action -> Time -> model -> (model, Effects action)