deck of cards

So im having trouble adding cards to a deck. im stuck on how to add the face and suits to one vector. In the end i have to print out a shuffled deck, but i need to get the all cards into a deck first.
Any suggestions for how to add the cards to the deck.

header.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
using namespace std;

enum Face { three, four, five, six, seven, eight, nine, ten, jack, queen, king, joker };
enum Suit { diamonds, spades, hearts, stars, clubs };

class Cards
{
private:
	Face f;
	Suit s;
public:
	string card(Face f, Suit s);
	string toString();

};


implementation.cpp
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
  #include <iostream>
#include <string>
#include "header.h"

using namespace std;


string Cards::card(Face f, Suit s)
{
	//having all the enum be strings
	switch (s)
	{
	case clubs: "Clubs";
		break;
	case diamonds:  "Diamonds";
		break;
	case hearts: "Hearts";
		break;
	case spades: "Spades";
		break;
	case stars:  "Stars";
		break;
	
	}

	switch (f)
	{
	case three: "Three";
		break;
	case four:  "Four";
		break;
	case five: "Five";
		break;
	case six:  "Six";
		break;
	case seven:  "Seven";
		break;
	case eight: "Eight";
		break;
	case nine: "Nine";
		break;
	case ten:  "Ten";
		break;
	case jack: "Jack";
		break;
	case queen: "Queen";
		break;
	case king: "King";
		break;
	}
        //joker has no face so is just return as joker
	if (f == joker)
	{
		return "joker";
	}
}
//toString function that returns a string in the form “face of suit” 
string Cards::toString()
{

	return card(f, s);
}
	


source.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  #include <iostream>
#include <vector>
#include <string>
#include "header.h"


using namespace std;

int main()
{
	
	vector<Cards> deckOfCards;
	for (int f = 0; f < 12; f++) //stuck here
	{
		Cards deck(f, s);

		deckOfCards.push_back(deck);
	}
}
Last edited on
Hi,

First some ideas about naming, it's important in C++ - it can affect the design:

The Cards class should be IMO Card, because it is a single card.

Name your files after the class, as in Card.hpp (header file with cpp code) and Card.cpp.

Try to avoid single char names for variables, choose something meaningful, as in FaceValue , SuitValue. You need to change your class declaration in the header file to alter this. If you can choose something better as a name than that then go for it !

IMO, you don't need a separate function to initialise a card. You can do it with the constructor. Funnily enough this will be named Card::Card.

In the constructor, you need to set the values for all the member variables. It's a bit confusing to name the arguments to the constructor the same as the class members. I like to append "Arg" to them, as in:

1
2
3
4
5
6
Card::Card(const Face FaceArg, const Suit SuitArg) 
   // set member variable values with member initialization list
  : // colon introduces member initialization list
FaceValue(FaceArg),
SuitValue(SuitArg)
{}


So that code you can get rid of all your switch statements in the constructor.

However, you will need them in your toString function. If a function doesn't alter the state of a class (i.e alter the value of member variables) then the function should be marked const:

