You are on page 1of 8

/* Blackjack Game written by Keith Fenske Sunday, 2 June 2002 Copyright (c) 2002 by Keith Fenske.

All rights reserved. This Java program plays the "Blackjack" ("Twenty-One") card game. This program would be a good place to use an object for the deck of cards. However, we haven't done objects yet in CS 1083, so instead, the deck of cards will be represented by static class variables. The cards are numbers from 0 to 51, stored in an integer array (which is also indexed from 0 to 51). The order of the array is shuffled by pseudo-random permutation. The card numbers are as follows: ace 2 3 . 9 10 jack queen king */ import cs1.Keyboard; // // import Lewis/Loftus keyboard class http://duke.csc.villanova.edu/jss/keyboard.html clubs 0 1 2 . 8 9 10 11 12 diamonds 13 14 15 .. 21 22 23 24 25 hearts 26 27 28 .. 34 35 36 37 38 spades 39 40 41 .. 47 48 49 50 51

public class Blackjack { static final int BESTHAND = 21; // we want to add up to this number static final int BLACKJACK = 101; // special value for black jack + ace // (must be a large positive number) static final int DECKSIZE = 52; // number of cards in the deck static final int FIVECARDS = 102; // special value for five cards <= 21 // (must be a large positive number) static final int HANDSIZE = 5; // maximum number of cards in a hand static final int ACE = 1; static final int JACK = 11; static static static static static static static static final final final final int int int int CLUBS = 0; DIAMONDS = 1; HEARTS = 2; SPADES = 3; // numeric code for an ace // numeric code for a jack // // // // // // // // numeric numeric numeric numeric code code code code for for for for clubs diamonds hearts spades

int cardsUsed; int compWins; int userWins; int[] deck;

how many cards used in this deck number of winning games for computer number of winning games for user array to hold card numbers

public static void main(String[] args) { boolean again; // true if we play another game compWins = 0; userWins = 0; // no wins for computer yet // no wins for user yet

System.out.println("\nWelcome to Blackjack for CS 1083.\n"); do { playGame(); // play one game System.out.println("\nYou have won " + userWins + " games and I have won " + compWins + " games."); again = yesNo("Do you want to play another game? (YES or NO)"); } while (again); System.out.println("\nThank you for playing Blackjack with me!"); } // // // // /* getCardName() method Given a card number, return a string with the full name of the card: "2 of diamonds", "ace of spades", etc. */ static String getCardName(int card) { String result; // result from this function result = getFaceName(card) + " of " + getSuitName(card); return result; } /* getFaceName() method Given a card number, return a string with the face name of the card: "ace", "2", "10", "queen", etc. */ static String getFaceName(int card) { String[] names = {"ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "jack", "queen", "king"}; String result; // result from this function result = names[getFaceNumber(card) - 1]; return result; } /* getFaceNumber() method Given a card number, return an integer from 1 to 13 to represent the number of the card: 1 = ace, 2 = two, ..., 10 = ten, 11 = jack, 12 = queen, 13 = king. Note that these numbers start at one, not at zero. */ static int getFaceNumber(int card) { int result; // result from this function if ((card < 0) { (card >= DECKSIZE)) ------------------------------------------------------------------------For Java applications, put the main() method first, then put the other methods in alphabetical order. -------------------------------------------------------------------------

System.out.println("error in getFaceNumber() method: card = " + card); card = 0; // reset is better than crashing } result = 1 + (card % 13); return result; } /* getNextCard() method Return an integer 0 <= n < DECKSIZE to represent the next card in the deck. */ static int getNextCard() { int result; // result from this function // 13 cards per suit

if (cardsUsed >= DECKSIZE) { System.out.println("error in getNextCard() method: cardsUsed = " + cardsUsed + " >= DECKSIZE = " + DECKSIZE); cardsUsed = 0; // reset is better than crashing } result = deck[cardsUsed]; // return this card to caller cardsUsed ++; // one more card has been used return result; } /* getSuitName() method Given a card number, return a string with the name of the card's suit. */ static String getSuitName(int card) { String[] names = {"clubs", "diamonds", "hearts", "spades"}; String result; // result from this function result = names[getSuitNumber(card)]; return result; } /* getSuitNumber() method Given a card number, return an integer from 0 to 3 to represent the suit number. */ static int getSuitNumber(int card) { int result; // result from this function if ((card < 0) (card >= DECKSIZE)) { System.out.println("error in getSuitNumber() method: card = " + card); card = 0; // reset is better than crashing } result = card / 13; // 13 cards per suit return result; }

/* playGame() method Play one game of Blackjack. There is no betting in this version of the game. We do keep track of how many games the computer or user wins. */ static void playGame() { boolean again; int compCount; int compValue; int i; int userCount; int userValue; int[] compCards; int[] userCards; // // // // // // // // true if we repeat while loop number of computer's cards value of computer's cards index variable in for loop number of user's cards value of user's cards cards for the computer cards for the user (person)

// Start the game with two cards each. There are at most five cards // in each hand. shuffle(); // shuffle the deck of cards compCards = new int[HANDSIZE]; compCards[0] = getNextCard(); compCards[1] = getNextCard(); compCount = 2; userCards = new int[HANDSIZE]; userCards[0] = getNextCard(); userCards[1] = getNextCard(); userCount = 2; System.out.println("\nI have the " + getCardName(compCards[0]) + " plus one hidden card."); do { System.out.print("You have the " + getCardName(userCards[0])); for (i = 1; i < userCount; i ++) System.out.print(", " + getCardName(userCards[i])); System.out.println("."); userValue = value(userCards, userCount); if ((userValue < BESTHAND) && (userCount < HANDSIZE)) { System.out.println("The current value of your hand is " + userValue + "."); if (yesNo("Do you want another card? (YES or NO)")) { userCards[userCount] = getNextCard(); userCount ++; // one more card in user's hand again = true; // loop again to check new hand } else again = false; // user doesn't want another card } else again = false; // user's hand is already finished } while (again); // Check if the user has already won or lost this game.

if (userValue == BLACKJACK) { System.out.println("You have a black jack and an ace. You automatically w in!"); userWins ++; // user wins this game } else if ((userValue > BESTHAND) && (userValue != FIVECARDS)) { System.out.println("Sorry, your cards add up to " + userValue + " so you lose this game."); compWins ++; // computer wins this game } else { // The computer takes cards until the total is 16 or more. do { System.out.print("I have the " + getCardName(compCards[0])); for (i = 1; i < compCount; i ++) System.out.print(", " + getCardName(compCards[i])); System.out.println("."); compValue = value(compCards, compCount); if ((compValue < 16) && (compCount < HANDSIZE)) { System.out.println("My hand is worth " + compValue + ". I will take another card."); compCards[compCount] = getNextCard(); compCount ++; // one more card in computer's hand again = true; // loop again to check new hand } else again = false; // computer's hand is already finished } while (again); // Sort out who finally wins. if (compValue == BLACKJACK) { System.out.println("I have a black jack and an ace ... so I win."); compWins ++; // computer wins this game } else if ((compValue > BESTHAND) && (compValue != FIVECARDS)) { System.out.println("Oops! Too many cards! My cards add up to " + compValue + " so I lose this game."); userWins ++; // user wins this game } else if (userValue == FIVECARDS) { System.out.println("You have " + HANDSIZE + " cards under 21, so you win."); userWins ++; // user wins this game } else if (compValue == FIVECARDS) { System.out.println("I have " + HANDSIZE + " cards under 21, so I win."); compWins ++; // computer wins this game

} else if (compValue <= userValue) { System.out.println("You win because your hand is worth " + userValue + " and my hand is worth only " + compValue + "."); userWins ++; // user wins this game } else { System.out.println("I win because my hand is worth " + compValue + " but your hand is worth only " + userValue + "."); compWins ++; // computer wins this game } } } // end of playGame() method /* shuffle() method Take the current deck of cards and shuffle them using a pseudo-random permutation of some prime numbers less than 52. We can't use 2 or 13, because they are not relatively prime to 52 (the deck size). Just for fun, the number of prime numbers in our random list is also a prime number! */ static void shuffle() { int i; int inc; int pos; int[] newdeck; int[] primes = {3, 5, 7, 11, // // // // 17, index variable in for loop random prime increment random starting position our new deck of cards 19, 23, 29, 31, 37, 41, 43, 47};

// If this is the first game, then start a fresh deck of cards. if (deck == null) { deck = new int[DECKSIZE]; for (i = 0; i < DECKSIZE; i ++) deck[i] = i; } // Take current deck of cards and change the order (i.e., shuffle). System.out.println("Shuffling the deck of cards ..."); pos = (int) (Math.random() * DECKSIZE); inc = primes[(int) (Math.random() * primes.length)]; newdeck = new int[DECKSIZE]; for (i = 0; i < DECKSIZE; i ++) { newdeck[i] = deck[pos]; // copy card at this position pos = (pos + inc) % DECKSIZE; // next pseudo-random position } deck = newdeck; // replace old deck with new deck cardsUsed = 0; // no cards used yet in this deck } // end of shuffle() method /* value() method

There are two parameters to this method. The first is an array of card numbers. The second is the number of elements in the array that are being used, starting from the first element (index zero). The result is the total points for the hand. If the hand is good, then the result is a number from 1 to 21, or a special number for: (1) a black jack plus an ace, or (2) five cards less than or equal to 21. In some versions of Blackjack, when two players have the same number of points, then the person with the greater number of cards wins. In this game, there is only the user and the computer, and the user always wins a tie, so there is no need to compare the number of cards. */ static int value(int[] cards, int count) { int aces; // number of aces found int face; // card number (1 to 13) int i; // index variable in for loop int result; // result from this function aces = 0; result = 0; // no aces found yet // start with no result

// Check for the best case of all: exactly two cards, where one card is // a black jack and the other card is an ace. if (count == 2) { if (((getFaceNumber(cards[0]) == ACE) && (getFaceNumber(cards[1]) == JACK) && ((getSuitNumber(cards[1]) == CLUBS) (getSuitNumber(cards[1]) == SPADES))) ((getFaceNumber(cards[1]) == ACE) && (getFaceNumber(cards[0]) == JACK) && ((getSuitNumber(cards[0]) == CLUBS) (getSuitNumber(cards[0]) == SPADES)))) { result = BLACKJACK; // very good news! } } // If there was no "blackjack", then compute the total points. if (result == 0) { for (i = 0; i < count; i ++) { face = getFaceNumber(cards[i]); if (face == ACE) { aces ++; // aces need special processing later result ++; // add one to total for now } else if (face > 10) // jack, queen, or king result = result + 10; else result = result + face; // 2 to 10

} // Aces can be 1 or 11. if ((aces > 0) && (result <= (BESTHAND - 10))) result = result + 10; // Having five cards under 21 is very good. if ((result <= BESTHAND) && (count >= HANDSIZE)) result = FIVECARDS; // good news } return result; } // end of value() method /* yesNo() method Ask the user a yes-or-no question and keep asking until a valid answer is received. Return true for "yes" and false for "no". */ static boolean yesNo(String question) { boolean asking; // true while we are asking boolean result; // result from this function String answer; // input from user asking = true; // we are looking for an answer result = false; // default value to keep compiler happy while (asking) { System.out.println(question); answer = Keyboard.readString(); if (answer.equalsIgnoreCase("yes") answer.equalsIgnoreCase("y")) { asking = false; // stop asking result = true; // answer is yes } else if (answer.equalsIgnoreCase("no") answer.equalsIgnoreCase("n")) { asking = false; // stop asking result = false; // answer is no } else System.out.println("Please answer YES or NO."); } return result; } // end of yesNo() method } // end of class

You might also like