简体   繁体   中英

Haskell- War card Game

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)

Add another parameter to the war function.

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)

In the call from the standardRound function: the first parameter should be ([],[]) , in the recursive calls it should be the list of cards.

You can use let ... in to extract the values of a tuple

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

so that you can returned a modified version. Add the dropped cards before or after, however you like.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM