C++ Cards Project

I'm trying completing a book project:
"Write a program that simulates a deck of 52 playing cards. The program should present a user with a menu that allows him or her to display the deck, shuffle the deck, or quit the program. Use an array of constant string objects to represent the cards and an array of pointers to constant string objects to represent the deck. The deck should have all 52 cards in it. Another way to say this is that each pointer element in the array that represents the deck should point to a different string object in the array that represents the cards. Your program should present the user with the following menu choices:
0 - Quit
1 - Shuffle deck
2 - Display deck
"

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

#include <iostream>
#include <string>

using namespace std;


int main()
{
	cout << "\tWelcome to Inventory!" << endl;

	//items
	const int NUM_CARDS = 52;
	const int NUM_RANK = 13;
	const int NUM_SUIT = 4;
	const string rank[NUM_RANK] = {"2", "3", "4",
		"5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };
	const char suit[NUM_SUIT] = { 'c', 'h', 's', 'd' };

	int choice;         //menu choice

	do
	{
		cout << endl << "Inventory" << endl;
		cout << "---------" << endl << endl;
		cout << "0 - Quit" << endl;
		cout << "1 - Shuffle deck";
		cout << endl;
		cout << "2 - Display deck";
		cout << endl;
		cout << endl << "Choice: ";
		cin >> choice;
		cout << endl;

		switch (choice)
		{
		case 0:
			cout << "Good-bye." << endl;
			break;
		case 1:
			//cout << "Shuffled:" << endl;
			break;
		case 2:
			cout << "Deck: " << endl;
			for (int i = 0; i < NUM_RANK; i++)
			{
				for (int j = 0; j < NUM_SUIT; j++)
				{
					cout << rank[i] << suit[j] << " ";
				}
				cout << endl;
			}
			break;
		default:
			cout << "Sorry, " << choice;
			cout << " isn't a valid choice." << endl;
		}
	} while (choice != 0);

	return 0;
}


This is what I have so far. I'd also like to use functions, but I couldn't figure out how to get past assigning an array to an array(which is illegal). I do not know classes yet so I hope I can stay away from those for now.
Last edited on
vectors can be assigned to vectors. you can assign an array of simple types with memcpy function, but you need to be very careful with it, and its not safe on an array of string (or anything with hidden dynamic storage). You can also just brute force copy with a loop (safer but slower). Use vectors instead of arrays if you need these kinds of things; or generally vectors are preferred in modern c++ for almost all cases where an array is used. Arrays are just lacking in advanced features all around -- all they do is store data in a block of memory, nothing else is provided beyond access to the memory.

you don't need classes to use vectors & functions.

you can also pass arrays as a pointer into a function.

for fun, the ascii table actually contains the chars for the suits. You can use those :)

this looks pretty good as a start. See if what I said makes sense and if you can do it from here, or if you need actual code examples.


Last edited on
I don't want to use vectors if I don't have to either. Sorry I should have mentioned that. Thanks for the feedback.
for fun, the ascii table actually contains the chars for the suits.

Really, and what would be the numeric value for the CLUB symbol? If the value is greater than 127 then it is not part of the ASCII table, the ASCII table is limited to values of 0 to 127 anything else is not ASCII. And those "extended" characters are not part of the ASCII standard nor do they always represent the same glyphs.
In addition to this question there is another question:
"Modify the program in Project 4(listed above) to add a hand of cards to the mix. The hand should be able to hold up to five cards. The hand should start out empty, with no cards in it. Declare another array of pointers to strings objects to represent a hand of cards.

The user should be able to display the cards in the hand, transfer a number of cards from the deck to the hand, and transfer a number of cards from the hand back to the deck. When a user indicates that he or she wants to translate more cards than is possible, display an appropriate message and don't transfer any cards.

Update the menu system so it has the follows choices:
0 - Quit
1 - Shuffle deck
2 - Display deck
3 - Display hand
4 - Deal cards from deck to hand
5 - Return cards from deck to hand

