练习 - 应用列表属性

已完成

假设你是一家休闲游戏公司的开发人员。 你的工作是编写一些可用于纸牌游戏的起始代码。 你的第一项任务是创建一副纸牌,然后创建一个函数,此函数可以实现每次抽出一张牌。

创建一副纸牌

虽然一副纸牌有 52 张,但为了更轻松地阅读控制台打印内容,我们将这副牌缩减为五张。 你可以通过在列表中的第一个和最后一个数字之间插入两个点 (..)(前后各加一个空格)来创建一个数字序列。

  1. 在控制台中,通过运行 dotnet new 创建一个新项目:

    dotnet new console --language F# -o Cards
    cd Cards
    
  2. 若要创建包含纸牌的列表,请在 Program.fs 文件中添加以下代码:

    let cards = [ 0 .. 5 ]
    

    此代码会创建一个从 0 到 5 的数字列表。

从一副牌中抽牌

现在你已经创建了一副牌,接下来就可以构造抽牌的方法了。 可以使用内置属性 HeadTail 来实现此目的。

  1. 接下来,创建函数 drawCard()

    let drawCard (list:int list) = 
        printfn "%i" list.Head
        list.Tail 
    

    通过使用 Head 属性,你可以读取列表中的第一项,通过返回 Tail,你可以模拟从列表顶部抽牌并返回剩余纸牌。

  2. 将以下代码添加到 main() 方法来试用实现:

    let result = cards |> drawCard |> drawCard // 0 1
    
  3. 通过调用 dotnet run 运行项目:

    现在,你应该会看到控制台中打印的 01

祝贺你! 你已经实现了可从中抽牌的一副纸牌。

绘制手牌

实现从一副牌中抽牌的功能是一个很好的开始,但纸牌游戏通常需要两名或更多玩家来拿取这些纸牌。 如你所知,每名玩家抽取的纸牌集合被称为“底牌”。 接下来,需要实现代码,将每张抽取出来的纸牌添加到底牌中。

  1. 在声明 cards 列表的代码中添加以下代码:

    let hand = []
    
  2. 接下来,修改 drawCard() 方法以接受由两个列表(一个表示纸牌,另一个表示底牌)组成的元组:

    let drawCard (tuple: int list * int list) = 
        let deck = fst tuple
        let draw = snd tuple
        let firstCard = deck.Head
        printfn "%i" firstCard
    
        let hand = 
            draw
            |> List.append [firstCard]
    
        (deck.Tail, hand)
    

    fst() 函数用于访问元组中的第一个属性,即你的纸牌。 snd 函数用于访问底牌。 你还修改了返回类型,因此将返回元组,其中包含纸牌和你的底牌 (deck.Tail, hand),但添加了纸牌 firstCard

  3. 修改 main 方法中的代码以绘制手牌:

    let d, h = (cards, hand) |> drawCard |> drawCard
    
    printfn "Deck: %A Hand: %A" d h // Deck: [2; 3; 4; 5] Hand: [1; 0]
    
  4. 通过调用 dotnet run 运行项目:

    dotnet run
    

    你应该会看到控制台中打印的以下输出:

    Deck: [2; 3; 4; 5] Hand: [1; 0]
    

祝贺你! 你已成功模拟在每次绘制纸牌时都有玩家 hand