BlackJack Game

Modules - Procedural Programming 1, Data Structures 1, Object Oriented Programming 1

 

Teacher’s Notes:

=======================================

This is a VERY detailed assignment that is meant to be done in groups.  The purpose of the assignment is for the groups to divide the tasks amongst themselves to demonstrate how using methods in programming facilitates group programming.

 

 

There is a line of code that I use:

dealNextCard(deck, cardsDealt++, playerHand);

that may seem a little weird. The cardsDealt++ can be done in line because the ++ operation happens at the end of the order of operations and thus, executes after the method call.  You may want to adjust it to be on two lines like this:

dealNextCard(deck, cardsDealt, playerHand);

cardsDealt++;

if you think it would confuse your students.

 
 
 
This might be a good time to show your students about the Kanban system and tracking the burndown velocity to see how fast the project is taking.  You can watch a video explaining these concepts here:
 
https://www.youtube.com/watch?v=Bcid33tgq8A
 
When you set up a Kanban board, you can assign an estimated amount of time it should take for each task.  Thus, you know the estimated time for the whole project.  When each task is complete (or even in progress), you update the amount of time remaining on the project to see how fast it is being completed.  Using this method, you can track the estimated completion time to see if the project will be finished early, on time, or late.
 
 
 
This project is probably different from most things you have done in your class.  It is a very different challenge to look at someone else's code and make it work.  There are many ways to solve each method.
 

Assignment:

=======================================

BlackJack Game

In this project, we are going to take an incomplete skeleton of a BlackJack game and complete the game. In the game of BlackJack, there is a player and a dealer.  The player is given one card from the deck, then the dealer is given a card face down.  The player is then given another card and the dealer is also given another card but face up.  After dealing, it is the player's turn.

The goal of the game is get as close to a hand total of 21 without going over.  The hand totals are calculated as follows: Aces are worth 11 points or 1 point.  For the purpose of this game, they are always counted as 11 points unless the hand value goes over 21 in which case they count as 1 point.  Any Jack, Queen or King counts as 10 points.  All other cards have the same number of points as their card number.

Example:

A 2 K

has a hand value of 13 since counting the A as 11 would put the player over 21.

Example:

A A 9

has a hand value of 21 since only one ace needs to be counted as a 1 in order for the hand value to be below 21.

 

During the player's turn, the player can choose to Hit or Stay.  If they Hit, they get another card.  If they Stay, they end their turn. 

If the player's hand value goes over 21, they have Busted and lose the game immediately.  If they have 5 cards in their hand and have not Busted, they automatically win the game. 

 

Once the player completes their turn (and has not Busted or won), then it is the dealer's turn.  The dealer is controlled by the computer and according to the rules, must always hit if they have a hand value less than 17.  If they have a hand value of 17 or more, then they must stay.  If the dealer busts, the player immediately wins.

 

If both players end their turns without busting or winning (by having 5 cards for the player), then the winner is determined as being the player with the highest value hand.  A tie is possible and is called a Push.

 

To complete this game, we are going to start with the following Card class:

public class Card {
    
    int number;
    char suit;
}
 
We will create a deck of these cards by creating a size 52 array of Card objects.  Your team's job is to complete the code and make a properly functioning game.  You can find the skeleton at:
 
 
 

 

Solution (JAVA Card Class):

=======================================

package code;
public class Card {
    
    int number;
    char suit;
}

 

Solution (JAVA BlackJack Class):

=======================================

package code;
import java.util.Scanner;
 
public class BlackJack {
    public static void populate(Card[] deck) {
        
        char[] suit = {'\u2666','\u2663','\u2665','\u2660'};
        
        for(int x = 0; x < 52; x++)
        {
            deck[x].number = x % 13 + 1;
            deck[x].suit = suit[x/13];
        }
    }
    
    public static void shuffle(Card[] deck) {
        for(int x = 0; x < 52; x++) {
            int randomIndex = (int)(Math.random()*52);
            Card temp = deck[x];
            deck[x] = deck[randomIndex];
            deck[randomIndex] = temp;
        }
    }
    
    public static int numberOfCardsInHand(Card[] hand) {
        int numberOfCardsInHand = 0;
        
        for(int x = 0; x < 5; x++) {
            if(hand[x].number != 0)
                numberOfCardsInHand++;
        }
        return numberOfCardsInHand;
    }
    
