In: Computer Science
This project involves writing a program to simulate a blackjack card game. You will use a simple console-based user interface to implement this game. A simple blackjack card game consists of a player and a dealer. A player is provided with a sum of money with which to play. A player can place a bet between $0 and the amount of money the player has. A player is dealt cards, called a hand. Each card in the hand has a point value. The objective of the game is to get as close to 21 points as possible without exceeding 21 points. A player that goes over is out of the game. The dealer deals cards to itself and a player. The dealer must play by slightly different rules than a player, and the dealer does not place bets. A game proceeds as follows: A player is dealt two cards face up. If the point total is exactly 21 the player wins immediately. If the total is not 21, the dealer is dealt two cards, one face up and one face down. A player then determines whether to ask the dealer for another card (called a “hit”) or to “stay” with his/her current hand. A player may ask for several “hits.” When a player decides to “stay” the dealer begins to play. If the dealer has 21 it immediately wins the game. Otherwise, the dealer must take “hits” until the total points in its hand is 17 or over, at which point the dealer must “stay.” If the dealer goes over 21 while taking “hits” the game is over and the player wins. If the dealer’s points total exactly 21, the dealer wins immediately. When the dealer and player have finished playing their hands, the one with the highest point total is the winner. Play is repeated until the player decides to quit or runs out of money to bet. You must use an object-oriented solution for implementing this game.
Each public class must be contained in a separate Java source file. Only one source file will have a main() method and this source will be named BlackjackGameSimulator.java. Other source/class names are up to you following the guidelines specified so far in the course. The format of the Java source must meet the general Java coding style guidelines discussed so far during the course. Pay special attention to naming guidelines, use of appropriate variable names and types, variable scope (public, private, protected, etc.), indentation, and comments. Classes and methods should be commented with JavaDoc-style comments (see below). Please use course office hours or contact the instructor directly if there are any coding style questions. JavaDocs: Sources should be commented using JavaDoc-style comments for classes and methods. Each class should have a short comment on what it represents and use the @author annotation. Methods should have a short (usually 1 short sentence) description of what the results are of calling it. Parameters and returns should be documented with the @param and @return annotations respectively with a short comment on each. JavaDocs must be generated against every project Java source file. They should be generated with a - private option (to document all protection-level classes) and a –d [dir] option to place the resulting files in a javadocs directory/folder at the same level as your source files.
//Card.java
package Blackjack;
class Card {
/*
* Creates a playing card.
*/
private int rank;//represents the rank of a card
private int suit;//represents the suit of a card
private int value;//represents the value of a card
private static String[] ranks = {"Joker","Ace","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Jack","Queen","King"};
private static String[] suits = {"Clubs","Diamonds","Hearts","Spades"};
/*
* Created with an integer that represents a spot in the String array ranks and the String array suits. This represents
* the rank and suit of an individual card.
*/
Card(int suit, int values)
{
this.rank=values;
this.suit=suit;
}
/*
* Returns the string version of a card.
*/
public String toString()
{
return ranks[rank]+" of "+suits[suit];
}
/*
* Returns the rank of a card.
*/
public int getRank()
{
return rank;
}
/*
* Returns the suit of a card.
*/
public int getSuit()
{
return suit;
}
/*
* Returns the value of a card. If a jack, queen, or king the value is ten. Aces are 11 for now.
*/
public int getValue()
{
if(rank>10)
{
value=10;
}
else if(rank==1)
{
value=11;
}
else
{
value=rank;
}
return value;
}
/*
* Sets the value of a card.
*/
public void setValue(int set)
{
value = set;
}
}
//Deck.java
package Blackjack;
import java.util.ArrayList;
import java.util.Random;
/*
* Creates and shuffles a deck of 52 playing cards.
*/
class Deck {
private ArrayList<Card> deck;//represents a deck of cards
Deck()
{
deck = new ArrayList<Card>();
for(int i=0; i<4; i++)
{
for(int j=1; j<=13; j++)
{
deck.add(new Card(i,j));
}
}
}
/*
* Shuffles the deck by changing the indexes of 200 random pairs of cards in the deck.
*/
public void shuffle()
{
Random random = new Random();
Card temp;
for(int i=0; i<200; i++)
{
int index1 = random.nextInt(deck.size()-1);
int index2 = random.nextInt(deck.size()-1);
temp = deck.get(index2);
deck.set(index2, deck.get(index1));
deck.set(index1, temp);
}
}
/*
* Draws a card from the deck.
*/
public Card drawCard()
{
return deck.remove(0);
}
}
//Dealer.java
package Blackjack;
import java.util.ArrayList;
import java.util.Arrays;
/*
* Creates a dealer that the user plays against.
*/
class Dealer {
ArrayList<Card> hand;//represents the dealer's hand
private int handvalue=0;//value of the dealer's hand (starts at 0)
private Card[] aHand;//used to convert the dealer's hand to an array
private int AceCounter;//counts the aces in the dealer's hand
Dealer(Deck deck)
{
hand = new ArrayList<>();
aHand = new Card[]{};
int AceCounter=0;
for(int i=0; i<2; i++)
{
hand.add(deck.drawCard());
}
aHand = hand.toArray(aHand);
for(int i=0; i<aHand.length; i++)
{
handvalue += aHand[i].getValue();
if(aHand[i].getValue()==11)
{
AceCounter++;
}
while(AceCounter>0 && handvalue>21)
{
handvalue-=10;
AceCounter--;
}
}
}
/*
* Prints the dealer's first card (the card face up at the beginning of a blackjack game).
*/
public void showFirstCard()
{
Card[] firstCard = new Card[]{};
firstCard = hand.toArray(firstCard);
System.out.println("["+firstCard[0]+"]");
}
/*
* Gives the dealer another card and updates the value of his hand. Takes into account the value of aces.
*/
public void Hit(Deck deck)
{
hand.add(deck.drawCard());
aHand = hand.toArray(aHand);
handvalue = 0;
for(int i=0; i<aHand.length; i++)
{
handvalue += aHand[i].getValue();
if(aHand[i].getValue()==11)
{
AceCounter++;
}
while(AceCounter>0 && handvalue>21)
{
handvalue-=10;
AceCounter--;
}
}
}
/*
* Determines if the dealer wants to hit according to classic Blackjack rules.
*/
public boolean wantsToHit()
{
if(handvalue<17)
{
return true;
}
return false;
}
/*
* Returns true if the dealer has blackjack.
*/
public boolean hasBlackJack()
{
if(hand.size()==2 && handvalue==21)
{
System.out.println("The dealer has blackjack!");
return true;
}
return false;
}
/*
* Prints the dealer's hand.
*/
public void showHand()
{
System.out.println(hand);
}
/*
* Returns the value of the dealer's hand.
*/
public int getHandValue()
{
return handvalue;
}
/*
* Determines if a dealer has busted.
*/
public boolean busted(int handvalue)
{
if(handvalue>21)
{
System.out.println("The dealer busted!");
return true;
}
return false;
}
/*
* Takes the turn for the dealer and returns the value of his hand.
*/
public int takeTurn(Deck deck)
{
while(wantsToHit())
{
System.out.println("The dealer hits");
Hit(deck);
if(busted(handvalue))
{
break;
}
}
if(handvalue<=21)
{
System.out.print("The dealer stands.");
}
return handvalue;
}
}
//Main.java
package Blackjack;
import java.util.*;
public class Blackjack {
private static int cash;//cash the user bets with
private static int bet;//how much the user wants to bet
private static int AceCounter;//how many aces are in the user's hand
private static ArrayList<Card> hand;//represents the user's hand
private static int handvalue;//the value of the user's hand
private static String name;//name of the user
public static void main(String[] args){
System.out.println("Hi! What is your name?");
Scanner scan = new Scanner(System.in);
name = scan.nextLine();
System.out.println("Hello, "+name+", lets play some BlackJack!");
System.out.println("How much cash do you want to start with?");
Scanner money = new Scanner(System.in);
cash = money.nextInt();
System.out.println("You start with cash: "+cash);
while(cash>0){
Deck deck = new Deck();//initialize deck, dealer, hands, and set the bet.
deck.shuffle();
AceCounter=0;
Dealer dealer = new Dealer(deck);
List<Card> hand = new ArrayList<>();
hand.add(deck.drawCard());
hand.add(deck.drawCard());
System.out.println("How much would you like to bet?");
bet=Bet(cash);
System.out.println("Cash:"+(cash-bet));
System.out.println("Money on the table:"+bet);
System.out.println("Here is your hand: ");
System.out.println(hand);
int handvalue = calcHandValue(hand);
System.out.println("The dealer is showing: ");
dealer.showFirstCard();
if(hasBlackJack(handvalue) && dealer.hasBlackJack())//check if both the user and dealer have blackjack.
{
Push();
}
else if(hasBlackJack(handvalue))//check if the user has blackjack.
{
System.out.println("You have BlackJack!");
System.out.println("You win 2x your money back!");
cash=cash+bet;
Win();
}
else if(dealer.hasBlackJack())//check if the dealer has blackjack.
{
System.out.println("Here is the dealer's hand:");
dealer.showHand();
Lose();
}
else
{
if(2*bet<cash)//check if the user can double down.
{
System.out.println("Would you like to double down?");//allows the user to double down.
Scanner doubledown = new Scanner(System.in);
String doubled = doubledown.nextLine();
while(!isyesorno(doubled))
{
System.out.println("Please enter yes or no.");
doubled = doubledown.nextLine();
}
if(doubled.equals("yes"))
{
System.out.println("You have opted to double down!");
bet=2*bet;
System.out.println("Cash:"+(cash-bet));
System.out.println("Money on the table:"+bet);
}
}
System.out.println("Would you like to hit or stand?");//ask if the user will hit or stand
Scanner hitorstand = new Scanner(System.in);
String hitter = hitorstand.nextLine();
while(!isHitorStand(hitter))
{
System.out.println("Please enter 'hit' or 'stand'.");
hitter = hitorstand.nextLine();
}
while(hitter.equals("hit"))//hits the user as many times as he or she pleases.
{
Hit(deck, hand);
System.out.println("Your hand is now:");
System.out.println(hand);
handvalue = calcHandValue(hand);
if(checkBust(handvalue))//checks if the user busted
{
Lose();
break;
}
if(handvalue<=21 && hand.size()==5)//checks for a five card trick.
{
fivecardtrick();
break;
}
System.out.println("Would you like to hit or stand?");
hitter = hitorstand.nextLine();
}
if(hitter.equals("stand"))//lets the user stand.
{
int dealerhand = dealer.takeTurn(deck);//takes the turn for the dealer.
System.out.println("");
System.out.println("Here is the dealer's hand:");
dealer.showHand();
if(dealerhand>21)//if the dealer busted, user wins.
{
Win();
}
else
{
int you = 21-handvalue;//check who is closer to 21 and determine winner
int deal = 21-dealerhand;
if(you==deal)
{
Push();
}
if(you<deal)
{
Win();
}
if(deal<you)
{
Lose();
}
}
}
}
System.out.println("Would you like to play again?");//ask if the user wants to keep going
Scanner yesorno = new Scanner(System.in);
String answer = yesorno.nextLine();
while(!isyesorno(answer))
{
System.out.println("Please answer yes or no.");
answer = yesorno.nextLine();
}
if(answer.equals("no"))
{
break;
}
}
System.out.println("Your cash is: "+cash);//if user doesn't want to play or runs out of cash, either congratulates them on their winnings or lets them know
if(cash==0)
{
System.out.println("You ran out of cash!");
}
else
{
System.out.println("Enjoy your winnings, "+name+"!");
}
}
/*
* Checks if the user has blackjack.
*/
public static boolean hasBlackJack(int handValue)
{
if(handValue==21)
{
return true;
}
return false;
}
/*
* Calculates the value of a player's hand.
*/
public static int calcHandValue(List<Card> hand)
{
Card[] aHand = new Card[]{};
aHand = hand.toArray(aHand);
int handvalue=0;
for(int i=0; i<aHand.length; i++)
{
handvalue += aHand[i].getValue();
if(aHand[i].getValue()==11)
{
AceCounter++;
}
while(AceCounter>0 && handvalue>21)
{
handvalue-=10;
AceCounter--;
}
}
return handvalue;
}
/*
* Asks the user how much he or she would like to bet.
*/
public static int Bet(int cash)
{
Scanner sc=new Scanner(System.in);
int bet=sc.nextInt();
while(bet>cash)
{
System.out.println("You cannot bet more cash than you have!");
System.out.println("How much would you like to bet?");
bet=sc.nextInt();
}
return bet;
}
/*
* Called if the user wins.
*/
public static void Win()
{
System.out.println("Congratulations, you win!");
cash=cash+bet;
System.out.println("Cash: "+cash);
}
/*
* Called if the user loses.
*/
public static void Lose()
{
System.out.println("Sorry, you lose!");
cash=cash-bet;
System.out.println("Cash: "+cash);
}
/*
* Called if the user pushes
*/
public static void Push()
{
System.out.println("It's a push!");
System.out.println("You get your money back.");
System.out.println("Cash: "+cash);
}
/*
* Adds a card to user's hand and calculates the value of that hand. Aces are taken into account.
*/
public static void Hit(Deck deck, List<Card> hand)
{
hand.add(deck.drawCard());
Card[] aHand = new Card[]{};
aHand = hand.toArray(aHand);
handvalue = 0;
for(int i=0; i<aHand.length; i++)
{
handvalue += aHand[i].getValue();
if(aHand[i].getValue()==11)
{
AceCounter++;
}
while(AceCounter>0 && handvalue>21)
{
handvalue-=10;
AceCounter--;
}
}
}
/*
* Determines if a user has input hit or stand.
*/
public static boolean isHitorStand(String hitter)
{
if(hitter.equals("hit") || hitter.equals("stand"))
{
return true;
}
return false;
}
/*
* Determines if a user has busted.
*/
public static boolean checkBust(int handvalue)
{
if(handvalue>21)
{
System.out.println("You have busted!");
return true;
}
return false;
}
/*
* Determines if a user has input yes or no.
*/
public static boolean isyesorno(String answer)
{
if(answer.equals("yes") || answer.equals("no"))
{
return true;
}
return false;
}
/*
* Called if the user has a five card trick.
*/
public static void fivecardtrick()
{
System.out.println("You have achieved a five card trick!");
Win();
}
}
Screenshots: