1

I am trying to make a card game that two players show there cards and the one with the highest rank wins and takes the card.(War Card Game). The trouble i am having is running the whole game, to see the final result of who the winner is. I have made the code that can do one round of the game:

type ComparisonRule = Card -> Card -> Bool
type RoundRule = ([Card],[Card]) -> ([Card],[Card])

standardComparison :: ComparisonRule
standardComparison (Card r1 _) (Card r2 _)
    | r1 > r2  = True
    |otherwise = False

roundWithoutWar :: ComparisonRule -> RoundRule
roundWithoutWar f (x:xs,y:ys)
        |f x y     = (xs ++ [x] ++ [y],ys)
        |f y x     = (xs,ys ++ [y] ++ [x])
        |otherwise = (xs,ys)

I use

standardRound :: RoundRule
standardRound =  roundWithoutWar standardComparison
to run one round of the game.

I am trying to make a full game function that would run the rounds in recursion until someone wins(the winner is the person with the most cards):

fullGame :: RoundRule -> ([Card],[Card]) -> [([Card],[Card])]
fullGame r  ([],[]) = [([],[])]
fullGame r ([],y:ys)        = [([],y:ys)]
fullGame r (x:xs,[])      = [(x:xs,[])]
fullGame r (x:xs,y:ys)       = (x:xs,y:ys) : fullGame ( r (x:xs,y:ys))

"r" being the single round function (StandardRound) However, i get an error when i try to run the full game function

 War_Project_2.hs:138:46:
    Couldn't match expected type ‘[([Card], [Card])]’
                with actual type ‘([Card], [Card]) -> [([Card], [Card])]’
    Probable cause: ‘fullGame’ is applied to too few arguments
    In the second argument of ‘(:)’, namely
      ‘fullGame (r (x : xs, y : ys))’
    In the expression: (x : xs, y : ys) : fullGame (r (x : xs, y : ys))

War_Project_2.hs:138:57:
    Couldn't match type ‘([Card], [Card])’
                   with ‘([Card], [Card]) -> ([Card], [Card])’

    Expected type: RoundRule
      Actual type: ([Card], [Card])
    Possible cause: ‘r’ is applied to too many arguments
    In the first argument of ‘fullGame’, namely ‘(r (x : xs, y : ys))’
    In the second argument of ‘(:)’, namely
      ‘fullGame (r (x : xs, y : ys))’

The point free function i tried to write to run the fullgame is:

simpleFullGame ::([Card],[Card]) -> [([Card],[Card])]
simpleFullGame = fullGame simpleRound
1
  • fullGame ( r (x:xs,y:ys)) should be fullGame r ( r (x:xs,y:ys)) Commented Nov 21, 2015 at 5:12

1 Answer 1

2

There is a helpful function that almost does exactly what you are looking for.

  iterate :: (a -> a) -> a -> [a]

This can successively apply your RoundRule function which is essentially an update function. All you have to do is stop when the game is done.

done :: ([Card],[Card]) -> Bool

Then when you have that function your full game will be.

fullGame roundRule initState = takeWhile (not . done) (iterate roundRule initState)

Since Haskell is lazy it won't generate at game states beyond the end state.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.