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;
}
| |