F# создание раздачи с игральными картами

#f#

Вопрос:

Однако у меня есть этот код, который генерирует колоду карт и функцию, которая может случайным образом выбрать одну из 52 карт. Теперь мне нужен способ разыграть пять уникальных карт из колоды, и я не уверен, как это сделать.

Комментарии:

1. Попробуйте перетасовать колоду и взять 5 сверху

2. как бы я сделал перетасовку и взял сверху?

3. Ну, есть много способов перетасовать колоду, но самый простой-взять карту наугад, положить ее в новую колоду и повторять до тех пор, пока исходная колода не опустеет. Вы можете настроить свой GetCard , чтобы удалить выбранную карту, а затем повторить это 52 раза. Выберите первые 5 карт с Seq.take 5 помощью .

4. Как ты думаешь, ты мог бы написать в коде, что ты для меня значишь? я очень новичок в F# и не понимаю, как это сделать? извините

5. Кстати, если вы не возражаете против использования отражения, вы можете генерировать allSuits и allFaces непосредственно из их соответствующих DU: например let allFaces = FSharpType.GetUnionCases typeof<Faces> |> List.ofSeq

Ответ №1:

Как я указывал в комментариях, один из способов создать эту комбинацию-перетасовать колоду, а затем взять 5 карт сверху.

 type Suit = Diamonds | Hearts | Clubs | Spades
 
type Face =
    | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten
    | Jack | Queen | King | Ace
 
type Card = { Face: Face; Suit : Suit }

let allFaces = [
   Two; Three; Four; Five; Six; Seven; Eight; Nine; Ten;
   Jack; Queen; King; Ace
]

let allSuits = [ Diamonds; Hearts; Clubs; Spades ]

let fullDeck = [
    for suit in allSuits do
        for face in allFaces do
             yield { Face = face; Suit = suit } 
]

// returns a random card and the remaining deck
let GetCard (deck: Card list) =
    let rand = new System.Random()
    let idx = rand.Next(deck.Length)
    let card = deck.[idx]
    (card, List.except [card] deck)

// shuffle a deck
let rec shuffle = function
    | card :: [] -> [card]
    | deck -> let (card, rest) = GetCard deck
              card :: shuffle rest

let hand deck = deck |> shuffle |> List.take 5

fullDeck |> hand |> printfn "%A"
 

Комментарии:

1. Большое Вам спасибо, есть ли способ убрать скобки и прочее на выходе?

2. Насколько я знаю, нет, но для спецификатора могут быть доступны некоторые модификаторы A . Я тоже довольно новичок в F#, но в прошлом я использовал Haskell

3. Вы можете создать функцию для печати списка карточек, просто повторите список List.iter и распечатайте каждую карточку.

4. @AMieres Как бы ты это сделал? Будет ли это удалять скобки из вывода?

5. @TESTING1 AMieres предлагает создать собственную функцию печати, которая печатает одну карту, и применить ее ко всему списку. Вы можете сделать так, чтобы он печатался так, как вы хотите. Например, let printCard (card: Card) = printfn "%O of %O" card.Face card.Suit затем нанесите на руку с fullDeck |> hand |> List.iter printCard