[英]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.