神刀安全网

C++ Practice Assignment #4 – Blackjack

Implementing a blackjack game in C++ can be a big task. Since the game involves players, a deck of cards and the house, we have to break down the code into smaller parts. This is where we use the power of C++’s object orientated abilities toimplement classes. Firstly we need get a visual diagram of how we are sorting the code and an overview of the game. Without this, we would get confused and lose track of what’s going where.

C++ Practice Assignment #4 – Blackjack

Now Lets have a look at how exactly we are implementing blackjack in C++ with the help of organising the code into header and implementation files. Remember that with C++, we can share data from other header files by importing in the file.

C++ Practice Assignment #4 – Blackjack

Card header file

/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:card.h ========================================================= */  /* ==================================== Defining header ==================================== */  #ifndef CARD_H #define CARD_H  /* ======================================= Included files ======================================= */ #include <iostream> #include <string> #include <vector> #include <algorithm> #include <ctime>  using namespace std;  /* ================================================= Card Class ================================================= */  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};  friend ostream&amp; operator &lt;&lt; (ostream&amp; os, const Card&amp; aCard);  Card(rank r = ACE, suit s = SPADES, bool ifu = true);  /* ================================ Returns the value of a card ================================ */ 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; };  #endif

Card implementation file

/* ========================================================= Blackjack in C++ Made By Sahil Bora Made with Visual Studio 2010 File:card.cpp ========================================================= */  #include "card.h"  /* ================================================== Card Constructor ================================================== */  Card::Card(rank r, suit s, bool ifu): m_Rank(r), m_Suit(s), m_IsFaceUp(ifu) {}  /* ========================================= Get the value of the card ========================================= */  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 &gt;10) value = 10; } return value; }  /* ================================================== Flip the card  ================================================== */ void Card::Flip() { m_IsFaceUp = !(m_IsFaceUp); }

Deck header file

<pre>/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:deck.h ========================================================= */  /* ====================================== Defining header ====================================== */ #ifndef DECK_H #define DECK_H  /* ========================================== Included files ========================================== */ #include "hand.h" #include "genericPlayerClass.h"  /* ============================================= Deck Class ============================================= */ class Deck : public Hand { public:  Deck();  virtual ~Deck();  /* ========================================= Create a standard deck of 52 cards ========================================= */ void Populate();  /* ============================== Shuffle cards ============================== */ void Shuffle();  /* =================================== Deal one card to a hand =================================== */ void Deal(Hand&amp; aHand);  /* ============================================= Give additional cards to a generic player ============================================= */ void AdditionalCards(GenericPlayer&amp; aGenericPlayer); };  #endif

Deck implementation file

/* ========================================================= Blackjack in C++ Made By Sahil Bora Made with Visual Studio 2010 File:deck.cpp ========================================================= */  /* ================================ Included files ================================ */ #include "deck.h"  /* =================================== Reserve 52 cards =================================== */ Deck::Deck() { m_Cards.reserve(52); Populate(); }  /* =============================== Deck deconstructor =============================== */ Deck::~Deck() {}  /* ======================================= Populate the cards ======================================= */ void Deck::Populate() { Clear(); /* =================================== Create standard deck =================================== */ for (int s = Card::CLUBS; s &lt;= Card::SPADES; ++s) for (int r = Card::ACE; r &lt;= Card::KING; ++r) Add (new Card(static_cast&lt;Card::rank&gt;(r), static_cast&lt;Card::suit&gt;(s))); }  /* ==================================== Randomize and Shuffle the cards ==================================== */ void Deck::Shuffle() { random_shuffle(m_Cards.begin(), m_Cards.end()); }  void Deck::Deal(Hand&amp; aHand) { if (!m_Cards.empty()) { aHand.Add(m_Cards.back()); m_Cards.pop_back(); } else { cout &lt;&lt; "Out of cards. Unable to deal"; } }  /* =============================================== Additional cards  =============================================== */  void Deck::AdditionalCards(GenericPlayer&amp; aGenericPlayer) { cout &lt;&lt; endl;  /* =================================================================== continue to deal a card as long as generic player isn't busted  and wants another hit =================================================================== */ while (!(aGenericPlayer.IsBusted()) &amp;&amp; aGenericPlayer.IsHitting()) { Deal(aGenericPlayer); cout &lt;&lt; aGenericPlayer &lt;&lt; endl;  if (aGenericPlayer.IsBusted()) aGenericPlayer.Bust(); } }

