1
votes

I am writing a Cardguess Game, where user sets the answer and lets the PC guess. For my project, the input card number is 2.

Then, I need to write the cardguess algorithm. I have created the card module.

data Suit = Club | Diamond | Heart | Spade
      deriving (Eq, Ord, Bounded, Enum)

suitchars = "CDHS"

data Rank =
    R2 | R3 | R4 | R5 | R6 | R7 | R8 | R9 | R10 |
    Jack | Queen | King | Ace
         deriving (Eq, Ord, Bounded, Enum)

rankchars = "23456789TJQKA"

data Card = Card {suit::Suit, rank::Rank}
      deriving (Eq, Bounded)

instance Ord Card where
    compare (Card s1 r1) (Card s2 r2) =
        let suitorder = compare s1 s2
            in  if suitorder == EQ then compare r1 r2 else suitorder

instance Enum Card where
    fromEnum (Card s r) = (fromEnum s)*13 + (fromEnum r)
    toEnum n = (Card s r)
     where s = toEnum (n `div` 13)
           r = toEnum (n `mod` 13)

and my strategy is to separate both Suit and Rank into two parts. initial guess could be Card Club R5 , Card Heart Jack

Then I will be given the feedback, and, according to it, I will try nextGuess, so on so far, till getting the right answer.

I have written the initialGuess function.

i put the remaining cards in the GameState.

initialGuess :: Int -> ([Card], GameState)
initialGuess card_number 
     | card_number == 2   = ((Card Club R5):(Card Heart J),cardDeck)

and now, I need to write the nextGuess code.

nextGuess :: ([Card],GameState) -> (Int,Int,Int,Int,Int) ->([Card],GameState)

(Int,Int,Int,Int,Int) is the feedback value. How can i represent the first parameter ([Card],GameState), which means the previous guess cards and previous GameState.

2
You ask “How can i represent the first parameter ([Card],GameState). I don't understand what you mean by this. Please clarify. The first parameter is a representation of “the previous guess cards and previous GameState. - dave4420
how can i get the previous cards and gamestate.. seems like a recursive - J.L
That would be the concern of the piece of code that calls nextGuess. As far as nextGuess is concerned it's just a parameter, same as card_number is for initialGuess. Is your question really about how to call nextGuess? - dave4420

2 Answers

1
votes

As I don't understand your question, and you are a beginner, I am going to nitpick on some other areas of your post.

  1. You have

    initialGuess card_number 
         | card_number == 2   = ((Card Club R5):(Card Heart J),cardDeck)
    

    Accepting that you only need initialGuess 2 to work for now, you have the list syntax wrong. You mean either

    initialGuess card_number 
         | card_number == 2   = (Card Club R5 : Card Heart J : [], cardDeck)
    

    or

    initialGuess card_number 
         | card_number == 2   = ([Card Club R5, Card Heart J], cardDeck)
    

    They mean the same thing, but the latter is clearer.

  2. You have

    instance Ord Card where
        compare (Card s1 r1) (Card s2 r2) =
            let suitorder = compare s1 s2
                in  if suitorder == EQ then compare r1 r2 else suitorder
    

    If you import Data.Monoid, you can write this more simply as

    instance Ord Card where
        compare (Card s1 r1) (Card s2 r2) = compare s1 s2 `mappend` compare r1 r2
    

    But better is to leave it out and ask the compiler to write it for you instead:

    data Card = Card {suit::Suit, rank::Rank}
          deriving (Eq, Ord, Bounded)
    

    The generated Ord instance uses lexicographical ordering, as you require.

1
votes

Hard to read your mind here, but maybe you want something like this:

startGuessing guesses state = do
  feedBack <- readFeedback
  let (newGuess, newState) = nextGuess (guesses, state) feedback
  startGuessing (guesses ++ newGuess) newState

main = do
  let (guesses, state) = initialGuess 2      
  startGuessing guesses state