Tags:
create new tag
view all tags

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

// 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
};

enum cSuit {
    CLUBS, DIAMONDS, HEARTS, SPADES
};

class Card {
public:
    // Card Constructors
    Card();
    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:
    cRank rank;
    cSuit suit;
};

#endif /* CARD_H */

Card.cpp

// Implementation of Card class
#include <iostream>
#include <string>
#include <vector>
#include "Card.h"

//Constructor

Card::Card() {
    rank = ACE;
    suit = CLUBS;
}

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"};
    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
    int value = rank;
    //value is 10 for face cards
    if (value > 10) {
        value = 10;
    }
    return value;
}

Hand.h

// A class for a Hand of playing cards
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();
    
    // return true if plyyer has exactly 21
    bool Wins();

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

private:
    vector <Card> cards;
};

#endif /* HAND_H */

Hand.cpp

// Implementation of Hand class
#include <iostream>
#include <string>
#include <vector>
#include "Card.h"
#include "Hand.h"

Hand::Hand() {
    cards.reserve(7);
}

void Hand::Add(Card& card) {
    // add a card to hand
    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
    cards.clear();
}

string Hand::GetCardList() {
    string list = "";
    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;
}

Deck.h

// A class for a deck of playing card

using namespace std;

const int DECKSIZE = 52;

#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();

    // create a string list of all the cards in this deck.
    string GetCardList();

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

#endif /* DECK_H */

Deck.cpp

// Implementation of Deck class
#include <iostream>
#include <string>
#include <vector>
#include "Card.h"
#include "Deck.h"

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

double nextRandom() {
    double random = ((double) rand()) / RAND_MAX;
    return random;
}

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

void Deck::Clear() {
    //clear vector
    Cards.clear();
}

void Deck::Populate() {
    Clear(); // clear out the deck before you create a new one

    //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) {
            Cards.push_back(Card(static_cast<cRank> (r), static_cast<cSuit> (s)));
        }
    }
}

void Deck::Shuffle() {
    // This needs to randomize the cards in the deck
    // you will need to use the random function to do this
}

Card Deck::Deal() {
    // 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);
    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 = "";
    for (int i = 0; i < Cards.size(); i++) {
        list += Cards[i].CardName() + " ";
    }
    return list;

}

main Blackjack.cpp

#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;
}

Sample Run

              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

Topic attachments
I Attachment History Action Size Date Who Comment
PNGpng CardGameOBJ.png r1 manage 37.9 K 2016-11-07 - 20:39 JimSkon  
PNGpng Screen_Shot_2016-11-07_at_3.43.17_PM.png r1 manage 13.9 K 2016-11-07 - 20:46 JimSkon  
PNGpng Screen_Shot_2016-11-07_at_3.44.48_PM.png r1 manage 61.6 K 2016-11-07 - 20:46 JimSkon  
JPEGjpg blackjack-01.jpg r1 manage 386.8 K 2016-10-24 - 10:32 JimSkon  
Edit | Attach | Watch | Print version | History: r25 < r24 < r23 < r22 < r21 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r25 - 2018-04-03 - JimSkon
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2018 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback