簡體   English   中英

如何修復我的 haskell 代碼來計算剪刀石頭布的第一人稱得分?

[英]How can I fix my haskell code to count the first person points in rock paper scissors?

我想計算第一個玩家贏得游戲的次數。 有人可以幫我解決嗎?

data RPS = Rock | Paper | Scissors deriving (Eq) 

beats :: RPS -> RPS
beats rps = case rps of 
    Rock -> Scissors
    Paper -> Rock
    Scissors -> Paper


firstBeats :: [RPS] -> [RPS] -> Int
firstBeats (a:ax) (b:bx)  
 | a==Rock && b==Scissors = 1 + (firstBeats ax) : (firstBeats bx)
 | a==Scissors && b==Paper = 1 + (firstBeats ax) : (firstBeats bx)
 | a==Paper && b==Rock = 1+ (firstBeats ax) : (firstBeats bx)
 | otherwise = (a: firstBeats ax) + (b : firstBeats bx)

Examples:
firstBeats [Rock] [Paper]    == 0
firstBeats [Rock] [Scissors] == 1
firstBeats [Paper, Scissors] [Rock, Paper] == 2
firstBeats [Paper, Scissors, Paper] [Rock, Paper, Scissors] == 2
firstBeats (replicate 20 Paper) (replicate 20 Rock) == 20

主要問題是firstBeats有兩個參數,因此您應該傳遞兩個列表的尾部。 此外,您應該涵蓋兩個列表之一或兩者都為空的情況,因此:

firstBeats :: [RPS] -> [RPS] -> Int
firstBeats (a:ax) (b:bx)  
 | a == Rock && b == Scissors = 1 + firstBeats ax bx
 | a == Scissors && b == Paper = 1 + firstBeats ax bx
 | a == Paper && b == Rock = 1 + firstBeats ax bx
 | otherwise = firstBeats ax bx
firstBeats _ _ = 0

但這並不優雅,需要大量重復。 您可以定義一個 function 來檢查第一項是否擊敗了第二項:

hasBeaten :: RPS -> RPS -> Bool
hasBeaten Rock Scissors = True
hasBeaten Scissors Paper = True
hasBeaten Paper Rock = True
hasBeaten _ _ = False

然后你可以將其實現為:

firstBeats :: [RPS] -> [RPS] -> Int
firstBeats (a:as) (b:bs)
    | hasBeaten a b = 1 + firstBeats ax bx
    | otherwise = firstBeats ax bx
firstBeats _ _ = 0

但是造型也不是很好看。 人們會期望使用RPS的 2 元組列表,這樣就不可能傳遞包含不同數量項目的兩個列表。 然后是:

firstBeats :: [(RPS, RPS)] -> Int
firstBeats = length . filter (uncurry hasBeaten)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM