-3

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)
  • 1
    Please don't use screenshots for code -- just paste it in your question and add code formatting. – duplode Oct 31 '15 at 00:26

2 Answers2

1

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.

Jeremy List
  • 1,756
  • 9
  • 16
  • I'm sorry, i'm still a bit confused. How would i redirect those card values into the second round of war? – Andalib Ali Oct 31 '15 at 00:39
  • Can this done, as a single single parameter? The whole program was written treating player 1 and player 2 as one tuple. – Andalib Ali Oct 31 '15 at 01:00
  • You can structure the parameters however you want, as long as they include all this information: the cards in player 1's hand, the cards in player 2's hand, the cards on the table from player 1, and the cards on the table from player 2. Your original function was just missing all the cards on the table. – Jeremy List Oct 31 '15 at 01:34
1

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.

luqui
  • 59,485
  • 12
  • 145
  • 204