c++ 2) Casino Blackjack (This is a long problem; even if you don\'t finish it do
ID: 3682947 • Letter: C
Question
c++
2) Casino Blackjack (This is a long problem; even if you don't finish it do as much as you can on it since it provides good practice with classes and objects in a mildly complicated program.) In this problem, you will use the DeckOfCards class created in the previous exercise to construct a simulation program that determines how frequently the dealer will go "bust" when playing the casino game "Blackjack". The simulation involves dealing a large number of Blackjack hands according to the dealer-rule "stand on soft-17" and reporting the frequencies of various scoring outcomes. In this version of Blackjack, a player initially receives 2 cards and optionally draws 1, 2 or 3 more in an attempt to bring the total value of the cards as close as possible to 21 without going over. To determine the value of the hand, the cards labeled 2 through 10 are scored respectively 2 through 10 points each, so-called "Face cards" (jack, queen, and king) are scored as 10 points, and the ace can count as either 1 or 11, whichever is better for the player. If the score is over 21 the player loses (the player is "busted"), regardless what the dealer does. When played in a casino, the dealer plays according to fixed rules. For this simulation, we'l assume the casino employs the "stand on soft-17" rule that is more advantageous for the player. Regardless the player's score, the dealer is required to continue drawing cards until his/her hand achieves a value of 17 or more, or goes bust. Since an ace counts as either 1 or 11 points, each ace results in two possible scores for a hand. A "soft score" is a score that includes one or more acesExplanation / Answer
//Black Jack:
//Plays a simple version of the casino blackjack game with 1 to 7 players.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> // srand, random_shuffle
#include <ctime> // time()
using namespace std;
//-------------------------------------------------------------------- Class Card:
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};
Card(rank r, suit s): m_Rank(r), m_Suit(s) {}
int getValue() const // returns the value of a card: 1 - 10
{
int value = m_Rank; // value is number showing on card
if(value > 10) value = 10; // value is 10 for face cards
return value;
}
friend ostream& operator<<(ostream& os, const Card& card);
private:
rank m_Rank;
suit m_Suit;
};
ostream& operator<<(ostream& os, const Card& card)
{
switch(card.m_Rank)
{
case Card::ACE: os << "Ace"; break; // Program Hierarqui |
case Card::TWO: os << "Two"; break; // |
case Card::THREE: os << "Three"; break; // GroupOfCards |
case Card::FOUR: os << "Four"; break; // / |
case Card::FIVE: os << "Five"; break; // / |
case Card::SIX: os << "Six"; break; // / |
case Card::SEVEN: os << "Seven"; break; // (v)GenericPlayer Deck |
case Card::EIGHT: os << "Eight"; break; // / |
case Card::NINE: os << "Nine"; break; // / |
case Card::TEN: os << "Ten"; break; // / |
case Card::JACK: os << "Jack"; break; // (v)Player House(v) |
case Card::QUEEN: os << "Queen"; break; // |
case Card::KING: os << "King"; break; // (v):virtual |
}
switch(card.m_Suit)
{
case Card::CLUBS: os << " Clubs"; break;
case Card::DIAMONDS: os << " Diamonds"; break;
case Card::HEARTS: os << " Hearts"; break;
case Card::SPADES: os << " Spades"; break;
}
return os;
}
//---------------------------------------------------------------- Group of Cards:
class GroupOfCards
{
public:
GroupOfCards(int n) : m_AreFaceup(true) {m_Cards.reserve(n);}
void addCard(Card card) {m_Cards.push_back(card);} // Adds a card to the group
void flipCards() {m_AreFaceup = !m_AreFaceup;}
ostream& printTo(ostream& os) const // Show only faceup cards
{
if(m_AreFaceup) for(auto& card : m_Cards) os << card << ", ";
return os << m_Cards.size() << " cards";
}
protected:
vector<Card> m_Cards;
bool m_AreFaceup;
};
ostream& operator<<(ostream& os, GroupOfCards& gc)
{
return gc.printTo(os);
}
//---------------------------------------------------------- Class Generic Player:
class GenericPlayer: public GroupOfCards
{
public:
GenericPlayer(const string& name = "") : GroupOfCards(7), m_Name(name) {}
// Note that this is the only virtual function in this program
virtual bool isHitting() const = 0; // Indicates if player will keep hitting
int getTotal() const // Gets hand total value, treats aces as 1 or 11
{
int total = 0;
bool containsAce = false;
for(auto& card : m_Cards) // Add up card values, treast each ace as 1
{ // and determine if hand contains ace
total += card.getValue();
if(card.getValue() == Card::ACE) containsAce = true;
}
// If hand contains ace and total is low enough, treat ace as 11
if(containsAce && total <= 11) total += 10; // Add only 10 since we've added 1
return total;
}
bool isBusted() const {return (getTotal()>21);}
void bust() const {cout << m_Name << ": busts. ";}
void total() const {cout<<m_Name<<": ("<<getTotal()<<")";} // Hand total value
ostream& printTo(ostream& os) const
{
os << m_Name << ": ";
return GroupOfCards::printTo(os);
}
protected:
string m_Name;
};
ostream& operator<<(ostream& os, GenericPlayer& gp)
{
return gp.printTo(os);
}
//------------------------------------------------------------------ Class Player:
class Player : public GenericPlayer
{
public:
Player(const string& name = "") : GenericPlayer(name) {}
virtual bool isHitting() const override // Returns if player wants another card
{
cout << m_Name << ", do you want a hit? (Y/N): ";
char response;
cin >> response;
return (response == 'y' || response == 'Y');
}
void win() const {total(); cout << " wins. ";}
void lose() const {total(); cout << " loses. ";}
void push() const {total(); cout << " pushes. ";}
};
//-Class House:
class House : public GenericPlayer
{
public:
House(const string& name = "House") : GenericPlayer(name) {}
virtual bool isHitting() const override {return getTotal() <= 16;}
};
//-------------------------------------------------------------------- Class Deck:
class Deck : public GroupOfCards
{
public:
Deck() : GroupOfCards(52) // Create a shuffled standard deck of 52 cards
{
for(int s = Card::CLUBS; s<=Card::SPADES; ++s)
for(int r = Card::ACE; r<=Card::KING; ++r)
m_Cards.push_back(Card(static_cast<Card::rank>(r),
static_cast<Card::suit>(s)));
srand(static_cast<unsigned int>(time(0))); // Seed the random generator
random_shuffle(m_Cards.begin(),m_Cards.end()); // Shuffle cards
}
void deal(GenericPlayer& player) // Deal one card to a player
{
player.addCard(m_Cards.back()); // There are enough cards for seven playes
m_Cards.pop_back();
}
void additionalCards(GenericPlayer& gp) // Gives additional cards to a player
{
cout << endl;
while(!gp.isBusted() && gp.isHitting())
{
deal(gp);
cout << gp << endl;
if(gp.isBusted()) gp.bust();
}
}
};
//-------------------------------------------------------------------- Class Game:
class Game
{
public:
Game(const vector<string>& names)
{ // Create a vector of players froma a vector of names
for(auto& name : names) m_Players.push_back(Player(name));
}
void play(); // Plays the game of blackjack
private:
Deck m_Deck;
House m_House;
vector<Player> m_Players;
};
void Game::play()
{
for(int i = 0; i<2; ++i) // Deal initial 2 cards to everyone
{
for(auto& player : m_Players) m_Deck.deal(player);
m_Deck.deal(m_House);
}
m_House.flipCards(); // Hide house's cards
for(auto& player : m_Players) cout << player << endl; // Display everyones hand
cout << m_House << endl;
for(auto& player : m_Players) m_Deck.additionalCards(player);
m_House.flipCards(); // Reveal house's cards
cout << endl << m_House;
m_Deck.additionalCards(m_House); // Deal additional cards to house
cout << endl;
m_House.total();
cout << endl;
if(m_House.isBusted())
{
for(auto& player : m_Players)
if(!player.isBusted()) player.win(); // Everyone still playing wins
}
else
{
for(auto& player : m_Players) // Compare each player still playing to house
{
if(!player.isBusted())
{
int playerTotal = player.getTotal();
int houseTotal = m_House.getTotal();
if(playerTotal>houseTotal) player.win();
else if(playerTotal < houseTotal) player.lose();
else player.push();
}
}
}
}
//-------------------------------------------------------------------------- main:
int main ()
{
cout << "================== Welcome to BlackJack! ================== ";
int numPlayers = 0;
while(numPlayers < 1 || numPlayers>7)
{
cout << "How many players? (1 to 7): ";
cin >> numPlayers;
}
vector<string> names;
cout << endl;
for(int i = 1; i<=numPlayers; ++i)
{
cout << "Enter player name " << i << ": ";
string name;
cin >> name;
names.push_back(name);
}
char again = 'y';
while(again != 'n' && again != 'N') // The multiple game loop
{
cout << " -------------------------------------------------- Lets go: ";
Game game(names);
game.play();
cout << " Do you want to play again? (Y/N): ";
cin >> again;
}
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.