Card Numbers

I need to get the Ace to display as either 1 or 11, depending on the score. However I'm completely lost and don't know how to achieve this. I don't want to change must of the original code or change the way the deck is. Any thoughts?

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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

#include "pch.h"
#include <iostream>
#include <algorithm> 
#include <ctime>
#include <cstdlib>


using namespace std;
#define NUMBER_OF_CARDS 52


enum SUIT { HEARTS, DIAMONDS, CLUBS, SPADES };
enum VALUES { ACE=1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, KING, QUEEN };

static const char *SUIT_STRING[] = {
	"Hearts", "Diamonds", "Clubs", "Spades",

};

static const char *VALUE_STRING[] = {
	"not used", "Ace", "2", "3", "4", "5", "6", "7", "8", "9",  "10", "JACK", "QUEEN", "KING",

};


struct Card {
	SUIT suit; // H, D, S, C
	int value; // A, 2, 3, 4, 5, 6, 7, 8, 9, 10
	int score; // A = 1 2 = 2, Q = 10


};

Card Pack[NUMBER_OF_CARDS];

Card Playerscard[5];
Card Dealercard[5];

void SetupPack();
void SetupHearts();
void SetupDiamonds();
void SetupClubs();
void SetupSpades();
void displayPack();
char Menuchoice;
void Play(); 

void Menu();
void NewGame();

void Shuffle();
void Deal();
int PlayerScore = 0;
int DealerScore = 0;

int cardcount = 0;



int main()
{

	Menu();
}