    public static void drawHand(Card[] hand) {
        int numberOfCardsInHand = numberOfCardsInHand(hand);
        for(int x = 0; x < numberOfCardsInHand; x++) {
            System.out.print("\u250f");
            System.out.print("\u2501"+"\u2501"+"\u2501"+"\u2501");
            System.out.print("\u2513");
        }
        
        System.out.println();
        for(int x = 0; x < numberOfCardsInHand; x++) {
            System.out.print("\u2503");
            if(hand[x].number == 1)
                System.out.print("A" + hand[x].suit + "  ");
            else if(hand[x].number == 10)
                System.out.print("10" + hand[x].suit + " ");
            else if(hand[x].number == 11)
                System.out.print("J" + hand[x].suit + "  ");
            else if(hand[x].number == 12)
                System.out.print("Q" + hand[x].suit + "  ");
            else if(hand[x].number == 13)
                System.out.print("K" + hand[x].suit + "  ");
            else
                System.out.print(hand[x].number + "" + hand[x].suit + "  ");
            
            System.out.print("\u2503");
        }
            
            
        
        System.out.println();
        for(int x = 0; x < numberOfCardsInHand; x++) 
            System.out.print("\u2503"+"    " + "\u2503");
        System.out.println();
        for(int x = 0; x < numberOfCardsInHand; x++) 
            System.out.print("\u2503"+"    " + "\u2503");
        
        System.out.println();
        for(int x = 0; x < numberOfCardsInHand; x++) {
            System.out.print("\u2517");
            System.out.print("\u2501"+"\u2501"+"\u2501"+"\u2501");
            System.out.print("\u251b");
        }
        System.out.println();
    }
    
    public static void drawHandWithHiddenFirstCard(Card[] hand) {
        int numberOfCardsInHand = 0;
        
        for(int x = 0; x < 5; x++) {
            if(hand[x].number != 0)
                numberOfCardsInHand++;
        }
        
        for(int x = 0; x < numberOfCardsInHand; x++) {
            System.out.print("\u250f");
            System.out.print("\u2501"+"\u2501"+"\u2501"+"\u2501");
            System.out.print("\u2513");
        }
        
        System.out.println();
        for(int x = 0; x < numberOfCardsInHand; x++) {
            if(x == 0)
                System.out.print("\u2503"+ "####" + "\u2503");
            else {
                System.out.print("\u2503");
                if(hand[x].number == 1)
                    System.out.print("A" + hand[x].suit + "  ");
                else if(hand[x].number == 10)
                    System.out.print("10" + hand[x].suit + " ");
                else if(hand[x].number == 11)
                    System.out.print("J" + hand[x].suit + "  ");
                else if(hand[x].number == 12)
                    System.out.print("Q" + hand[x].suit + "  ");
                else if(hand[x].number == 13)
                    System.out.print("K" + hand[x].suit + "  ");
                else
                    System.out.print(hand[x].number + "" + hand[x].suit + "  ");
                System.out.print("\u2503");
            }
                
        }
            
        System.out.println();
        for(int x = 0; x < numberOfCardsInHand; x++) 
            if(x == 0)
                System.out.print("\u2503"+ "####" + "\u2503");
            else
                System.out.print("\u2503"+"    " + "\u2503");
        System.out.println();
        for(int x = 0; x < numberOfCardsInHand; x++) 
            if(x == 0)
                System.out.print("\u2503"+ "####" + "\u2503");
            else
                System.out.print("\u2503"+"    " + "\u2503");
        
        System.out.println();
        for(int x = 0; x < numberOfCardsInHand; x++) {
            System.out.print("\u2517");
            System.out.print("\u2501"+"\u2501"+"\u2501"+"\u2501");
            System.out.print("\u251b");
        }
        System.out.println();
    }
    
    public static void dealNextCard(Card[] deck, int nextCardInDeck, Card[] hand) {
        int firstEmptySlot = 0;
        for(int x = 0; x < 5; x++)
            if(hand[x].number == 0) {
                firstEmptySlot = x;
                break;
            }
        
        hand[firstEmptySlot].number = deck[nextCardInDeck].number;
        hand[firstEmptySlot].suit = deck[nextCardInDeck].suit;
        
    }
    
    public static void resetHand(Card[] deck) {
        for(int x = 0; x < 5; x++) {
            deck[x].number = 0;
            deck[x].suit = ' ';
        }
    }
    
    public static int errorTrap(int min, int max) {
        if(min > max) {
            int temp = min;
            min = max;
            max = temp;
        }
        
        int number = -1;
        Scanner input = new Scanner(System.in);
        do {
            try {
                number = input.nextInt();
            }
            catch (Exception e) {
                input.next();
            }
        }while(number < min || number > max);
        return number;
    }
    
    public static int valueOfHand(Card[] hand) {
        int sum = 0;
        int numberOfAces = 0;
        
        for(int x = 0; x < 5; x++) {
            if(hand[x].number == 1) {
                sum += 11;
                numberOfAces++;
            }
            else if(hand[x].number >= 10)
                sum += 10;
            else
                sum += hand[x].number;    
        }
        
        while(sum > 21 && numberOfAces > 0) {
            numberOfAces--;
            sum -= 10;
        }
        
        return sum;
    }
    
    public static void showHandsRevealed(Card[] playerHand, Card[] dealerHand) {
        System.out.println("\n\n\n\n");
        System.out.println("Player's Hand:");
        drawHand(playerHand);
        System.out.println("Dealer's Hand:");
        drawHand(dealerHand);
    }
    