Game header file

/* ========================================================= Blackjack in C++ Made By Sahil Bora File:game.h ========================================================= */  /* ===================================== Defining header ===================================== */ #ifndef GAME_H #define GAME_H  /* ============================================= Included files ============================================= */ #include "deck.h" #include "house.h" #include "player.h"  /* ============================================== Game Class ============================================== */ class Game { public: Game(const vector&lt;string&gt;&amp; names);  ~Game();  /* ================================== Plays the game of blackjack ================================== */ void Play();  private: Deck m_Deck; House m_House; vector&lt;Player&gt; m_Players; };  #endif

Game implementation file

/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:game.cpp ========================================================= */  /* ====================================== Included files ====================================== */ #include "game.h" #include "player.h" #include "card.h"  /* ========================================= Game constructor ========================================= */ Game::Game(const vector&lt;string&gt;&amp; names) { /* ======================================================= Create a vector of players from a vector of names ======================================================= */ vector&lt;string&gt;::const_iterator pName;  for (pName = names.begin(); pName != names.end(); ++pName) m_Players.push_back(Player(*pName));  /* ===================================== The random number generator ===================================== */  srand(time(0));  m_Deck.Populate(); m_Deck.Shuffle(); }  /* ======================================== Game desconstructor ======================================== */ Game::~Game() {}  /* =============================================== Play the game =============================================== */ void Game::Play() { /* =========================================== Deal initial 2 cards to everyone  =========================================== */ vector&lt;Player&gt;::iterator pPlayer; for (int i = 0; i &lt; 2; ++i) { for (pPlayer = m_Players.begin(); pPlayer != m_Players.end();  ++pPlayer) m_Deck.Deal(*pPlayer); m_Deck.Deal(m_House); }  /* ================================== Hide house's first card ================================== */ m_House.FlipFirstCard();  /* ======================================= Display everyone's hand ======================================= */ for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer) cout &lt;&lt; *pPlayer &lt;&lt; endl; cout &lt;&lt; m_House &lt;&lt; endl;  /* ========================================== Deal additional cards to players ========================================== */ for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer) m_Deck.AdditionalCards(*pPlayer);  /* ==================================== Reveal house's first card ==================================== */ m_House.FlipFirstCard(); cout &lt;&lt; endl &lt;&lt; m_House;  /* ======================================== Deal additional cards to house ======================================== */ m_Deck.AdditionalCards(m_House);  if (m_House.IsBusted()) { /* ==================================== Everyone still playing wins ==================================== */ for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer) if (!(pPlayer-&gt;IsBusted())) pPlayer-&gt;Win(); }  else { /* ============================================== Compare each player still playing to house ============================================== */ for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer) if(!(pPlayer-&gt;IsBusted())) { if(pPlayer-&gt;GetTotal() &gt; m_House.GetTotal()) pPlayer-&gt;Win(); else if (pPlayer-&gt;GetTotal() &lt; m_House.GetTotal()) pPlayer-&gt;Lose(); else pPlayer-&gt;Push(); } }  /* ========================================== Remove everyone's cards ========================================== */ for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer) pPlayer-&gt;Clear(); m_House.Clear(); }

Generic player header file

/* ========================================================= Blackjack in C++ Made By Sahil Bora Made with Visual Studio 2010 File:genericPlayerClass.h ========================================================= */  /* ================================== Defining header ================================== */  #ifndef GENERICPLAYERCLASS_H #define GENERICPLAYERCLASS_H  /* ======================================= Included files ======================================= */  #include "card.h" #include "hand.h"  /* ================================================= Generic Player class ================================================= */ class GenericPlayer : public Hand { friend ostream&amp; operator &lt;&lt; (ostream&amp; os,  const GenericPlayer&amp; aGenericPlayer);  public: GenericPlayer(const string&amp; name = "");  virtual ~GenericPlayer();  /* ================================================================= Indicates wheater or not generic player wants to keep hitting ================================================================= */ virtual bool IsHitting() const = 0;  /* ========================================================================= returns wheater generic player has busted - has a total greater than 21 ========================================================================= */ bool IsBusted() const;  /* ============================================ Annouces that the generic player bust ============================================ */ void Bust() const;  protected: string m_Name; };  #endif

