4

私は 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 プロジェクトを見ると少しは役に立ちますが、それらの多くは初心者の私には解析が困難です。どんな方向性でも役に立ちます!

  1. 私が最初に抱えた問題の 1 つは、ドローしたカードをリストから除外するなどの方法を使用して、ドローしたカードをデッキから削除する方法を見つけようとすることでしたdropCard deck card = filter (\card /= nextCard) deck。しかし、Elm についての私の理解では、シグナルが変化するたびにプログラムが再評価されます。つまり、カードが引かれるたびにデッキが完全に再作成されます。foldpオリジナルのデッキも必要ですか?

  2. 関数型プログラミングで、あるリストから要素を削除して別のリストに追加する適切な方法は何ですか? のような機能合成toHand . dropCard card

  3. 勝敗を決定するためにカードの顔を追加するために、リストから整数値を取得する方法がわかりません。をやってみfst (head deck)ましたが、おそらくデッキ自体が何らかのシグナルであるため、型エラーが発生しました。私が見ていないものはありますか?

そうは言っても、これまでのところ、私は Elm を本当に楽しんでいます!

4

1 に答える 1

7

質問

  1. 単純なプログラムの場合、シグナルについて考える最も簡単な方法は、プログラム内でどのような種類のものを変更できるかを考えることです。あなたの場合、それはデッキと手になります。次に、これらのものを取得して、それらを格納するデータ構造を作成します。次にfoldp、そのデータ構造全体を処理するため、ハンドを追跡するだけでなく、デッキも追跡します。
  2. リストとインデックスを受け取り、リスト内のそのインデックスにある項目と、その項目を削除したリストを返す関数を作成できます。次に、アイテムを他のリストに追加して完了です。
  3. 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

ご不明な点がございましたら、お知らせください。

于 2014-10-08T18:02:57.757 に答える