Haskell- War card Game

时间:2015-10-31 00:11:10

标签: haskell functional-programming ghci

One of the rules that i'm trying to program is: When the two players play cards of equal rank, this triggers a “war”. Each player sets down three cards, and then flips one more card. Whoever wins between these last two flipped cards gets to take all the cards in the round, including the 3 cards that were set down by each player. If those flipped cards match again, another war is triggered, which is resolved in the same way. I can implement the first round of war inside my code, however the part that i am stuck with is when the second round of war is initiated when the two players get the same card again. The trouble i am having is when the second round of war is initiated, the two players put aside the cards from the first war and whoever whens the second war gets all the cards from the second war and the first war. I don't know understand how to make my war function store the first round of cards, as you can see in my otherwise i just dropped the cards from the first round. war :: ([Int], [Int]) -> ([Int], [Int]) war (x:xs,y:ys) | head(drop 3 xs) > head(drop 3 (ys)) = (drop 4 (xs) ++ player1Pot (x:xs) ++ player2Pot (y:ys), drop 4 (ys)) | head(drop 3 xs) < head(drop 3 (ys)) = (drop 4 (xs), drop 4 (ys) ++ player2Pot (y:ys) ++ player1Pot (x:xs)) | otherwise = war (drop 4 (xs),drop 4 (ys)) standardRound :: ([Int], [Int]) -> ([Int], [Int]) standardRound ([],y:ys) = ([],y:ys) standardRound (x:xs,[]) = (x:xs,[]) standardRound (x:xs,y:ys) | x > y = (xs ++ [y] ++ [x], ys) | y > x = (xs, ys ++ [x] ++ [y]) | otherwise = war (x:xs,y:ys)

2 个答案:

答案 0 :(得分:1)

将另一个参数添加到war函数。

war :: ([Int],[Int]) -> ([Int],[Int]) -> ([Int],[Int])
war (px,py) (x,y) = let
  [(xp',(xc:xr)),(yp',(yc:yr))] = map (splitAt 3) [x,y]
  in case xc `compare` yc of
    GT -> (xr ++ px ++ xp' ++ [xc] ++ py ++ yp' ++ [yc], yr)
    LT -> (xr, yr ++ py ++ yp' ++ [yc] ++ px ++ xp' ++ [xc])
    EQ -> war (px ++ xp' ++ [xc], py ++ yp' ++ [yc]) (xr,yr)

来自standardRound函数的调用:第一个参数应该是([],[]),在递归调用中它应该是卡片列表。

答案 1 :(得分:1)

您可以使用let ... in提取元组的值

| otherwise = let (newxs,newys) = war (drop 4 xs, drop 4 ys) in
              (take 3 xs ++ newxs, take 3 ys ++ newys)

以便您可以返回修改后的版本。无论你喜欢,都可以在之前或之后添加掉落的卡片。