Generic Player Class Implementation file

/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:genericPlayerClass.cpp ========================================================= */  /* ====================================== Included files ====================================== */ #include "genericPlayerClass.h"  /* ===================================================== Name constructor  ===================================================== */ GenericPlayer::GenericPlayer(const string&amp; name): m_Name(name) {}  /* ====================================== Generic player ====================================== */ GenericPlayer::~GenericPlayer() {}  /* ================================================ If the player has over 21 and is busted ================================================ */  bool GenericPlayer::IsBusted() const { return (GetTotal() &gt; 21); }  /* ============================================= Say that the player is busted ============================================= */  void GenericPlayer::Bust() const { cout &lt;&lt; m_Name &lt;&lt; "busted./n"; }

Hand header file

<pre>/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:hand.h ========================================================= */  /* ========================================= Defining header ========================================= */ #ifndef HAND_H #define HAND_H  /* =============================================== Included files =============================================== */ #include "card.h"  /* ================================================= Hand Class ================================================= */  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, intelligently treats aces as 1 or 11 ============================================================== */  int GetTotal() const;  protected: vector&lt;Card*&gt; m_Cards; };  #endif

Hand implementation file

/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:hand.cpp ========================================================= */  /* ==================================== Included files ==================================== */ #include "hand.h"  /* ============================================== Reserve 7 cards  ============================================== */ Hand::Hand() { m_Cards.reserve(7); }  /* ================================================= Virtual deconstructor of Hand ================================================= */ Hand::~Hand()  { Clear(); }  /* ==================================================== Add a card  ==================================================== */ void Hand::Add(Card* pCard) { m_Cards.push_back(pCard); }  /* ================================================ Clear the cards ================================================ */  void Hand::Clear() { /* ========================================================= Iterate through vector, freezing all memory on the heap ========================================================= */ vector&lt;Card*&gt;::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(); }  /* =========================================== Get total of cards in the hand =========================================== */ int Hand::GetTotal() const { /* ============================================== If no cards in hand, return 0 ============================================== */ if(m_Cards.empty()) return 0;  /* ==================================================================== If a first can has value of 0, then card is face down; return 0 ==================================================================== */ if(m_Cards[0]-&gt;GetValue() == 0) return 0;  /* ===================================================== Add up card values, treat each ace as 1 ===================================================== */ int total = 0; vector&lt;Card*&gt;::const_iterator iter;  for(iter = m_Cards.begin(); iter != m_Cards.end(); ++iter) total += (*iter)-&gt;GetValue();  /* ========================================= Determine if hand contains an ace ========================================= */ bool containsAce = false; for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter) if ((*iter)-&gt;GetValue() == Card::ACE) containsAce = true;  /* ================================================================= If hand contains ace and total is low enough, treat ace as 11 ================================================================= */ if(containsAce &amp;&amp; total &lt;= 11) /* ======================================================= Add only 10 since we've already added 1 for the ace ======================================================= */ total +=10;  return total; }

House header file

<pre>/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:house.h ========================================================= */  /* ========================================== Defining header ========================================== */  #ifndef HOUSE_H #define HOUSE_H  /* =========================================== Included files =========================================== */  #include "genericPlayerClass.h"  /* ============================================= House Class ============================================= */  class House : public GenericPlayer { public: House(const string&amp; name = "House");  virtual ~House();  /* ==================================================================== Indicates wheater house is hitting (will always hit on 16 or less ==================================================================== */ virtual bool IsHitting() const;  /* ====================================== Flips over first card ====================================== */ void FlipFirstCard(); };  #endif

House implementation file

/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:house.cpp ========================================================= */  /* ===================================== Included files ===================================== */  #include "house.h"  /* ================================================== Generic Player game ================================================== */  House::House(const string&amp; name): GenericPlayer(name) {}  /* ========================================== House deconstructor ========================================== */ House::~House() {}  /* =========================================== If the player is hitting =========================================== */ bool House::IsHitting() const { return (GetTotal() &lt;= 16); }  /* ====================================== Flip the first card ====================================== */  void House::FlipFirstCard() { if(!(m_Cards.empty())) m_Cards[0]-&gt;Flip(); else cout &lt;&lt; "No card to flip!/n"; }

Player header