Write a function, Transfer(), to transfer the given number of cards from one group to another. Invoke this function when the user enters menu choice 4 or 5. Since this transfer process requires a fair amount of work, create two other functions that Transfer() calls: Add(), which adds a card to a group, and Remove(), which removes a card from a group.
"

Any help with either of these two problems would be greatly appreciated. I'm still stuck and don't want to continue the book until I complete these projects.
Last edited on
I question your use of the std::strings, look at this part of your instructions:

Use an array of constant string objects to represent the cards and an array of pointers to constant string objects to represent the deck.


To me that "an array of pointers to constant string objects" infers the use of C-strings not std::strings. You may want to talk to your instructor to get a clarification.

Okay now you will need to create a Deck, remember a Deck contains 52 separate cards. And from your original post a single card consists of the "suite" ('D', 'C', 'S', 'H') and the "rank" ('1', '2', ..., 'K', 'A'), ie "2D" (two of Diamonds). Note the use of single character for the "suites" and "ranks" and a string for the "card".

So the first thing you need to do is to create a Deck (an array of cards) with the ranks and suites in order. I suggest you give this a try.

This is what I came up with. I couldn't figure out how to get the same output though.
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
#include "stdafx.h"


// Inventory
// Manages a player's inventory

#include <iostream>
#include <string>

using namespace std;

void Display(string cards[], const string * ps, const char * pc);


