How does this work?

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
// Blackjack.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>

using namespace std;

class Card
{
public:
	enum rank {ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
		JACK, QUEEN, KING};
	enum suit {CLUBS, DIAMONDS, HEARTS, SPADES};

	// overloading << operator so can send Card object to standard output
	friend ostream& operator<<(ostream& os, const Card& aCard);

	Card(rank r = ACE, suit s = SPADES, bool ifu = true);

	// returns the value of a card, 1 - 11
	int GetValue() const;

	// flips a card; if face up, becomes face down and vice versa
	void Flip();

private:
	rank m_Rank;
	suit m_Suit;
	bool m_IsFaceUp;
};

Card::Card(rank r, suit s, bool ifu): m_Rank(r), m_Suit(s), m_IsFaceUp(ifu)
{}

int Card::GetValue() const
{
	// if a card is face down, its value is 0
	int value = 0;
	if (m_IsFaceUp)
	{
		// value is number showing on card
		value = m_Rank;
		// value is 10 for face cards
		if (value > 10)
			value = 10;
	}
	return value;
}

void Card::Flip()
{
	m_IsFaceUp = !(m_IsFaceUp);
}

class Hand
{
public:
	Hand();

	virtual ~Hand();

	//adds a card to the hand
	void Add(Card* pCard);

	// clears hand of all cards
	void Clear();

	// gets hand total value, inteillgiently treats aces as 1 or 11
	int GetTotal() const;

protected:
	vector<Card*> m_Cards;
};

Hand::Hand()
{
	m_Cards.reserve(7);
}

Hand::~Hand() // don't use the keyword virtual outside of class definition
{
	Clear();
}

void Hand::Add(Card* pCard)
{
	m_Cards.push_back(pCard);
}

void Hand::Clear()
{
	// iterate through vector, freeing all memory on the heap
	vector<Card*>::iterator iter = m_Cards.begin();
	for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
	{
		delete *iter;
		*iter = 0;
	}
	// clear vector of pointers
	m_Cards.clear();
}

int Hand::GetTotal() const
{
	// if no cards in hand, return 0
	if (m_Cards.empty())
		return 0;

	// if a first card has a value of 0, then card is face down; return 0
	if (m_Cards[0]->GetValue() == 0)
		return 0;

	// add up card values, treat each ace as 1
	int total = 0;
	vector<Card*>::const_iterator iter;
	for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
		total += (*iter)->GetValue();

	// determine if hand contains an ace
	bool containsAce = false;
	for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
		if ((*iter)->GetValue() == Card::ACE)
			containsAce = true;

	// if hand contains ace and total is low enough, treat ace as 11
	if (containsAce && total <= 11)
		// add only 10 since we've already added 1 for the ace
		total += 10;

	return total;
}

class GenericPlayer : public Hand
{
	friend ostream& operator<<(ostream& os, const GenericPlayer& aGenericPlayer);

public:
	GenericPlayer(const string& name = "");

	virtual ~GenericPlayer();

	// indicated whether or not generic player wants to keep hitting
	virtual bool IsHitting() const = 0;

	// returns whether generic player has busted - has a total greater than 21
	bool IsBusted() const;

	// announces that the generic player busts
	void Bust() const;

protected:
	string m_Name;
};

GenericPlayer::GenericPlayer(const string& name): m_Name(name)
{}

GenericPlayer::~GenericPlayer()
{}

bool GenericPlayer::IsBusted() const
{
	return (GetTotal() > 21);
}

void GenericPlayer::Bust() const
{
	cout << m_Name << " busts.\n";
}

class Player : public GenericPlayer
{
public:
	Player(const string& name = "");

	virtual ~Player();

	// returns whether or not the player wants another hit
	virtual bool IsHitting() const;

	// announces that the player wins
	void Win() const;

	// announces that the player loses
	void Lose() const;

	// announces that the player pushes
	void Push() const;
};

Player::Player(const string& name): GenericPlayer(name)
{}

Player::~Player()
{}

bool Player::IsHitting() const
{
	cout << m_Name << ", do you want a hit?  (Y/N): ";
	char response;
	cin >> response;
	return (response == 'y' || response == 'Y');
}

void Player::Win() const
{
	cout << m_Name << " wins.\n";
}

void Player::Lose() const
{
	cout << m_Name << " loses.\n";
}

void Player::Push() const
{
	cout << m_Name << " pushes.\n";
}

class House : public GenericPlayer
{
public:
	House(const string& name = "House");

	virtual ~House();

	// indicates wheter house is hitting - will always hit on 16 or less
	virtual bool IsHitting() const;

	// flips over the first card
	void FlipFirstCard();
};

House::House(const string& name): GenericPlayer(name)
{}

House::~House()
{}

bool House::IsHitting() const
{
	return (GetTotal() <= 16);
}

void House::FlipFirstCard()
{
	if (!(m_Cards.empty()))
		m_Cards[0]->Flip();
	else cout << "No card to flip!\n";
}

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}




1
2
3
4
5
        // add up card values, treat each ace as 1
	int total = 0;
	vector<Card*>::const_iterator iter;
	for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
		total += (*iter)->GetValue();


The second code block above, how does it work?
It is an iterator of type Card* and from the looks of it, it is doing exactly what any iterator will do. It is going through your vector called m_Cards and from the start of the vector, it is adding up the value of each card.

I bet line 5 is the one confusing you. I am stumped on that one to, I have no idea why you can't just do iter->GetValue()
Same. Could you possibly explain how GetValue works? :).
Bump.
What's to understand?
1
2
3
4
5
6
7
8
9
10
11
12
int Card::GetValue() const
{  // if a card is face down, its value is 0
    int value = 0;
    if (m_IsFaceUp)
   { // value is number showing on card
      value = m_Rank;
      // value is 10 for face cards
      if (value > 10)
         value = 10;
      }
    return value;
}

The code is distinguishing between cards that are face up or not. If a card is not face up (dealer's hole card), then it is not included in the computed value. The value is set to the rank of the card, unless it's a face card, then it is set to 10 since all face cards have a value of 10. Then the computed value is returned.

The book I have doesn't explain things very well for a beginner. I just needed the explanation that was provided above.

Thanks.
1
2
3
4
5
    //add up card values, treat each Ace as 1   
    int total = 0;   
    vector<Card*>::const_iterator iter;   
    for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)   
        total += (*iter)->GetValue();  


What does vector<Card*>. What does Card* do?
It's the vector type. It's declaring an iterator for a vector of Card*s
Could I name it to whatever I wanted to?
If this book is intended for beginners, it's a terrible book. I suggest you brush up on your knowledge before digging any deeper into this particular program.
use youtube and two books and this sites tutorials to structure your learning and you will learn at optimum speed
What two books do you recommend?
c++ for dummies isn't as easy as it sounds but it is ideal, the learning curve with books is irritating for me, i think i have a hard time interpreting what they mean, just with this book and another and a video you have more perspective on each concept, like having three different explanations on the same thing,

I found this way my brain had more data making interpreting an abstract idea into reality
Topic archived. No new replies allowed.