void Menu()
{
	do
	{
		cout << endl;
		cout << "Welcome to Blackjack" << endl;
		cout << "1. New Game - Press N" << endl;


		cout << endl;

		cin >> Menuchoice; cout << endl;

		cout << "You entered: " << Menuchoice; cout << endl;


		if ((Menuchoice == 'N') || (Menuchoice == 'n'))
		{
			cout << endl;
			NewGame();



	} while (Menuchoice != 'X');

}

void NewGame()
{

	cout << "New Game" << endl;

	Play();
}

void Play()

{
	PlayerScore = 0;
	DealerScore = 0;
	SetupPack();
	Shuffle();

	Deal();

	cout << endl;

	if (PlayerScore > 21)
	{
		cout << "You went bust, dealer wins";


	}

	if (DealerScore > 21)
	{
		cout << "Player wins, dealer went bust";

	}


	if (PlayerScore == 21)
	{
		cout << "Player got Black Jack, player wins!";


          }
	

	if (DealerScore == 21)
	{
		cout << "Dealer got Black Jack, dealer wins!";

	}

	cout << endl;

void SetupPack()
{
	SetupHearts();
	SetupDiamonds();
	SetupClubs();
	SetupSpades();

}

void SetupHearts()
{
	for (int loop = 0; loop <= 12; loop++)
	{
		Pack[loop].suit = HEARTS;
		Pack[loop].value = loop + 1;
		Pack[loop].score = loop + 1;

	}
	//score for Jack, Queen, King
	Pack[0].score = 11;
	Pack[10].score = 10;
	Pack[11].score = 10;
	Pack[12].score = 10;


}

void SetupDiamonds()
{
	for (int loop = 13; loop <= 25; loop++)
	{
		Pack[loop].suit = DIAMONDS;
		Pack[loop].value = loop + 1 - 13;

	}
	//score for Jack, Queen, King
	Pack[13].score = 11;
	Pack[23].score = 10;
	Pack[24].score = 10;
	Pack[25].score = 10;



}


void SetupClubs()
{
	for (int loop = 26; loop <= 38; loop++)
	{
		Pack[loop].suit = CLUBS;
		Pack[loop].value = loop + 1 - 26;

	}
	//score for Jack, Queen, King
	Pack[26].score = 11;
	Pack[36].score = 10;
	Pack[37].score = 10;
	Pack[38].score = 10;


}

void SetupSpades()
{
	for (int loop = 39; loop <= 51; loop++)
	{
		Pack[loop].suit = SPADES;
		Pack[loop].value = loop + 1 - 39; // need to take away 38 so it shows 1 - 12
		Pack[loop].score = loop + 1 - 39; // need to take away 38 so it shows 1 - 12

	}
	//score for Ace, Jack, Queen, King
	Pack[39].score = 11; //ace
	Pack[49].score = 10;
	Pack[50].score = 10;
	Pack[51].score = 10;


}

void displayPack()

{
	for (int loop = 0; loop < NUMBER_OF_CARDS; loop++)
	{
		cout << "Suit =  " << Pack[loop].suit;
		cout << " Score = " << Pack[loop].score;
		cout << " Value = " << Pack[loop].value;

		cout << endl;
	}
}

void Shuffle()
{
	unsigned seed = time(0);
	srand(seed);

	for (int Shuffle = 0; Shuffle < 100; Shuffle++)
	{
		int RandomNum1 = rand() % 52;
		int RandomNum2 = rand() % 52;

		Card CardTemp = Pack[RandomNum1];
		Pack[RandomNum1] = Pack[RandomNum2];
		Pack[RandomNum2] = CardTemp;
	}
}


void Deal()
{
	Playerscard[0] = Pack[0];

	cout << "Players first card " << SUIT_STRING[Playerscard[0].suit] << Playerscard[0].score << endl;


	if (Playerscard[0].score == 10) {
		cout << VALUE_STRING[Playerscard[0].value] << endl;
	}


	if (Playerscard[0].score == 11) {
		cout << VALUE_STRING[Playerscard[0].value] << endl;
	}

	cout << endl;

	Dealercard[0] = Pack[1];

	cout << "Dealers first card " << SUIT_STRING[Dealercard[0].suit] << Dealercard[0].score  << endl;


	if (Dealercard[0].score == 10)
		cout << VALUE_STRING[Dealercard[0].value] << endl;



	if (Dealercard[0].score == 11)
		cout << VALUE_STRING[Dealercard[0].value] << endl;


	cout << endl;

	Playerscard[1] = Pack[2];
	cout << "Players second card " << SUIT_STRING[Playerscard[1].suit] << Playerscard[1].score << endl;

	
	if (Playerscard[1].score == 10)
		cout << VALUE_STRING[Playerscard[1].value] << endl;


	if (Playerscard[1].score == 11)
		cout << VALUE_STRING[Playerscard[1].value] << endl;

	


	cout << endl;

	Dealercard[1] = Pack[3];

	cout << "Dealers second card " << SUIT_STRING[Dealercard[1].suit] << Dealercard[1].score << endl;

	if (Dealercard[1].score == 10)
		cout << VALUE_STRING[Dealercard[1].value] << endl;


	if (Dealercard[1].score == 11)
		cout << VALUE_STRING[Dealercard[1].value] << endl;

	cout << endl;

	PlayerScore = PlayerScore + Playerscard[0].score + Playerscard[1].score; cout << endl;

	cout << "Players score is: " << PlayerScore << endl;


	DealerScore = DealerScore + Dealercard[0].score + Dealercard[1].score; cout << endl;

	cout << "Dealers score is: " << DealerScore << endl;


}











you make it do what you want.

PlayerScore = PlayerScore + Playerscard[0].score + Playerscard[1].score; cout << endl;

here, you only have 2 cards and the ace is ALWAYS 11. If you have 2 aces, its 11 and 1, so you need to catch that possible combination here, its the only exception.

Later, when the player can hit and get more than 2 cards, you have to iterate.
what I would do is move the aces to the back of the hand first, eg if you had 4 cards,
2,ace, 5, jack
then resort it like this
2,5,J, A
that makes it easy to do this:
total += 2,5,j (17) (don't add the ace yet).
now, if you have an ace, you do a simple
if total + ace > 21, add 1, else add 11.
or more than once ace, it still has to iterate, say you had
2,5,A,A then the total looks like
2+5 is 7.
7+11 is 18.
18+11 is bust, try 18+1, 19 is ok, score is 19.

its going to take a bit of logic to get this into your code due to the scattered way you coded it in the first place. We have tried to warn you about this in several threads already, but your spread out logic and approach are making things harder for you and getting worse as you grow the code. This is not an insult; its actually very clear that you wrote your own code and are putting in a lot of effort, and that is noted, but the code still could use a do-over to simplify these issues to make doing stuff like handling the aces easier.

Last edited on
I just don't know how to actually approach it. Wouldn't an If statement work?

I understand my code is difficult but it seems to make sense to me.
step back from the code.
what is the question?
its how to generate the total score of a hand.
how do you do that if you have zero aces, 1 ace, 2 aces... 4 aces, 10 aces... 21 aces in a row...
an if statement to do that is going to be insanely complex. Its going to have many, many terms ored and anded together every which way and if its wrong, it will be unpossible to debug. give it a try. what does the if statement look like for 8 cards, 2,2,ace,3,ace,4,ace,jack? try to write that in such a way that it also works for 2 cards, ace and jack.

or you can iterate.
for every card in the hand
is it an ace?
yes: do ace things
no: just add it to the running total.

there are several simple ways to do it.
you can generate 2 totals into a vector<int> for each ace in the hand -- effectively generate every possible combination of totals.
or you can do what I said above ... move the aces to the end of the total, add up everything else, then add the aces with a simple rule of if the total exceeds 21, add 1, else add 11 for each ace. That seems the simplest to me. Remember you have to do this each time you add a card; you can't keep the total from the last time you computed it and you have to move the aces each time as well. But its very simple to do it this way.

Last edited on
But I don't understand how I could move the ace to the end of the total, and then add them with the code I'm using
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if nothing else you can do some logic like this:

for(all the cards)
{
     if(card == ace)
         numaces++;
     else
     runningtotal +=card.value;
}

for( x = 0; x < numaces; x++)
  {
       if(runningtotal+11 > 21) 
         runningtotal +=1;
      else
       runningtotal +=11;
  }

there is probably a better way but I don't have the energy to try to unravel it.  
Last edited on
@Robin53

I haven't quite finished my 'Blackjack' game, as I don't have betting, splitting etc., in it, but I do have up to 3 players plus the dealer, playing. Look over the code, and you can find out how I deal with aces, etc.

Source can be downloaded from my dropbox account, below
.
https://www.dropbox.com/s/l9n2ats6hawcuqv/Blackjack.cpp?dl=0
I've tried to do it like this but it doesn't work when a player twists.
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
void Deal()
{
	Playerscard[0] = Pack[0];

	cout << "Players first card " << SUIT_STRING[Playerscard[0].suit] << Playerscard[0].score << endl;


	if (Playerscard[0].score == 10) {
		cout << VALUE_STRING[Playerscard[0].value] << endl;
	}


	if (Playerscard[0].score == 11) {
		cout << VALUE_STRING[Playerscard[0].value] << endl;
	}


	
	cout << endl;

	Dealercard[0] = Pack[1];

	cout << "Dealers first card " << SUIT_STRING[Dealercard[0].suit] << Dealercard[0].score << endl;


	if (Dealercard[0].score == 10) {
		cout << VALUE_STRING[Dealercard[0].value] << endl;

	}

	if (Dealercard[0].score == 11) {
		cout << VALUE_STRING[Dealercard[0].value] << endl;


	}
	

	cout << endl;

	Playerscard[1] = Pack[2];
	cout << "Players second card " << SUIT_STRING[Playerscard[1].suit] << Playerscard[1].score << endl;

	
	if (Playerscard[1].score == 10)
		cout << VALUE_STRING[Playerscard[1].value] << endl;


	if (Playerscard[1].score == 11)
		cout << VALUE_STRING[Playerscard[1].value] << endl;

	

	

	cout << endl;

	Dealercard[1] = Pack[3];

	cout << "Dealers second card " << SUIT_STRING[Dealercard[1].suit] << Dealercard[1].score << endl;

	if (Dealercard[1].score == 10)
		cout << VALUE_STRING[Dealercard[1].value] << endl;


	if (Dealercard[1].score == 11)
		cout << VALUE_STRING[Dealercard[1].value] << endl;

	cout << endl;



	if (Playerscard[0].score == 11) {
		Acecount = Acecount + 1;
		
		if (Playerscard[1].score == 11)
			Acecount = Acecount + 1;


		if (Acecount == 2)
		{
			PlayerScore - 10;
				Acecount - 1;
		}
		if (Acecount == 1 && PlayerScore >= 22)
		{
			PlayerScore - 10;
			Acecount - 1;
		}

	
	
		if (Dealercard[0].score == 11) {
			Acecount = Acecount + 1;

			if (Dealercard[1].score == 11)
				Acecount = Acecount + 1;


			if (Acecount == 2)
			{
				DealerScore - 10;
				Acecount - 1;
			}
			if (Acecount == 1 && DealerScore >= 22)
			{
				DealerScore - 10;
				Acecount - 1;
			}
		}
	
	}
The key is recognize that the value of an ace depends on the hand you hold, not the individual card. So want to write:
int score(const Hand &);
Inside score you start by assuming that ace's are worth 11. If the score busts, then change the score of an ace to 1.

Of course, this means you need a data structure to hold a hand. Maybe vector<Card>
Referring to your original post:
Line 12 & 20: The order of QUEEN and KING do not agree.

Get rid of the double spacing. It makes your program hard to read.

As dhayden suggested, you should use a std::vector for both Pack and Hand.
Casino Blackjack uses multiple decks in a shoe.

Line 88: You're missing a close } for your if

Lines 129, 137: Both player and dealer could have 21. This is called a "push". You declare both as winners.

Line 144: You're missing a close } for function Play()

Here's a much shorter way to setup your pack.
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
void SetupSuit (SUIT s, int low, int high)
{   for (int loop = low; loop <= high; loop++)
    {   Pack[loop].suit = s;
        Pack[loop].value = loop % 13 + 1;
        Pack[loop].score = loop % 13 + 1;
    }
    //score for Jack, Queen, King
    Pack[low].score = 11;   
    Pack[low+10].score = 10;
    Pack[low+11].score = 10;
    Pack[low+12].score = 10;
}

 void SetupPack()
 {   SetupSuit (HEARTS, 0, 12); 
     SetupSuit (DIAMONDS, 13, 25); 
     SetupSuit (CLUBS, 26, 38);
     SetupSuit (SPADES, 39, 51);
}


As previously suggested, you need a single function to display a card:
1
2
3
4
5
6
void DisplayCard(const Card & c)
 {  cout << VALUE_STRING[c.value] << " of ";
    cout << SUIT_STRING[c.suit];
    cout << " Score = " << c.score;
    cout << endl;
 }


DisplayPack becomes:
1
2
3
4
5
void displayPack()
 {  for (int loop = 0; loop < NUMBER_OF_CARDS; loop++)
    {   DisplayCard(Pack[loop]);
    }
}


Line 242: I pointed out to you before:
Do not call srand() multiple times. srand() sets the RNG to a particular starting point. Calling srand() repeatedly can cause the RNG to return the same random numbers. srand() should be called ONCE at the beginning of main().
http://www.cplusplus.com/reference/cstdlib/srand/

Line 244: I also pointed out to you before, you should not name you loop index the same as your function. Is the token "Shuffle" a function pointer or a scalar? Confusing to the reader.

Here's a cleaned up version of Deal()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Deal()
{   Playerscard[0] = Pack[0];
    cout << "Players first card ";
    DisplayCard(Playerscard[0]);

    Dealercard[0] = Pack[1];
    cout << "Dealers first card ";
    DisplayCard(Dealercard[0]); 

    Playerscard[1] = Pack[2];
    cout << "Players second card ";
    DisplayCard(Playerscard[1]); 

    Dealercard[1] = Pack[3];
    cout << "Dealers second card "; 
    DisplayCard(Dealercard[1]); 
 
    PlayerScore = PlayerScore + Playerscard[0].score + Playerscard[1].score; cout << endl;
    cout << "Players score is: " << PlayerScore << endl;

    DealerScore = DealerScore + Dealercard[0].score + Dealercard[1].score; cout << endl;
    cout << "Dealers score is: " << DealerScore << endl;
}










Last edited on
Topic archived. No new replies allowed.