/* ========================================================= Blackjack in C++ Made with Visual Studio 2010 File:player.h ========================================================= */  /* ======================================= Defining header ======================================= */ #ifndef PLAYER_H #define PLAYER_H  /* ========================================= Included files ========================================= */ #include "genericPlayerClass.h"  /* ============================================== Player Class ============================================== */ class Player : public GenericPlayer { public: Player(const string&amp; name = "");  virtual ~Player();  /* ========================================================= Returns wheater 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; };  #endif

Player implementation file

/* ========================================================= Blackjack in C++ Made By Sahil Bora Made with Visual Studio 2010 File:card.cpp ========================================================= */  /* ======================================== Included files ======================================== */  #include "player.h"  /* ========================================== Player Generic Player constructor ========================================== */ Player::Player(const string& name): GenericPlayer(name) {}  /* ================================== Player deconstructor ================================== */ Player::~Player() {}  /* ============================================== If player wants to hit a card ============================================== */ bool Player::IsHitting() const { cout << m_Name << ", do you want a hit (Y/N): "; char response; cin >> response;  return (response == 'y' || response == 'Y');  }  /* ====================================== If the player wins ====================================== */ void Player::Win() const { cout << m_Name << " wins./n"; }  /* ======================================== If the player has lost ======================================== */  void Player::Lose() const { cout << m_Name << " loses./n"; }  /* ====================================== If the player continues ====================================== */ void Player::Push() const { cout << m_Name << " pushes./n"; }

Putting it all together in the “main.cpp” file

/* ========================================================= Blackjack in C++ Made By Sahil Bora Made with Visual Studio 2010 File:main.cpp ========================================================= */  #include "card.h" #include "deck.h" #include "game.h" #include "genericPlayerClass.h" #include "hand.h" #include "house.h" #include "player.h"  /* ======================================= Fuction prototypes ======================================= */ ostream&amp; operator &lt;&lt; (ostream&amp; os, const Card&amp; aCard); ostream&amp; operator &lt;&lt; (ostream&amp; os, const GenericPlayer&amp; aGenericPlayer);  int main() { cout &lt;&lt; "/t/tWELCOME TO BLACKJACK!/n/n";  int numPlayers = 0; while (numPlayers &lt; 1 || numPlayers &gt; 7) { cout &lt;&lt; "How many Players? (1-7): "; cin &gt;&gt; numPlayers; }  vector&lt;string&gt; names; string name; for (int i = 0; i &lt; numPlayers; ++i) { cout &lt;&lt; "Enter player name: "; cin &gt;&gt; name; names.push_back(name); } cout &lt;&lt; endl;  /* ================================ The Game Loop ================================ */ Game aGame(names); char again = 'y'; while (again != 'n' &amp;&amp; again != 'N') { aGame.Play(); cout &lt;&lt; "/nDo you want to play again? (Y/N): "; cin &gt;&gt; again; }  return 0; }  /* ============================================================ Overloads &lt;&lt; operator so Card object can be sent to cout ============================================================ */ ostream&amp; operator &lt;&lt;(ostream&amp; os, const Card&amp; aCard) { const string RANKS[] = {"0", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}; const string SUITS[] = {"c", "d", "h", "s"};  if (aCard.m_IsFaceUp) os &lt;&lt; RANKS[aCard.m_Rank] &lt;&lt; SUITS[aCard.m_Suit]; else os &lt;&lt; "XX";  return os; }  /* ====================================================================== Overloads &lt;&lt; operator so a Generic Playe object can be sent to cout ====================================================================== */ ostream&amp; operator&lt;&lt;(ostream&amp; os, const GenericPlayer&amp; aGenericPlayer) { os &lt;&lt; aGenericPlayer.m_Name &lt;&lt; ":/t";  vector&lt;Card*&gt;::const_iterator pCard; if (!aGenericPlayer.m_Cards.empty()) { for (pCard = aGenericPlayer.m_Cards.begin(); pCard != aGenericPlayer.m_Cards.end(); ++pCard) os &lt;&lt; *(*pCard) &lt;&lt; "/t"; if (aGenericPlayer.GetTotal() != 0) cout &lt;&lt; "(" &lt;&lt; aGenericPlayer.GetTotal() &lt;&lt; ")"; } else { os &lt;&lt; "&lt;empty"; }  return os; }

Share this post

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » C++ Practice Assignment #4 – Blackjack

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