    public static void showHandsHidden(Card[] playerHand, Card[] dealerHand) {
        System.out.println("\n\n\n\n");
        System.out.println("Player's Hand:");
        drawHand(playerHand);
        System.out.println("Dealer's Hand:");
        drawHandWithHiddenFirstCard(dealerHand);
    }
    
    public static void main(String[] args) {
        /*
        in order to set Eclipse to work with Unicode
        Project -> Properties -> Resource -> TextFileEncoding -> Set it to UTF-8
        
        Unicode characters you will need:
        System.out.println("\u2660 Spades");
        System.out.println("\u2665 Hearts");
        System.out.println("\u2666 Diamonds");
        System.out.println("\u2663 Clubs");
        System.out.println("\u250f Top Left Card Corner");
        System.out.println("\u2513 Top Right Card Corner");
        System.out.println("\u2501 Horizontal Card Edge");
        System.out.println("\u2503 Vertical Card Edge");
        System.out.println("\u2517 Bottom Left Card Corner");
        System.out.println("\u251b Bottom Right Card Corner");
        */
        
        int cardsDealt = 0, choice = 0, money = 100, playAgain = 0;
        Card[] deck = new Card[52];
        for(int x = 0; x < 52; x++)
            deck[x] = new Card();
        
        Card[] playerHand = new Card[5];
        for(int x = 0; x < 5; x++)
            playerHand[x] = new Card();
        
        Card[] dealerHand = new Card[5];
        for(int x = 0; x < 5; x++)
            dealerHand[x] = new Card();
        
        do {
            populate(deck);
            shuffle(deck);
            resetHand(playerHand);
            resetHand(dealerHand);
            cardsDealt = 0;
            choice = 0;
            
            //Test Code
            /*
            for(int x = 0; x < 52; x++) {
                System.out.print(deck[x].number + "" + deck[x].suit + " ");
            }
            System.out.println();
            */
            
            
            dealNextCard(deck, cardsDealt++, playerHand);
            dealNextCard(deck, cardsDealt++, dealerHand);
            dealNextCard(deck, cardsDealt++, playerHand);
            dealNextCard(deck, cardsDealt++, dealerHand);
            
            while(numberOfCardsInHand(playerHand) < 5 && choice != 2 && valueOfHand(playerHand) < 22) {
                
                showHandsHidden(playerHand, dealerHand);
                System.out.println("Cash: $ " + money);
                System.out.println("Player's Hand Value: " + valueOfHand(playerHand));
                
                System.out.println("Player's Turn: ");
                System.out.println("1. Hit");
                System.out.println("2. Stand");
                System.out.print("What would you like to do?");
                choice = errorTrap(1,2);
            
                if(choice == 1)
                    dealNextCard(deck, cardsDealt++, playerHand);
            }
            
            if(valueOfHand(playerHand) > 21) {
                showHandsHidden(playerHand, dealerHand);
                System.out.println("Cash: $ " + money);
                System.out.println("Player's Hand Value: " + valueOfHand(playerHand));
                System.out.println("You have busted! You lose.");
                money -= 5;
            }
            else if(numberOfCardsInHand(playerHand) == 5)
            {
                showHandsHidden(playerHand, dealerHand);
                System.out.println("Cash: $ " + money);
                System.out.println("Player's Hand Value: " + valueOfHand(playerHand));
                System.out.println("You Win!");
                money += 5;
            }
            else {
                showHandsRevealed(playerHand, dealerHand);
                System.out.println("Cash: $ " + money);
                System.out.println("Player's Hand Value: " + valueOfHand(playerHand));
                System.out.println("Dealer's Hand Value: " + valueOfHand(dealerHand));
                System.out.println("Dealer's Turn: ");
                while(valueOfHand(dealerHand) < 17)
                {
                    System.out.println("Dealer must draw a card...");
                    System.out.println("Enter any key to continue...");
                    new Scanner(System.in).next();
                    dealNextCard(deck, cardsDealt++, dealerHand);
                    showHandsRevealed(playerHand, dealerHand);
                    System.out.println("Cash: $ " + money);
                    System.out.println("Player's Hand Value: " + valueOfHand(playerHand));
                    System.out.println("Dealer's Hand Value: " + valueOfHand(dealerHand));
                    System.out.println("Dealer's Turn: ");
                    
                }
                if(valueOfHand(dealerHand) > 21) {
                    System.out.println("The dealer busted! You win!");
                    money += 5;
                }
                else{
                    System.out.println("Dealer Stands.");
                    
                    System.out.println("\n");
                    if(valueOfHand(dealerHand) > valueOfHand(playerHand)) {
                        System.out.println("You lose.");
                        money -= 5;
                    }
                    else if(valueOfHand(dealerHand) < valueOfHand(playerHand)) {
                        System.out.println("You win.");
                        money += 5;
                    }
                    else
                        System.out.println("It's a push.");
                    
                }
                
                
            }
            
            System.out.println("Would you like to play again (1. Yes, 2. No):");
            playAgain = errorTrap(1,2);
        }while(money > 0 && playAgain == 1);
        
        
    }
}