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