SLIDE 1
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− // Card, Deck and Player classes // This is in header (*.h) file(s) // Remember how header file guard look? #ifndef BLACKJACK_CLASSES_H #define BLACKJACK_CLASSES_H #include <iostream> #include <vector> #include <random> //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− class Card { public: std::ostream& print(std::ostream& os); // "getter" functions access private parts safe int getValue() const { return value; } std::string getSuit() const { return suit; } int getBlackjackValue() const; private: friend class Deck; Card(int v, std::string s); int value; // 1 − 13 std::string suit; // hearts, diamonds, clubs, spades }; //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− class Deck { public: Deck(); void shuffle(); Card top(); private: std::vector<Card> deck; // Create only one instance of random_device in your program, // creating several, or recreating one, will possibly yield // not−very−random numbers. // static: one for all instances of class static std::random_device rand; };
nov 05, 13 11:33 Page 1/7
blackjack.cc
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− class Player { public: Player(std::string n); // default values in interface specification (header file) void draw(Deck& d, int count = 1); bool decideToHit(); bool blackjack() const { return sum == 21; } bool stands() const { return stopped; } bool busted() const { return sum > 21; } // const: no member variable is modified int getScore() const { return sum; } std::string getName() const { return name; } private: std::string name; int sum; bool stopped; }; #endif // end of header guard
nov 05, 13 11:33 Page 2/7
blackjack.cc
Printed by Klas Arvidsson tisdag november 05, 2013 1/4 blackjack.cc
SLIDE 2 //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− // Card, Deck and Player implementation // This is in implementation (*.cc) file(s) // Would #include "blackjack_classes.h" //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− using namespace std; // Card member functions //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Card::Card(int v, string s) : value(v), suit(s) { // initializer list preferred over this // value = v; // suit = s; } // A long way toward operator<<
- stream& Card::print(ostream& os)
{ return os << value << " of " << suit; } int Card::getBlackjackValue() const { return min(value, 10); } // Deck member functions and members //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− // static member must be created once! random_device Deck::rand; Deck::Deck() { for (int v = 1; v <= 13; ++v) { deck.push_back(Card(v, "hearts")); deck.push_back(Card(v, "diamonds")); deck.push_back(Card(v, "spades")); deck.push_back(Card(v, "clubs")); } } // std::shuffle would work instead void Deck::shuffle() { for (int i = 0; i < 52; ++i) { swap(deck.at(i), deck.at( rand() % 52 )); } } Card Deck::top() { Card c = deck.back(); deck.pop_back(); return c; }
nov 05, 13 11:33 Page 3/7
blackjack.cc
// Player member functions //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Player::Player(string n) : name(n), sum(0), stopped(false) { // initializer list preferred over this // name = n; // sum = 0; // stopped = false; } bool Player::decideToHit() { string answer; cout << name << ", your score is " << sum << "." << endl; cout << "Do you want to take a hit? (Y/n) "; getline(cin, answer); bool hit = (answer.size() == 0 || answer == "y" || answer == "yes"); stopped = !hit; return hit; } void Player::draw(Deck& d, int count) { for (int i = 0; i < count; ++i) { Card card = d.top(); cout << name << " draws "; card.print(cout) << endl; if (card.getBlackjackValue() == 1 && (sum + 11) <= 21) sum += 11; else sum += card.getBlackjackValue(); if (sum > 21) { cout << name << " busted." << endl; } } }
nov 05, 13 11:33 Page 4/7
blackjack.cc
Printed by Klas Arvidsson tisdag november 05, 2013 2/4 blackjack.cc
SLIDE 3
// A simplified implementation of the card game Blackjack // see wikipedia for full information of the game #include <iostream> #include <vector> #include <algorithm> // sort using namespace std; //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− // main program in it’s own implementation file // Would #include "blackjack_classes.h" //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− int main() { // discuss what happen when variables are declared Deck my_deck; // discuss how call to member function works my_deck.shuffle(); cout << "Welcome to the game of Blackjack!" << endl; vector<Player> v{ Player("One"), Player("Two"), Player("Three"), Player("Four"), Player("Five") }; unsigned int done = 0; // Start by drawing two cards... for ( Player& player : v) { player.draw(my_deck); player.draw(my_deck); }
nov 05, 13 11:33 Page 5/7
blackjack.cc
// Play the game... while ( done < v.size() ) { cout << endl << "Next round −−−−−−−−−−−−−−−−" << endl; done = 0; for ( Player& player : v) { if ( player.busted() ) { cout << player.getName() << " had gone bust!" << endl; ++done; } else if ( player.blackjack() ) { cout << player.getName() << " have Blackjack!" << endl; ++done; } else if ( player.stands() ) { cout << player.getName() << " stands." << endl; ++done; } else if ( player.decideToHit() ) { player.draw(my_deck); } else // Player choose to stand { ++done; } } }
nov 05, 13 11:33 Page 6/7
blackjack.cc
Printed by Klas Arvidsson tisdag november 05, 2013 3/4 blackjack.cc
SLIDE 4
vector<Player>::iterator end; end = remove_if(v.begin(), v.end(), [](Player const& p)−>bool { return p.getScore() > 21; }); v.erase(end, v.end()); sort(v.begin(), v.end(), [](Player const& a, Player const& b)−>bool { return a.getScore() > b.getScore(); }); if ( v.size() == 0 ) { cout << "No winner!" << endl; } else { int winning_score = v.at(0).getScore(); unsigned int i{0}; while ( i < v.size() && v.at(i).getScore() == winning_score ) { cout << v.at(i).getName() << " wins! (score " << winning_score << ")" << endl; ++i; } } return 0; }
nov 05, 13 11:33 Page 7/7
blackjack.cc
Printed by Klas Arvidsson tisdag november 05, 2013 4/4 blackjack.cc