#include #include #include #include using std::string; using std::vector; using std::cout; using std::cin; using std::endl; using std::ostream; // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- class Card { friend ostream &operator<<(ostream&, const Card); public: string suit, face; int value; protected: private: }; // ----------------------------------------------------------------------------- ostream &operator<<(ostream& output, const Card c) { output << c.face << " of " << c.suit; return output; } // ----------------------------------------------------------------------------- static const string SUIT[4] = {"Hearts", "Diamonds", "Clubs", "Spades" }; static const string FACE[13] = {"Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"}; // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- class Deck { public: Deck(); ~Deck(); void Shuffle(void); void ShowCards(void); Card DealCard(void); protected: private: vector cards; void CreateCards(void); void SwapCards(int, int); }; // ----------------------------------------------------------------------------- Deck::Deck() { Shuffle(); } // ----------------------------------------------------------------------------- Deck::~Deck() { cards.clear(); } // ----------------------------------------------------------------------------- void Deck::CreateCards(void) { cards.clear(); Card c; int s, f; for (s=0; s < 4; s++) { // loop for all suits for (f=0; f < 13; f++) { // loop for all faces c.face = FACE[f]; c.suit = SUIT[s]; c.value = f + 1; if (c.value > 10) // make sure face cards' values = 10 c.value = 10; cards.push_back(c); } } } // ----------------------------------------------------------------------------- void Deck::Shuffle(void) { CreateCards(); int i, random_pos; for (i = 0; i < 52; i++) { random_pos = rand() % 52; SwapCards(i, random_pos); } } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- void Deck::SwapCards(int pos1, int pos2) { Card temp; temp = cards[pos1]; cards[pos1] = cards[pos2]; cards[pos2] = temp; } // ----------------------------------------------------------------------------- void Deck::ShowCards(void) { for (int i = 0; i < 52; i++) cout << cards[i].face << " of " << cards[i].suit << " with value = " << cards[i].value << endl; } // ----------------------------------------------------------------------------- Card Deck::DealCard(void) { Card rt; if (!cards.empty()) { rt = cards[0]; cards.erase(cards.begin()); } return rt; } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- class Hand { public: void AddCard(Card); void ShowHand(void); Card FirstCard(void); int Value(void); protected: private: vector cards; int value; }; // ----------------------------------------------------------------------------- void Hand::AddCard(Card c) { cards.push_back(c); value += c.value; } // ----------------------------------------------------------------------------- void Hand::ShowHand(void) { for (int i=0; i < cards.size(); i++) cout << " " << cards.at(i) << endl; } // ----------------------------------------------------------------------------- int Hand::Value(void) { int sum = 0; for (int i=0; i < cards.size(); i++) sum += cards.at(i).value; return sum; } // ----------------------------------------------------------------------------- Card Hand::FirstCard(void) { // precondition is that the cards vector is not empty - which sould always be true here return cards.at(0); } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- #define DEALER_WINS 1 #define PLAYER_WINS 2 // ----------------------------------------------------------------------------- void DisplayInfo(Hand player_hand, Hand dealer_hand) { // this module displays all info except dealer's hand (only shows first card) cout << endl << endl << "Dealer's hand" << endl; cout << " " << dealer_hand.FirstCard() << endl; cout << " - unknown card -" << endl; cout << " value = " << dealer_hand.FirstCard().value << endl << endl; cout << "Your hand" << endl; player_hand.ShowHand(); cout << " value = " << player_hand.Value() << endl << endl; } // ----------------------------------------------------------------------------- void DisplayFinalInfo(Hand player_hand, Hand dealer_hand) { cout << "Dealer's hand" << endl; dealer_hand.ShowHand(); cout << " value = " << dealer_hand.Value() << endl << endl; cout << "Your hand" << endl; player_hand.ShowHand(); cout << " value = " << player_hand.Value() << endl << endl; } // ----------------------------------------------------------------------------- int PlayGame(void) { int winner = PLAYER_WINS; Deck d; Card c; Hand player_hand; Hand dealer_hand; // deal the intial two cards to player and dealer c = d.DealCard(); player_hand.AddCard(c); c = d.DealCard(); player_hand.AddCard(c); c = d.DealCard(); dealer_hand.AddCard(c); c = d.DealCard(); dealer_hand.AddCard(c); char choice = '?'; cout << endl << endl << "NEW HAND"; // leave the loop if they "stay" or "bust" while ((player_hand.Value() <= 21) && (toupper(choice) != 'S')) { DisplayInfo(player_hand, dealer_hand); cout << "Hit or Stay (H/S)? "; cin >> choice; // add a card if the user said "hit" if (toupper(choice) == 'H') { c = d.DealCard(); player_hand.AddCard(c); } } // if player busts, dealer wins if (player_hand.Value() > 21) winner = DEALER_WINS; else { // make the dealer try to win until he "busts" or matches/exceeds player's hand while (dealer_hand.Value() < player_hand.Value()) { c = d.DealCard(); dealer_hand.AddCard(c); } // if the dealer didn't "bust", then he must have won (b/c loop only ends on win or bust) if (dealer_hand.Value() <= 21) winner = DEALER_WINS; } // show final info about hand DisplayFinalInfo(player_hand, dealer_hand); return winner; } // ----------------------------------------------------------------------------- void finish_up (int dealer_wins, int player_wins) { // display some finishing info about who won and by how much cout << endl << endl << "Dealer won " << dealer_wins << " game(s)." << endl; cout << "You won " << player_wins << " game(s)." << endl << endl; if (dealer_wins > player_wins) cout << "Too bad... dealer wins." << endl << endl; else if (dealer_wins < player_wins) cout << "YOU WIN!" << endl << endl; else cout << "It's a tie." << endl << endl; cout << "Thanks for playing!" << endl << endl; } // ----------------------------------------------------------------------------- void main (void) { srand((unsigned)time(NULL)); int done = 0; int dealer_wins = 0; int player_wins = 0; char quit; cout << "-- BLACKJACK --" << endl << endl; // loop until the user says quit while (!done) { if (PlayGame() == DEALER_WINS) { cout << endl << "Dealer wins this hand." << endl << endl; dealer_wins++; } else { cout << endl << "You win this hand!" << endl << endl; player_wins++; } cout << "Play again (Y/N)? "; cin >> quit; done = (toupper(quit) == 'N'); } finish_up(dealer_wins, player_wins); }