1
2
string Cards::toString() const
{


Your switch statements are incorrect at the moment, in each case, you should assign a value to a string variable for the face value, then append another string to it for the Suit, then return the whole string.

in main, what is the value of the variable s on line 15? Always initialise your variables to something, the compiler should have warned about that.

deck is not a good name for a variable on line 15, it's just a single card.

In an enum, one can specify values which are different to the default ones:

1
2
enum Face { three=3, four, five, six, seven, eight, nine, ten, jack, queen, king, joker }; // joker is 14
enum Suit { diamonds=20, spades, hearts, stars, clubs }; // clubs is 24 


Does star mean a wild card, as in any suit? If so, generate one with a random number. Also need to select any suit if the joker is the current card.

A good way to initialise the whole deck, is to loop from 0 to 52, then use integer division to get the SuitValue, and modulus to get the FaceValue

Good Luck !!

Last edited on
what do you mean by this, because im not sure im following.

you should assign a value to a string variable for the face value, then append another string to it for the Suit, then return the whole string.


is there an example you can give!

Thank you for helping me out!
Last edited on
Not sure how to get the shuffle working, but i got it to display all the cards and yes there are supposed to be doubles.
in the source.cpp i have used static_cast. Which worked but a friend in my class showed me that but id rather not use it since if there is another option
sorry for the long code. I was sure on how to tackle using
use integer division to get the SuitValue, and modulus to get the FaceValue


card.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
#include <string>
using namespace std;

enum Face { three, four, five, six, seven, eight, nine, ten, jack, queen, king, joker };
enum Suit { diamonds , spades, hearts, stars, clubs, none};

class Card
{
	friend ostream& operator<<(ostream& os, const Card& dt);
private:

	Face faceValue;
	Suit suitValue;

public:

	Card(const Face face, const Suit suit);
	string toString();

};


Card.cpp
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include <iostream>
#include <vector>
#include <string>
#include "card.h"

using namespace std;


Card::Card(const Face faceArg, const Suit suitArg)
	:
	faceValue(faceArg),
	suitValue(suitArg)
{
	
	
}
string Card::toString()
{
	switch (faceValue)
	{
	case three:
		switch (suitValue)
		{
		case clubs: return "Three of Clubs";
			break;
		case diamonds: return "Three of Diamods";
			break;
		case hearts: return "Three of Hearts";
			break;
		case spades: return "Three of Spades";
			break;
		case stars: return "Three of Stars";
			break;
		case none:
			break;

		}
		break;
	case four:
		switch (suitValue)
		{
		case clubs: return "four of Clubs";
			break;
		case diamonds: return "four of Diamods";
			break;
		case hearts: return "four of Hearts";
			break;
		case spades: return "four of Spades";
			break;
		case stars: return "four of Stars";
			break;
		case none:
			break;
		}
		break;
	case five:
		switch (suitValue)
		{
		case clubs: return "Five of Clubs";
			break;
		case diamonds: return "Five of Diamods";
			break;
		case hearts: return "Five of Hearts";
			break;
		case spades: return "Five of Spades";
			break;
		case stars: return "Five of Stars";
			break;
		case none:
			break;
		}
		break;
	case six:
		switch (suitValue)
		{
		case clubs: return "Six of Clubs";
			break;
		case diamonds: return "Six of Diamods";
			break;
		case hearts: return "Six of Hearts";
			break;
		case spades: return "Six of Spades";
			break;
		case stars: return "Six of Stars";
			break;
		case none:
			break;
		}
		break;
	case seven:
		switch (suitValue)
		{
		case clubs: return " Seven of Clubs";
			break;
		case diamonds: return "Seven of Diamods";
			break;
		case hearts: return "Seven of Hearts";
			break;
		case spades: return "Seven of Spades";
			break;
		case stars: return "Seven of Stars";
			break;
		case none:
			break;
		}
		break;
	case eight:
		switch (suitValue)
		{
		case clubs: return "Eight of Clubs";
			break;
		case diamonds: return "Eight of Diamods";
			break;
		case hearts: return "Eight of Hearts";
			break;
		case spades: return "Eight of Spades";
			break;
		case stars: return "Eight of Stars";
			break;
		case none:
			break;
		}
		break;
	case nine:
		switch (suitValue)
		{
		case clubs: return "Nine of Clubs";
			break;
		case diamonds: return "Nine of Diamods";
			break;
		case hearts: return "Nine of Hearts";
			break;
		case spades: return "Nine of Spades";
			break;
		case stars: return "Nine of Stars";
			break;
		case none:
			break;
		}
		break;
	case ten:
		switch (suitValue)
		{
		case clubs: return "Ten of Clubs";
			break;
		case diamonds: return "Ten of Diamods";
			break;
		case hearts: return "Ten of Hearts";
			break;
		case spades: return "Ten of Spades";
			break;
		case stars: return "Ten of Stars";
			break;
		case none: 
			break;
		}
		break;
	case jack:
		switch (suitValue)
		{
		case clubs: return "Jack of Clubs";
			break;
		case diamonds: return "Jack of Diamods";
			break;
		case hearts: return "Jack of Hearts";
			break;
		case spades: return "Jack of Spades";
			break;
		case stars: return "Jack of Stars";
			break;
		case none: 
			break;
		}
		break;
	case queen:
		switch (suitValue)
		{
		case clubs: return "Queen of Clubs";
			break;
		case diamonds: return "Queen of Diamods";
			break;
		case hearts: return "Queen of Hearts";
			break;
		case spades: return "Queen of Spades";
			break;
		case stars: return "Queen of Stars";
			break;
		case none:
			break;
		}
		break;
	case king:
		switch (suitValue)
		{
		case clubs: return "King of Clubs";
			break;
		case diamonds: return "King of Diamods";
			break;
		case hearts: return "King of Hearts";
			break;
		case spades: return "King of Spades";
			break;
		case stars: return "King of Stars";
			break;
		case none: 
			break;
		}
		break;
	case joker: return "Joker";
		break;
	
	}		
}
ostream& operator<<(ostream& os, const Card& card)   //not sure what to add here 
{
	
	return os;
}


source.cpp
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
#include <iostream>
#include <vector>
#include <algorithm>    // std::random_shuffle
#include <random>
#include <string>
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand
#include "card.h"

using namespace std;

int myrandom(int i) { return std::rand() % i; }

int main()
{
	std::srand(unsigned(std::time(0)));
	std::vector<Card> deckOfCards;
	for (int s = 0; s <= 5; s++)
	{
		for (unsigned int f = 0; f <= 11; f++)
		{
			//is there a better way to do this then using static_cast. 
				Card adding = Card(static_cast<Face>(f), static_cast<Suit>(s)); 
				deckOfCards.push_back(adding);
				deckOfCards.push_back(adding);
			
		}
	}
	

	for (int i = 0; i < 116; i++) {
		cout << deckOfCards[i].toString() << endl;
	}
	system("pause");	


	


	// using built-in random generator:
	std::random_shuffle(deckOfCards.begin(), deckOfCards.end());

	// using myrandom:
	std::random_shuffle(deckOfCards.begin(), deckOfCards.end(), myrandom);

	
	for (std::vector<Card>::iterator it = deckOfCards.begin(); it != deckOfCards.end(); ++it)
		std::cout << ' ' << *it << "\n";   // here it was making me overload the << operator but im not sure    
//what to put in the fuction in file Card.cpp

	system("pause");

	return 0;

}
Hi,


what do you mean by this, because im not sure im following.


TheIdeasMan wrote:
you should assign a value to a string variable for the face value, then append another string to it for the Suit, then return the whole string.


Have a string variable CardAsString , then have a switch:

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
std::string CardAsString;

switch (faceValue)
{
case three:
    CardAsString = "Three of ";
    break;
case four:
    CardAsString = "Four of ";
    break;
  // .....
}

switch (suitValue)
		{
		case clubs: CardAsString +=  "Clubs";
			break;
		case diamonds: CardAsString +=   "Diamods";
			break;
		case hearts: CardAsString +=   "Hearts";
			break;
		case spades: CardAsString +=   "Spades";
			break;
		case stars: return "Stars";  // I guess this means any suit, so need separate code to randomly select 
			break;
		

		}
return CardAsString;


CardAsString could be a member of Card

Here is a better way to print out the whole vector using a range based for loop, easier than using iterators:

1
2
3
for (const auto& ACard : deckOfCards ) {
      std::cout << ACard.toString();
}


std::random_shuffle has been deprecated, use std::shuffle.

TheIdeasMan wrote:
use integer division to get the SuitValue, and modulus to get the FaceValue


If you have 11 cards per suit, and there 4 suits, and there are say 44 unique cards per deck. Then if you have a loop from 0 to 44 using variable i. So i modulus 11 gives the face value of the card, while 44 / i gives the suit. This all ties back to the enum values. You might need to alter the default values of the enum like I mentioned earlier.

For the operator<< look at the example near the bottom here:
http://en.cppreference.com/w/cpp/language/operators
Last edited on
Thank you for the response!
I have a question: what is the ACard in the range based loop for, what would that mean in terms of what i need. Because when i used that in the program it needed to be initialized.

Also would i still keep the switch statements under the toString() and then just create a member in the class for CardAsString
http://en.cppreference.com/w/cpp/language/range-for

Also would i still keep the switch statements under the toString() and then just create a member in the class for CardAsString


yes
I would recommend using a Deck object when using many cards as a game or other thing the same. The star is for a pointer so you can pass objects by their address. I think you should go slow using pointers as it can get complicated sometimes. Also, as a new to C++ I can recommend code security, especially for C++ and it's complication. I sometimes use Checkmarx for that.
Anyway, good luck!
Ben.
Can't thank you enough for helping me out. This program really was messing with my head but now i understand it better. Everything works perfectly now, so i really appreciate your guidance.
Topic archived. No new replies allowed.