int main()
{
	cout << "\tWelcome to Inventory!" << endl;

	//items
	const int NUM_CARDS = 52;
	const int NUM_RANK = 13;
	const int NUM_SUIT = 4;
	const string rank[NUM_RANK] = {"2", "3", "4",
		"5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };
	const char suit[NUM_SUIT] = { 'c', 'h', 's', 'd' };
	
	
	string cards[52];
	int choice;         //menu choice

	do
	{
		cout << endl << "Inventory" << endl;
		cout << "---------" << endl << endl;
		cout << "0 - Quit" << endl;
		cout << "1 - Shuffle deck";
		cout << endl;
		cout << "2 - Display deck";
		cout << endl;
		cout << endl << "Choice: ";
		cin >> choice;
		cout << endl;

		switch (choice)
		{
		case 0:
			cout << "Good-bye." << endl;
			break;
		case 1:
			//cout << "Shuffled:" << endl;
			break;
		case 2:
			cout << "Deck: " << endl;
			Display(cards, rank, suit);
			break;
		default:
			cout << "Sorry, " << choice;
			cout << " isn't a valid choice." << endl;
		}
	} while (choice != 0);

	return 0;
}

void Display(string cards[], const string * ps, const char * pc)
{
	for (int i = 0; i < 52; i++)
	{
		cards[i] = *(ps+(i%13)) + *(pc+(i%4));
		cout << cards[i] << endl;
	}
}
I couldn't figure out how to get the same output though.

What does this mean?

Why are you trying to initialize the cards array inside your display function? The display function should only display the current contents of the "Deck", nothing else.

Also you're not "initializing" your "Deck" properly. Look at your instructions:

Your program should present the user with the following menu choices:
0 - Quit
1 - Shuffle deck
2 - Display deck


Since you need a function to shuffle your deck the "initialization" should be initializing the "Deck" sequentially.

"1C", "2C", ... "AC"
"2S", "3S", ... "AS"
...

Then in your "shuffle" function should randomly shuffle the Deck.

I updated the code.


I couldn't figure out how to get the same output though.

What does this mean?

The output of display is not "2c 2h 2s 2d"

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
#include <iostream>
#include <string>

using namespace std;

void Initialize(string cards[], const string * ps, const char * pc);

void Display(string cards[]);


int main()
{
	cout << "\tWelcome to Inventory!" << endl;

	//items
	const int NUM_CARDS = 52;
	const int NUM_RANK = 13;
	const int NUM_SUIT = 4;
	const string rank[NUM_RANK] = {"2", "3", "4",
		"5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };
	const char suit[NUM_SUIT] = { 'c', 'h', 's', 'd' };
	
	
	string cards[52];
	int choice;         //menu choice
	Initialize(cards, rank, suit);

	do
	{
		cout << endl << "Inventory" << endl;
		cout << "---------" << endl << endl;
		cout << "0 - Quit" << endl;
		cout << "1 - Shuffle deck";
		cout << endl;
		cout << "2 - Display deck";
		cout << endl;
		cout << endl << "Choice: ";
		cin >> choice;
		cout << endl;

		switch (choice)
		{
		case 0:
			cout << "Good-bye." << endl;
			break;
		case 1:
			//cout << "Shuffled:" << endl;
			break;
		case 2:
			cout << "Deck: " << endl;
			Display(cards);
			break;
		default:
			cout << "Sorry, " << choice;
			cout << " isn't a valid choice." << endl;
		}
	} while (choice != 0);

	return 0;
}

void Initialize(string cards[], const string * ps, const char * pc)
{
	for (int i = 0; i < 52; i++)
	{
		cards[i] = *(ps + (i % 13)) + *(pc + (i % 4));
	}
}
void Display(string cards[])
{
	for (int i = 0; i < 52; i++)
	{
		cout << cards[i] << " ";
		if ((i+1) % 4 == 0)
			cout << endl;
	}
}

The output of display is not "2c 2h 2s 2d"

Why would you expect that output from your initialization function?

Did you try printing out the values that that function is generating?
Thank you for your help. I can now Display and Shuffle. This is my Shuffle function:
1
2
3
4
5
6
7
8
9
10
void Shuffle(string cards[])
{
	for (int i = 0; i < 52; i++)
	{
		int rnd = rand() % 51;
		string temp = cards[i];
		cards[i] = cards[rnd];
		cards[rnd] = temp;
	}
}


I still have to complete the second part of this project:

"Modify the program in Project 4(listed above) to add a hand of cards to the mix. The hand should be able to hold up to five cards. The hand should start out empty, with no cards in it. Declare another array of pointers to strings objects to represent a hand of cards.

The user should be able to display the cards in the hand, transfer a number of cards from the deck to the hand, and transfer a number of cards from the hand back to the deck. When a user indicates that he or she wants to translate more cards than is possible, display an appropriate message and don't transfer any cards.

Update the menu system so it has the follows choices:
0 - Quit
1 - Shuffle deck
2 - Display deck
3 - Display hand
4 - Deal cards from deck to hand
5 - Return cards from deck to hand

Write a function, Transfer(), to transfer the given number of cards from one group to another. Invoke this function when the user enters menu choice 4 or 5. Since this transfer process requires a fair amount of work, create two other functions that Transfer() calls: Add(), which adds a card to a group, and Remove(), which removes a card from a group."

Last edited on
Thank you for your help. I can now Display and Shuffle. This is my Shuffle function:


Have you considered std::shuffle instead of trying to roll your own?

The jumble function is used from a previous chapter in my book( https://www.amazon.com/C-Projects-Programming-Text-Based-Games/dp/1423902270 )
Last edited on
I'm stuck. The initial add works but can't remove from hand. Also, having trouble with the count algorithm(highlighted in bold; was told on irc can't use uninitialized strings so count won't work):
#include "stdafx.h"


// Inventory
// Manages a player's inventory

#include <iostream>
#include <string>
#include <ctime>

using namespace std;

void Initialize(string cards[], const string * ps, const char * pc);

void Display(string cards[], int size);

void Shuffle(string cards[]);

void Transfer(string cards[], string hnd[], int size, int fun);

void Add(string cards[], string hnd[], int size);

void Remove(string cards[], string hnd[], int size);



int main()
{
cout << "\tWelcome to Inventory!" << endl;
srand(time(NULL));
//items
const int NUM_CARDS = 52;
const int NUM_RANK = 13;
const int NUM_HAND = 5;
const int NUM_SUIT = 4;
const string rank[NUM_RANK] = {"2", "3", "4",
"5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };
const char suit[NUM_SUIT] = { 'c', 'h', 's', 'd' };


string deck[NUM_CARDS];
string hand[NUM_HAND] = { "" };
int choice; //menu choice
int input;
Initialize(deck, rank, suit);

do
{
cout << endl << "Inventory" << endl;
cout << "---------" << endl << endl;
cout << "0 - Quit" << endl;
cout << "1 - Shuffle deck";
cout << endl;
cout << "2 - Display deck";
cout << endl;
cout << "3 - Display hand";
cout << endl;
cout << "4 - Deal cards from deck to hand";
cout << endl;
cout << "5 - Return cards from hand to deck";
cout << endl;
cout << endl << "Choice: ";
cin >> choice;
cout << endl;

switch (choice)
{
case 0:
cout << "Good-bye." << endl;
break;
case 1:
Shuffle(deck);
cout << "Shuffled" << endl;
break;
case 2:
cout << "Deck: " << endl;
Display(deck, 52);
break;
case 3:
cout << "Hand: " << endl;
Display(hand, 5);
break;
case 4:
do
{
cout << "Enter number of cards to add to hand: ";
cin >> input;

} while (input < 0 || input > NUM_HAND);
cout << "Dealing cards from deck..." << endl;
Transfer(deck, hand,input, 1);
break;
case 5:
do
{
cout << "Enter number of cards to remove from hand: ";
cin >> input;

} while (input < 0 || input > NUM_HAND);
cout << "Removing cars from hand..." << endl;
Transfer(deck, hand, input, 2);
break;
default:
cout << "Sorry, " << choice;
cout << " isn't a valid choice." << endl;
}
} while (choice != 0);

return 0;
}

void Initialize(string cards[], const string * ps, const char * pc)
{
for (int i = 0; i < 52; i++)
{
cards[i] = *(ps + (i % 13)) + *(pc + (i % 4));
}
}
void Display(string cards[], int size)
{
for (int i = 0; i < size; i++)
{
cout << cards[i] << " ";
if ((i+1) % 4 == 0)
cout << endl;
}
}

void Shuffle(string cards[])
{
for (int i = 0; i < 52; i++)
{
int rnd = rand() % 51;
string temp = cards[i];
cards[i] = cards[rnd];
cards[rnd] = temp;
}
}

void Transfer(string cards[], string hnd[], int size, int fun)
{

int count = 0;
for (int i = 0; i < size; i++)
if (!hnd[i].empty())
count++;

cout << count << endl;
//adding
if (fun == 1)
{
if ((size + count) > 5)
{
cout << "Too many cards. Please try again." << endl;
return;
}
Add(cards, hnd, size);
}
//removing
else if (fun == 2)
{
if (size > count)
{
cout << "Hand is too small. Please try again." << endl;
return;
}
Remove(cards, hnd, size);
}
}

void Add(string cards[], string hnd[], int size)
{
for (int i = 51, j = 0; i > (51 - size); i--)
{
hnd[j++] = cards[i];
cards[i] = "";
}
}

void Remove(string cards[], string hnd[], int size)
{

int count = 0;
for (int i = 0; i < size; i++)
if (!hnd[i].empty())
count++;

for (int i = (51-size), j = count-1; i > 52; i++, j--)
{
cards[i] = hnd[j];
hnd[j] = "";
}
}
Last edited on
I'm afraid that you don't have the data that the assignment calls for. Reread the assignment carefully and declare the data that's required. I'll point out some of the mistakes:

Use an array of constant string objects to represent the cards

What one array of constant string objects in your program represents cards? I see two arrays (rank and suit), not one.

and an array of pointers to constant string objects to represent the deck

You have string deck[NUM_CARDS]; which is not an array of pointers.

Last edited on
Here is the good enough version of the assignment. Thanks for the help.

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
#include "stdafx.h"


// Inventory
// Manages a player's inventory

#include <iostream>
#include <string>
#include <ctime>

using namespace std;

void Initialize(string cards[], const string * ps, const char * pc);

void Display(string cards[], int size);

void Shuffle(string cards[]);

void Transfer(string cards[], string hnd[], int size, int fun);

void Add(string cards[], string hnd[], int size);

void Remove(string cards[], string hnd[], int size);



int main()
{
	cout << "\tWelcome to Inventory!" << endl;
	srand(time(NULL));
	//items
	const int NUM_CARDS = 52;
	const int NUM_RANK = 13;
	const int NUM_HAND = 5;
	const int NUM_SUIT = 4;
	const string rank[NUM_RANK] = {"2", "3", "4",
		"5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };
	const char suit[NUM_SUIT] = { 'c', 'h', 's', 'd' };
	
	
	string deck[NUM_CARDS];
	string hand[NUM_HAND] = { "" };
	int choice;         //menu choice
	int input;
	Initialize(deck, rank, suit);

	do
	{
		cout << endl << "Inventory" << endl;
		cout << "---------" << endl << endl;
		cout << "0 - Quit" << endl;
		cout << "1 - Shuffle deck";
		cout << endl;
		cout << "2 - Display deck";
		cout << endl;
		cout << "3 - Display hand";
		cout << endl;
		cout << "4 - Deal cards from deck to hand";
		cout << endl;
		cout << "5 - Return cards from hand to deck";
		cout << endl;
		cout << endl << "Choice: ";
		cin >> choice;
		cout << endl;

		switch (choice)
		{
		case 0:
			cout << "Good-bye." << endl;
			break;
		case 1:
			Shuffle(deck);
			cout << "Shuffled" << endl;
			break;
		case 2:
			cout << "Deck: " << endl;
			Display(deck, 52);
			break;
		case 3:
			cout << "Hand: " << endl;
			Display(hand, 5);
			break;
		case 4:
			do
			{
				cout << "Enter number of cards to add to hand: ";
				cin >> input;

			} while (input < 0 || input > NUM_HAND);
			cout << "Dealing cards from deck..." << endl;
			Transfer(deck, hand,input, 1);
			break;
		case 5:
			do
			{
				cout << "Enter number of cards to remove from hand: ";
				cin >> input;
				
			} while (input < 0 || input > NUM_HAND);
			cout << "Removing cars from hand..." << endl;
			Transfer(deck, hand, input, 2);
			break;
		default:
			cout << "Sorry, " << choice;
			cout << " isn't a valid choice." << endl;
		}
	} while (choice != 0);

	return 0;
}

void Initialize(string cards[], const string * ps, const char * pc)
{
	for (int i = 0; i < 52; i++)
	{
		cards[i] = *(ps + (i % 13)) + *(pc + (i % 4));
	}
}
void Display(string cards[], int size)
{
	for (int i = 0; i < size; i++)
	{
		cout << cards[i] << " ";
		if ((i+1) % 4 == 0)
			cout << endl;
	}
}

void Shuffle(string cards[])
{
	for (int i = 0; i < 52; i++)
	{
		int rnd = rand() % 51;
		string temp = cards[i];
		cards[i] = cards[rnd];
		cards[rnd] = temp;
	}
}

void Transfer(string cards[], string hnd[], int size, int fun)
{
	//adding
	if (fun == 1)
	{
		Add(cards, hnd, size);
	}
	//removing
	else if (fun == 2)
	{
		Remove(cards, hnd, size);
	}
}

void Add(string cards[], string hnd[], int size)
{
	int count1 = 0;
	for (int i = 0; i < 5; i++)
		if (!hnd[i].empty())
			count1++;
	cout << count1 << endl;
	if (size + count1 > 5)
	{
		cout << "Too many cards.  Please try again." << endl;
		return;
	}
	for (int i = 51, j = 0; i > (51 - size); i--)
	{
		hnd[j++] = cards[i];
		cards[i] = "";
	}
}

void Remove(string cards[], string hnd[], int size)
{
	int count1 = 0;
	for (int i = 0; i < 5; i++)
		if (!hnd[i].empty())
			count1++;
	cout << count1 << endl;
	int count2 = 0;
	for (int i = 0; i < 52; i++)
		if (!cards[i].empty())
			count2++;
	cout << count2 << endl;
	if (size > count1)
	{
		cout << "Hand is too small. Please try again." << endl;
		return;
	}
	for (int i = (count2), j = (count1-1); i < (count2+size); i++, j--)
	{
		cards[i] = hnd[j];
		hnd[j] = "";
	}
}
I still think you're going to get penalized for not following the instructions.
Topic archived. No new replies allowed.