我一直致力于使用 F# 对流行的纸牌游戏(情书)进行建模,以了解有关函数式编程的更多信息。
module Game =
open Cards
open Players
type Deck = Card list
let dealACard (deck:Deck) =
let randomGenerator = System.Random()
let index = randomGenerator.Next deck.Length
let card = deck.Item index
(card, (deck |> List.filter((<>) card)))
let createPlayer playerNumber deck =
let card, newDeck = dealACard deck
({cards=[card]; playerNumber=playerNumber}, newDeck)
我一直做得很好,直到我学会了如何模拟如何画一张卡片。为了测试这一点,我想从牌组中抽出所有的牌。我的程序看起来像这样:
let deck = createDeck
while not deck.IsEmpty do
let card, newDeck = dealACard deck
// print the card
// how do I update the deck?
任何帮助或反馈都会很棒。
最佳答案
F# 列表是 不可变 ,所以如果 deck.IsEmpty
开始 false
,它会留下false
永远。不过,真的没有理由让事情变得如此复杂。
假设你有一个排序的甲板。让我们仅以三张牌为例,但假设它是一副完整的牌:
let deck =
[
{ Suit = Hearts; Face = Queen }
{ Suit = Diamonds; Face = King }
{ Suit = Spades; Face = Ace }
]
您可以使用随机数生成器轻松打乱牌组:
let r = Random ()
let scrambledDeck = deck |> List.sortBy (fun _ -> r.Next ())
第一次创建
scrambledDeck
,它在 FSI 中可能是这样的:> let scrambledDeck = deck |> List.sortBy (fun _ -> r.Next ());;
val scrambledDeck : Card list =
[{Suit = Spades;
Face = Ace;}; {Suit = Hearts;
Face = Queen;}; {Suit = Diamonds;
Face = King;}]
但是如果你再做一次,它可能看起来像这样:
> let scrambledDeck = deck |> List.sortBy (fun _ -> r.Next ());;
val scrambledDeck : Card list =
[{Suit = Spades;
Face = Ace;}; {Suit = Diamonds;
Face = King;}; {Suit = Hearts;
Face = Queen;}]
现在你有一个打乱的牌组,你可以简单地开始把牌从上面拉下来,例如为了打印它们:
scrambledDeck |> List.iter (printfn "%O")
关于functional-programming - 如何使用 F# 发牌,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31709509/