Defining header file contents for drawing a card

Hi all, I have just started in C++ and currently I am having trouble with my assignment in which the question in itself sounds very vague? The question is as follows : I am to design and implement a class to represent a playing card, that can be used to play card games.
One of the requirements is that I can only have a card.h, card.cpp and a main.cpp files.

First, I need to know if I am on the right track: My understanding to the question is that I will need to shuffle then draw a card out of a deck (52 cards). While doing so, I will also need to display the contents of the drawn card only (its suit and value). Can I assume as such?

Secondly can I put multiple classes within a header file? At the moment I am not very sure if I am on the right track. Would appreciate if someone could guide me along.

Currently my Header file (card.h) contains the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef CARD_H
#define CARD_H
#include<string>
#include<iostream>

using namespace std;
 
class Card
{
 
    private:
        string suits[4] = {"Hearts", "Diamond", "Clubs". "Spades"};
        string values[13] = {"Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};
 
    public:
        Card();
        Card(string cardSuit, string cardValue);
        
        void draw();
        void display();
        
};
#endif 
Yes a header file can contain multiple classes. However to store a deck of cards I would create a class Deck like so - just an idea.
1
2
3
4
5
6
7
8
9
10
11
class Deck
{
public:
   Deck(); // creates all the 52 Card objects and stores them in the vector
   void Shuffle();
   Card Draw();
   size_t GetCount();
   void Reset();
private:
   vector<Card> m_Cards;
};
The question is as follows : I am to design and implement a class to represent a playing card, that can be used to play card games.

That sounds straightforward.
My understanding to the question is that I will need to shuffle then draw a card out of a deck (52 cards).

Woh. The question doesn't say anything about a deck or shuffling or drawing. So I'm very confused. Can you post the full text of the assignment?

As for your card class, an individual card doesn't need to have a list of all the suits and values. It just needs the suit and value of the current card itself.

I think you should store the value of the card as an integer (or an enum if you've studied those yet). That way you can easily tell if one card's value is greater than another. You can also examine a hand of 5 cards to see if they contain a straight (5 values in a row).
That's about the full text of my assignment - Design and implement a class to represent a playing card, that can be used to play card games. Consider what information you needs to be stored in a card and what you want to do with a card (accessors/mutators). You can only have a Card.h and Card.cpp, main.cpp is optional.


Then in that case, I suppose I should not have a deck at all? And I have not learn enum yet

At the moment, the following is the contents of my header file:
1
2
3
4
5
6
7
8
9
10
11
12
13
class card
{
    private:
        string cardSuit;
        string cardValue;

    public:
        string displayCard(string, string);
        string getSuit();
        string getValue();
        card();

};


While my implementation file is as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
#include "card.h"

using namespace std;


card::card()
{
    srand(time(0));
    cardSuit = getSuit();
    cardValue = getValue();
}


string card::displayCard(string suit, string value)
{
    return cardSuit + " of " + cardValue;
}


string card::getSuit()
{

    string arrSuits[] = {"HEARTS", "DIAMONDS", "CLUBS", "SPADES"};

    // 1 out of 4 suits is choose randomly
    int randSuits = rand() % 4;
    return arrSuits[randSuits];
}

string card::getValue()
{
    string arrValues[] = {"ACE", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING"};

    // 1 out of 13 values is choose randomly
    int randValues = rand() % 13;

    return arrValues[randValues];
}


Is this a good way to generate the suit and value of the card?
Last edited on
Is there a reason why you declare value and suit as a string ?

Is this a good way to generate the suit and value of the card?
1
2
3
4
5
6
7
8
9
string card::getValue()
{
    string arrValues[] = {"ACE", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING"};

    // 1 out of 13 values is choose randomly
    int randValues = rand() % 13;

    return arrValues[randValues];
}


I don't think so. Since you need 52 cards - how do you want to avoid duplicates?
Is there a reason why you declare value and suit as a string ?


Well, I thought this may makes my life easier..

And I am interpreting my question as a single card and hence the code I have written as above.. Now I am at a lost
I would do it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <string>

using namespace std;

const int HEARTS = 0;
const int DIAMONDS = 1;
const int CLUBS = 2;
const int SPADES = 3;

class Card
{
public:
  Card (int suit, int val);
  int getValue ();
  int getSuit ();
  void display ();
private:
  int mSuit, mValue;
};

Card::Card (int suit, int val)
{
  mSuit = suit;
  mValue = val;
}

int Card::getValue ()
{
  return mValue ;
}
int Card::getSuit ()
{
  return mSuit;
}

void Card::display ()
{
  string Suits[] = { "HEARTS", "DIAMONDS", "CLUBS", "SPADES" };
  string Values[] = 
  { 
    "ACE", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", 
    "SEVEN", "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING" 
  };

  cout << Suits[mSuit] << '\t' << Values[mValue];
}

int main ()
{
  Card card (HEARTS, 9);

  card.display ();
  system ("pause");
  return EXIT_SUCCESS;
}


A class Deck I have mentioned earlier.
Thomas195 is right. Advantages of doing it his way include:
- You can create a specific card, which also means you can create a deck of cards.
- You can compare two cards by value. This is important when playing games where you need to know which card is "higher" and when you need to analyze a hand to see if it contains a straight.
- It's small compared to storing the suit and value by string.

I would do some things related to display a little differently. Consider:
- what if you wanted to prompt a user with the possible suit values?
- what if you wanted to display a straight as "TWO THREE FOUR FIVE and SIX of HEARTS"?
- what if you wanted to let the user enter a card by string (e.g. "FOUR OF DIAMONDS"
and then create the corresponding card?
- what if you want to write the display string to a file?

For all of these reasons, I would expose the arrays of string values in the interface. Also, I'd create a "toString()" method that creates the string version of the card. Here is what I mean (based on Thomas195's code and with changes highlighted).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <string>

using namespace std;

const int HEARTS = 0;
const int DIAMONDS = 1;
const int CLUBS = 2;
const int SPADES = 3;

class Card
{
public:
    Card(int suit, int val);
    int getValue();
    int getSuit();
    static const char *suitStrings[];
    static const char *valueStrings[];
    string toString();
private:
    int mSuit, mValue;
};

Card::Card(int suit, int val)
{
    mSuit = suit;
    mValue = val;
}

int
Card::getValue()
{
    return mValue;
}

int
Card::getSuit()
{
    return mSuit;
}


const char *
Card::suitStrings[] = {
    "HEARTS", "DIAMONDS", "CLUBS", "SPADES"
};

const char *
Card::valueStrings[] = {
        "ACE", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX",
        "SEVEN", "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING"
};

string
Card::toString()
{
    string result = valueStrings[mValue];
    result += " of ";
    result += suitStrings[mSuit];
    return result;
}

int
main()
{
    Card card(HEARTS, 9);

    cout << card.toString();
    return 0;
}

Topic archived. No new replies allowed.