Вяз новичок: пытаюсь писать блэкджек


Я провожу независимое исследование по 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. Одна из первых проблем, с которой я столкнулся, была попытка выяснить, как удалить карты из колоды, когда они нарисованы, используя что-то вроде dropCard deck card = filter (card /= nextCard) deck, чтобы отфильтровать нарисованную карту из списка. Но мое понимание Elm заключается в том, что каждый раз, когда сигнал меняется, программа повторно оценивает, что означает, что колода воссоздается полностью каждый раз, когда карта вытягивается. Понадобится ли мне также foldp Оригинальная колода?

  2. Каков правильный способ удалить элемент из одного списка и добавить его в другой в функциональном программировании? Функциональная композиция, например toHand . dropCard card?

  3. Для добавления лиц карт, чтобы определить выигрыш / проигрыш, я не знаю, как получить целое значение из списка. Я попытался сделать fst (head deck), но получил ошибки типа, вероятно, потому, что дека сама по себе является сигналом какого-то рода. Есть что-то, чего я не вижу?

Тем не менее, я действительно наслаждался Вязом до сих пор!
1 4

1 ответ:

Вопросы

    Для простых программ самый простой способ думать о сигналах-это думать о том, какие вещи в вашей программе могут измениться. В вашем случае это была бы Колода и рука. Затем вы берете эти вещи и создаете структуру данных, в которой они хранятся. Затем вы делаете foldp над всей этой структурой данных, так что вместо того, чтобы просто отслеживать руку, вы также отслеживаете колоду.
  1. можно написать функцию, которая принимает список и индекс и возвращает элемент с этим индексом в списке и список с этим удаленным элементом. Затем вы добавляете этот пункт в другой список, и все готово.
  2. 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
Если что-то неясно, дайте мне знать.