我正在对 Elm 进行独立研究,我感觉我又重新开始学习编程了!作为一个学习语言的项目,我试图让一个简单的二十一点启动并运行,但是一旦我开始,我意识到我仍然没有掌握多少。我可以从一副牌中抽取卡片并将它们添加到列表中:

import Random
import Mouse
import Array

--Build the deck
faces = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
suits = ['H', 'D', 'C', 'S']

allCards faces suits =
  case suits of
    x :: xs -> family faces x ++ allCards faces xs
    _ -> []

family faces suit =
  case faces of
    x :: xs -> (,) x suit :: family xs suit
    _ -> []

deck = allCards faces suits

rand : Signal Int
rand = Random.range 0 (length deck-1) Mouse.clicks

pickCard n = head <| drop n deck
nextCard = lift pickCard rand

yourHand = foldp (::) [] nextCard

main = lift asText yourHand

我的问题主要是关于如何继续。查看已完成的 Elm 项目会有所帮助,但作为初学者,我很难解析其中的许多项目。任何方向都有帮助!
  • 我遇到的第一个问题是试图弄清楚如何在抽取卡片后从牌组中移除卡片,使用类似 dropCard deck card = filter (\card /= nextCard) deck 的东西从列表中过滤掉抽取的卡片。但我对 Elm 的理解是,每次信号改变时,程序都会重新评估,这意味着每次抽卡时都会重新创建完整的牌组。我还需要对原始牌组进行 foldp 吗?
  • 在函数式编程中,从一个列表中删除一个元素并将其添加到另一个列表中的正确方法是什么?函数组合,比如 toHand . dropCard card
  • 对于添加卡面以确定输赢,我不确定如何从列表中获取整数值。我尝试做 fst (head deck) ,但我遇到了类型错误,可能是因为甲板本身就是某种信号。有什么我没有看到的吗?

  • 也就是说,到目前为止我真的很喜欢 Elm!

    最佳答案

    问题

  • 对于简单的程序,考虑信号的最简单方法是考虑程序中哪些类型的事情可以改变。在你的情况下,这将是甲板和手。然后你把这些东西做成一个数据结构来存储它们。然后你对整个数据结构做一个 foldp,所以你不仅要跟踪手牌,还要跟踪牌组。
  • 您可以编写一个函数,该函数接受一个列表和一个索引,并返回列表中该索引处的项目和删除该项目的列表。然后您将该项目添加到另一个列表中,您就完成了。
  • fst (head deck) 应该可以工作。也许您在尝试时忘记删除 lift 定义中的 main

  • 示例代码
    -- This first part is your code:
    import Random
    import Mouse
    import Array
    
    --Build the deck
    faces = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
    suits = ['H', 'D', 'C', 'S']
    
    allCards faces suits =
      case suits of
        x :: xs -> family faces x ++ allCards faces xs
        _ -> []
    
    family faces suit =
      case faces of
        x :: xs -> (,) x suit :: family xs suit
        _ -> []
    
    -- Here come my additions/changes:
    -- Naming some types for clarity
    type Card = (Int,Char)
    type ProgramState = { deck : [Card], hand : [Card] }
    
    getFromList : Int -> [a] -> (a,[a])
    getFromList index list =
      let prefix = take index list
          (item :: postfix) = drop index list
      in (item, prefix ++ postfix)
    
    startState : ProgramState
    startState = { deck = allCards faces suits, hand = [] }
    
    rand : Signal Float
    rand = Random.float Mouse.clicks
    
    rFloatToInt : Float -> Int -> Int -> Int
    rFloatToInt rnd lo hi = round ((rnd + toFloat lo) * toFloat hi)
    
    pickCard : Float -> ProgramState -> ProgramState
    pickCard rnd {deck,hand} =
      let index = rFloatToInt rnd 0 (length deck - 1)
          (item, newDeck) = getFromList index deck
      in { deck = newDeck, hand = item :: hand }
    
    programState : Signal ProgramState
    programState = foldp pickCard startState rand
    
    main : Signal Element
    main = lift asText programState
    

    如果有什么不清楚的,请告诉我。

    关于functional-programming - 榆树初学者 : trying to write blackjack,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26242158/

    10-13 03:09