Difference: Lab9 (24 vs. 25)

Revision 252018-04-03 - JimSkon

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Lab 9 - Blackjack

Due: November 28, 11:55pm

Moodle Link
blackjack-01.jpg

Blackjack Game using objects

What is Blackjack?

Blackjack, also known as twenty-one, is the most widely played casino banking game in the world. Blackjack is a comparing card game between a player and dealer, meaning players compete against the dealer but not against other players. It is played with one or more decks of 52 cards. The objective of the game is to beat the dealer in one of the following ways:

  1. Get 21 points on the player's first two cards (called a "blackjack" or "natural"), without a dealer blackjack;
  2. Reach a final score higher than the dealer without exceeding 21; or
  3. Let the dealer draw additional cards until his or her hand exceeds 21.
Here is a link to a small web based version of the game: BlackJack

You are given a start of the code, which you must finish. You can get the start from Github here. Download the files, start s new project to NetBeans, and add the files to the NetBeans project.

The Overview

The goal of this lab is to use classes and objects to create a program to play Blackjack (21). A start of the program is given below, you must continue this program to complete the game.

The code below includes the following classes:

  1. Card - This is a single card with a suit and a rank (which is a given card's "state". The suit and rank are represented by the enum types (also in the code). The rank enum is design with "ACE=1" which allows for easy conversion between the rank and the integer value of the card. The methods on a card are Card(...) (the contructors) and CardName(...) and CardValue(...)which return the value of the card.
  2. Hand - This is essentually an arbitary group of playable cards. It contains zero or more Card objects (stored in a vector). The Hand class has the Hand() construct to create the (empty) hand, Add(...) to add a card to that hand, bool Wins() to tell you if the player wins by hitting 21, a Clear() to empty the hand, a GetCardList() to get a list of the card in the hand, and a GetTotal() to get the total value of the hand. Note that there are two hands - one for the house, and one for the player.
  3. Deck - This is similar ot the hand in that it is a set of cards. It is different in that it had (hidden inside) a pool of 52 cards from which it creates a deck which gets played from. As you play from the deck it gets smaller, until it is empty. WHen it is empty you will need to reinitialize the Deck to 52 cards. The deck includes the Deck() constructer, the clear() and GetCardList() (like the hand's member functions), the Populate() to remake a new deck of 52 card (from the pool), a Shuffle to randomize the deck, a Deal to remove the top card from the deck and return it.
These classes are incomplete, as is the main.cpp coude. In addition, you will need to add a new class (and associated files) for a game class to keep track of the numbers of wins, loses, and pushes (ties). The Game class should merely keep counters for player, house, and pushes, and have methods for incrementing these. Then it should have a displayScore() function to show the current score.

Note that as you play the cards in the deck get used up. This is normal. You will need to come up with a better plan on what to do when the deck runs out, and implement it. This may require modifying and even adding new member functions to the existing object classes.

Below shows the object oriented design for the system:

CardGameOBJ.png

This is a multi-file solution. There are actually 7 files in what I give you. You will need to create these files in the project. You will also need to create and add two more for the game class. Below is a picture of what the files will look like in your project.

Screen_Shot_2016-11-07_at_3.43.17_PM.png

You will need to right click on the "Source Files" directory, and pick New->C++ Class ... to create the .cpp and .h files in the right directories. Then you will need to replace the default content with the files listed below.

Screen_Shot_2016-11-07_at_3.44.48_PM.png

Grading Table

Requirement Grading Comments Points Score
Easy to use user interface   10  
C++ code includes comments, with project information at top, pre and post conditions for each functions and other comments as needed.   5  
The C++ code has good formatting, indentation, and organization.   5  
Good variable and function names, appropriate use of constants rather then literal numbers.   5  
Functional decomposition: Program is factored into functions. The "main" function should NOT be a single big function, but rather should be a series of calls to functions.   10  
Class Design: Appropriate methods added to existing to extend functionality, new class design clean and meaningful   10  
Class implementation: Logic is correctly implemented in the correct class methods   20  
Game Class: correct defined and added   10  
Runs: Runs correctly, Turn in a run with at total of at least 10 hands of play.   30  
Total   100  

Lab Object

Use classes and objects to complete the program to play Blackjack (21). Using the code here, you will create a game that:

  1. Plays the house agains a single player.
  2. Play a game of Blackjack until someone wins, and then annoucing the winner, and tallying the wins, loses, and ties (pushes)
  3. Allow the user to continue to play again, drawing from the same (shrinking) deck, until the deck is empty.
  4. You may offer the user the chance to restart the deck when done.

Card.h

%CODE{"c++"}% // A class for Playing Cards #ifndef CARD_H #define CARD_H

using namespace std; enum cRank { // Blank is a special rank to signal out of cards BLANK = 0, ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING };

Changed:
<
<
enum suit {
>
>
enum cSuit {
  CLUBS, DIAMONDS, HEARTS, SPADES };

class Card { public: // Card Constructors Card();

Changed:
<
<
Card(cRank r, suit s);
>
>
Card(cRank r, cSuit s);
  // Get the short name of a card (1s, Kc) string CardName() const;

// Get the long name (Ace of Hearts, 3 of Diamonds) string CardNameLong() const;

// Get the numeric value of the card // (Will be the face value, though some cards may have multiple values based on need) int GetValue() const; // 1-13

private:

Changed:
<
<
cRank m_Rank; suit m_Suit;
>
>
cRank rank; cSuit suit;
 };

#endif /* CARD_H */ %ENDCODE%

Card.cpp

%CODE{"c++"}% // Implementation of Card class #include #include #include #include "Card.h"

//Constructor

Card::Card() {

Changed:
<
<
m_Rank = ACE; m_Suit = CLUBS;
>
>
rank = ACE; suit = CLUBS;
 }
Changed:
<
<
Card::Card(cRank r, suit s) { m_Rank = r; m_Suit = s;
>
>
Card::Card(cRank r, cSuit s) { rank = r; suit = s;
 }

string Card::CardName() const { const string RANKS[] = {"0", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}; const string SUITS[] = {"c", "d", "h", "s"};

Changed:
<
<
return (RANKS[m_Rank] + SUITS[m_Suit]);
>
>
return (RANKS[rank] + SUITS[suit]);
 }

string Card::CardNameLong() const { // To be written return ("3 of Clubs"); }

int Card::GetValue() const { //value is number showing on card

Changed:
<
<
int value = m_Rank;
>
>
int value = rank;
  //value is 10 for face cards if (value > 10) { value = 10; } return value; }
Added:
>
>
 %ENDCODE%

Hand.h

%CODE{"c++"}% // A class for a Hand of playing cards
Deleted:
<
<
#ifndef HAND_H #define HAND_H
 using namespace std;

class Hand { public: Hand();

//adds a card to the hand void Add(Card& card);

//clears hand of all cards void Clear();

//gets total value of hand, intelligently treats aces as 1 or 11 int GetTotal();

// returns true of card sum is over 21 bool isBusted();

Changed:
<
<
// return true if player has exactly 21
>
>
// return true if plyyer has exactly 21
  bool Wins();

// returns a list of current cards hand. string GetCardList();

private:

Changed:
<
<
vector m_Cards;
>
>
vector cards;
 };
Added:
>
>
 #endif /* HAND_H */ %ENDCODE%

Hand.cpp

%CODE{"c++"}% // Implementation of Hand class #include #include #include #include "Card.h" #include "Hand.h"

Hand::Hand() {

Changed:
<
<
m_Cards.reserve(7);
>
>
cards.reserve(7);
 }

void Hand::Add(Card& card) { // add a card to hand

Changed:
<
<
m_Cards.push_back(card);
>
>
cards.push_back(card);
 }

bool Hand::Wins() { // Need to write, currently always busted. // Return true if this hand wins (21) return false ; //return false for testing }

void Hand::Clear() { //clear vector of cards

Changed:
<
<
m_Cards.clear();
>
>
cards.clear();
 }

string Hand::GetCardList() { string list = "";

Changed:
<
<
for (int i = 0; i < m_Cards.size(); i++) { list += m_Cards[i].CardName() + " ";
>
>
for (int i = 0; i < cards.size(); i++) { list += cards[i].CardName() + " ";
  } return list;

}

int Hand::GetTotal() { // Compute the total sum of the cards in hand // needs to be smart, the ACE is 11 or 1, whichever gets you closer to 21 without going over. int total = 0; // just return 0 for testing return total; }

bool Hand::isBusted() { // Need to write, currently always busted. // Return true if this hand is busted, otherwise return false return false; } %ENDCODE%

Deck.h

%CODE{"c++"}% // A class for a deck of playing card
Deleted:
<
<
#ifndef DECK_H #define DECK_H
 using namespace std;

const int DECKSIZE = 52;

Added:
>
>
#ifndef DECK_H #define DECK_H
  class Deck { public: Deck();

//clears deck of all cards void Clear();

//creates deck of 52 cards void Populate();

//shuffles cards void Shuffle();

//deals one card Card Deal();

Deleted:
<
<
// Return Deck size int Size();
  // create a string list of all the cards in this deck. string GetCardList();

private:

Changed:
<
<
vector m_Cards; // Used to store a list of current cards in Deck.
>
>
vector Cards; // Used to store a list of current cards in Deck.
 };

#endif /* DECK_H */

Added:
>
>
 %ENDCODE%

Deck.cpp

%CODE{"c++"}% // Implementation of Deck class #include #include #include
Deleted:
<
<
#include <time.h> #include <stdlib.h>
 #include "Card.h" #include "Deck.h"

// Private functions needed for shuffling void seedRandom() { srand(time(NULL)); }

Changed:
<
<
// random number between 0 and 51 int nextRandom() { int random = rand()%52;
>
>
double nextRandom() { double random = ((double) rand()) / RAND_MAX;
  return random; }

Deck::Deck() { seedRandom(); //seed the random number generator Populate(); }

void Deck::Clear() { //clear vector

Changed:
<
<
m_Cards.clear();
>
>
Cards.clear();
 }

void Deck::Populate() {

Changed:
<
<
Clear();
>
>
Clear(); // clear out the deck before you create a new one
 
Changed:
<
<
//create deck
>
>
//create deck by getting a copy of each card in the pool and placing it in the deck
  for (int s = CLUBS; s <= SPADES; ++s) { for (int r = ACE; r <= KING; ++r) {
Changed:
<
<
m_Cards.push_back(Card(static_cast (r), static_cast (s)));
>
>
Cards.push_back(Card(static_cast (r), static_cast (s)));
  } } }

void Deck::Shuffle() {

Changed:
<
<
// You do }

int Deck::Size() { return m_Cards.size();

>
>
// This needs to randomize the cards in the deck // you will need to use the random function to do this
 }

Card Deck::Deal() {

Changed:
<
<
// // Before dealing, check if the deck is empty, if so repopulate and shuffle, then draw.
>
>
// Pulls the top card out of the deck // and gives it to the caller // Make a special zero valued card in case we have nothing left
  Card aCard(BLANK,CLUBS);
Changed:
<
<
if (m_Cards.empty()) { aCard = m_Cards.back(); m_Cards.pop_back();
>
>
if (Cards.empty()) { aCard = Cards.back(); Cards.pop_back();
  } else { cout << "Out of cards, Unable to deal.\n"; } return aCard; }

string Deck::GetCardList() { string list = "";

Changed:
<
<
for (int i = 0; i < m_Cards.size(); i++) { list += m_Cards[i].CardName() + " ";
>
>
for (int i = 0; i < Cards.size(); i++) { list += Cards[i].CardName() + " ";
  } return list;

}

Added:
>
>
 %ENDCODE%
Changed:
<
<

main.cpp Blackjack

>
>

main Blackjack.cpp

 
<-- SyntaxHighlightingPlugin -->
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include "Card.h"
#include "Hand.h"
#include "Deck.h"

using namespace std;

void Instructions() {
    cout << "\tGoal: Reach 21 without going over\n\n";
    cout << "\tThe House (computer player) will be playing against you\n\n";
    cout << "\tIf the House busts (goes over), you win.\n\n";
    cout << "\tIf the House doesn't bust, you win, if your\n";
    cout << "\ttotal value is greater than the House's\n\n";
    cout << "\tIf the player gets 21 and the House doesn't\n";
    cout << "\tthe player is a winner\n\n";
    cout << "\tIf a player and the House both get 21\n";
    cout << "\tit is declared a push (tie)\n\n";
    cout << "\tc = clubs, d = diamonds, h = hearts, s = spades\n\n";
}

void displayPlayer(string name, Hand h) {
    cout << name << " shows " << h.GetCardList() << " count " << h.GetTotal() << endl;
}

int main() {
    Deck gameDeck;
    char opt;

    cout << "\t\tWelcome to Blackjack! Have fun playing!\n\n";
    Instructions();

    Hand player;
    Hand house;
    Card c;
    Card houseCard2; // A second card the house holds until the end
    
    // You will need to add a main loop wrapping a single game, allow the player
    // to keep playing, and keeping track of the score
    // You must create a new object class "Game".  The game object will keep track of the number of wins,  losses, and pushes
    // and will report the score when asked.

    //set up the game deck
    gameDeck.Populate();
    gameDeck.Shuffle();

    // Give house the first two cards
    // first card gets shown, second hid until end.
    c = gameDeck.Deal();
    house.Add(c);
    // Get a second house card to play after the player finishes (but don't play))
    houseCard2 = gameDeck.Deal();

    cout << "The Dealer deals two cards to the house and reveals one: " << c.CardName() << endl;

    // Give the player's their first card
    c = gameDeck.Deal();
    player.Add(c);
    cout << "The Dealer deals you a card: " << c.CardName() << endl;

    // loop giving deal a card until player stands or goes bust
    do {
        // show game state
        displayPlayer("House", house);
        displayPlayer("Player", player);
        cout << "Stand, or hit you with another card? (S or H)";
        cin >> opt;
        opt = tolower(opt);
        // Give the player another card as long as they want one
        if (opt == 'h') {
            // deal player a card ... you write this
        }
        // loop until the player stands, goes bust, or wins
    } while (opt != 's' && !player.isBusted() && !player.Wins());

    // Play last house card if the player didn't bust
    if (!player.isBusted()) {
        // write this code
    }
    cout << "Game over, final results:" << endl;
    //show game state
    displayPlayer("House", house);
    displayPlayer("Player", player);

    // finally examine state of hands and tell user who wins, why they win or if it is a push (tie)

    // Show winners and losers
    return 0;
}
<-- end SyntaxHighlightingPlugin -->

Sample Run

Deleted:
<
<
 
              Welcome to Blackjack! Have fun playing!

        Goal: Reach 21 without going over

        The House (computer player) will be playing against you

        If the House busts (goes over), you win.

        If the House doesn't bust, you win, if your
        total value is greater than the House's

        If the player gets 21 and the House doesn't
        the player is a winner

        If a player and the House both get 21
        it is declared a push (tie)

        c = clubs, d = diamonds, h = hearts, s = spades

The Dealer deals two cards to the house and reveals one: 4c
The Dealer deals you a card: Jh
House shows 4c  count 4
Player shows Jh  count 10
Stand, or hit you with another card? (S or H)h
You get a Kc
House shows 4c  count 4
Player shows Jh Kc  count 20
Stand, or hit you with another card? (S or H)s
House plays Ac
Game over, final results:
House shows 4c Ac  count 15
Player shows Jh Kc  count 20
Player wins with a higher count!
Overall Score:
   Player: 1
   House: 0
   Pushes: 0
Play again (y or Y)? y
The Dealer deals two cards to the house and reveals one: Js
The Dealer deals you a card: 8c
House shows Js  count 10
Player shows 8c  count 8
Stand, or hit you with another card? (S or H)h
You get a Qd
House shows Js  count 10
Player shows 8c Qd  count 18
Stand, or hit you with another card? (S or H)s
House plays 4d
Game over, final results:
House shows Js 4d  count 14
Player shows 8c Qd  count 18
Player wins with a higher count!
Overall Score:
   Player: 2
   House: 0
   Pushes: 0
Play again (y or Y)? y
The Dealer deals two cards to the house and reveals one: Jd
The Dealer deals you a card: 10s
House shows Jd  count 10
Player shows 10s  count 10
Stand, or hit you with another card? (S or H)h
You get a 2c
House shows Jd  count 10
Player shows 10s 2c  count 12
Stand, or hit you with another card? (S or H)h
You get a 2s
House shows Jd  count 10
Player shows 10s 2c 2s  count 14
Stand, or hit you with another card? (S or H)h
You get a 7c
House plays 8d
Game over, final results:
House shows Jd 8d  count 18
Player shows 10s 2c 2s 7c  count 21
Player wins with a perfect 21!
Overall Score:
   Player: 3
   House: 0
   Pushes: 0
Play again (y or Y)? y
The Dealer deals two cards to the house and reveals one: As
The Dealer deals you a card: Jc
House shows As  count 11
Player shows Jc  count 10
Stand, or hit you with another card? (S or H)h
You get a Ah
House plays Ad
Game over, final results:
House shows As Ad  count 12
Player shows Jc Ah  count 21
Player wins with a perfect 21!
Overall Score:
   Player: 4
   House: 0
   Pushes: 0
Play again (y or Y)? y
The Dealer deals two cards to the house and reveals one: 4s
The Dealer deals you a card: 8h
House shows 4s  count 4
Player shows 8h  count 8
Stand, or hit you with another card? (S or H)h
You get a 8s
House shows 4s  count 4
Player shows 8h 8s  count 16
Stand, or hit you with another card? (S or H)s
House plays Qc
Game over, final results:
House shows 4s Qc  count 14
Player shows 8h 8s  count 16
Player wins with a higher count!
Overall Score:
   Player: 5
   House: 0
   Pushes: 0
Play again (y or Y)? y
The Dealer deals two cards to the house and reveals one: 6d
The Dealer deals you a card: 3c
House shows 6d  count 6
Player shows 3c  count 3
Stand, or hit you with another card? (S or H)h
You get a 3d
House shows 6d  count 6
Player shows 3c 3d  count 6
Stand, or hit you with another card? (S or H)h
You get a 10h
House shows 6d  count 6
Player shows 3c 3d 10h  count 16
Stand, or hit you with another card? (S or H)s
House plays 3s
Game over, final results:
House shows 6d 3s  count 9
Player shows 3c 3d 10h  count 16
Player wins with a higher count!
Overall Score:
   Player: 6
   House: 0
   Pushes: 0
Play again (y or Y)? y
The Dealer deals two cards to the house and reveals one: 10c
The Dealer deals you a card: 7h
House shows 10c  count 10
Player shows 7h  count 7
Stand, or hit you with another card? (S or H)h
You get a 6c
House shows 10c  count 10
Player shows 7h 6c  count 13
Stand, or hit you with another card? (S or H)h
You get a 5d
House shows 10c  count 10
Player shows 7h 6c 5d  count 18
Stand, or hit you with another card? (S or H)s
House plays 3h
Game over, final results:
House shows 10c 3h  count 13
Player shows 7h 6c 5d  count 18
Player wins with a higher count!
Overall Score:
   Player: 7
   House: 0
   Pushes: 0
Play again (y or Y)? y
The Dealer deals two cards to the house and reveals one: 9d
The Dealer deals you a card: 6s
House shows 9d  count 9
Player shows 6s  count 6
Stand, or hit you with another card? (S or H)h
You get a 5s
House shows 9d  count 9
Player shows 6s 5s  count 11
Stand, or hit you with another card? (S or H)h
You get a 4h
House shows 9d  count 9
Player shows 6s 5s 4h  count 15
Stand, or hit you with another card? (S or H)h
You get a 7s
Player is busted! (over 21)
Game over, final results:
House shows 9d  count 9
Player shows 6s 5s 4h 7s  count 22
Player busted so house wins.
Overall Score:
   Player: 7
   House: 1
   Pushes: 0
Play again (y or Y)? s
The Dealer deals two cards to the house and reveals one: Ks
The Dealer deals you a card: 9s
House shows Ks  count 10
Player shows 9s  count 9
Stand, or hit you with another card? (S or H)h
You get a 5c
House shows Ks  count 10
Player shows 9s 5c  count 14
Stand, or hit you with another card? (S or H)h
You get a 2h
House shows Ks  count 10
Player shows 9s 5c 2h  count 16
Stand, or hit you with another card? (S or H)s
House plays 10d
Game over, final results:
House shows Ks 10d  count 20
Player shows 9s 5c 2h  count 16
House wins with a higher count.
Overall Score:
   Player: 7
   House: 1
   Pushes: 0
Play again (y or Y)? y
The Dealer deals two cards to the house and reveals one: Kh
The Dealer deals you a card: 2d
House shows Kh  count 10
Player shows 2d  count 2
Stand, or hit you with another card? (S or H)h
You get a 6h
House shows Kh  count 10
Player shows 2d 6h  count 8
Stand, or hit you with another card? (S or H)h
You get a 9c
House shows Kh  count 10
Player shows 2d 6h 9c  count 17
Stand, or hit you with another card? (S or H)h
You get a Kd
Player is busted! (over 21)
Game over, final results:
House shows Kh  count 10
Player shows 2d 6h 9c Kd  count 27
Player busted so house wins.
Overall Score:
   Player: 7
   House: 2
   Pushes: 0
Play again (y or Y)? s
The Dealer deals two cards to the house and reveals one: 7d
The Dealer deals you a card: 5h
House shows 7d  count 7
Player shows 5h  count 5
Stand, or hit you with another card? (S or H)y
House shows 7d  count 7
Player shows 5h  count 5
Stand, or hit you with another card? (S or H)h
Out of cards, Unable to deal.
You get a 0c
House shows 7d  count 7
Player shows 5h 0c  count 5
Stand, or hit you with another card? (S or H)


Solution

META FILEATTACHMENT attachment="blackjack-01.jpg" attr="" comment="" date="1477305123" name="blackjack-01.jpg" path="blackjack-01.jpg" size="396040" user="JimSkon" version="1"
META FILEATTACHMENT attachment="CardGameOBJ.png" attr="" comment="" date="1478551161" name="CardGameOBJ.png" path="CardGameOBJ.png" size="38846" user="JimSkon" version="1"
META FILEATTACHMENT attachment="Screen_Shot_2016-11-07_at_3.43.17_PM.png" attr="" comment="" date="1478551602" name="Screen_Shot_2016-11-07_at_3.43.17_PM.png" path="Screen_Shot_2016-11-07_at_3.43.17_PM.png" size="14264" user="JimSkon" version="1"
META FILEATTACHMENT attachment="Screen_Shot_2016-11-07_at_3.44.48_PM.png" attr="" comment="" date="1478551602" name="Screen_Shot_2016-11-07_at_3.44.48_PM.png" path="Screen_Shot_2016-11-07_at_3.44.48_PM.png" size="63108" user="JimSkon" version="1"
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback