In this exercise, you will create a simple console version of Blackjack using Java. You will practice fundamental Java concepts including object oriented design, inheritance, basic algorithm design, ArrayLists, and more. Rather than going through code individually class by class, I’ll be explaining the processes behind how I would logically develop certain parts of the program. We will be jumping between different files and adding methods as we need them. Starting from the ground up with creating the cards, then the deck, then the game logic, and so on.
I have a new version of this same project, but with a graphical user interface. It’s based off this console version. I’d encourage you to try building the console version, then check out the GUI version.
This will be a very basic version with only hit and stand functionality. Note that there are many variations of blackjack. Ours will follow simple rules.
The rules of the game will be:
- It will be played with a single, standard Deck of 52 cards, though you could easily change it to accommodate larger deck sizes.
- Players start with two cards and have an option to hit (draw another card) or stand (end their turn).
- Number cards are valued at their number, Face cards (Jack Queen and King) are valued at 10, and aces are valued at 1 or 11 depending on the situation.
- If the value of the hand with an ace puts it over 21, the ace is valued at 1. If it’s doesn’t, it’s 11. So, for example, a King and an ace would be 21, but one King, a 9, and an Ace would be valued at 20 (10+9+1=20).
- If the Player starts with 21, they automatically get BlackJack and win. If the dealer starts with 21, the player loses automatically, before they even get a chance to hit or stand. If they both get 21 in the end, it’s a push (a draw or tie).
- The player may stand (stop drawing) at any time. If they go over 21 they bust and lose. When the player stands, it’s the end of their turn, and the dealer begins drawing their third, fourth, fifth card, and so on.
- The dealer will keep drawing cards until they reach a hand valued at 17 or higher.
- Example: The dealer draws a 3 and a 7 to start, for a value of 10, then they draw a King. The total value of their hand is now 20, so they stand. If they started with a value of 10, and then drew a 3, they would keep drawing more cards until they get to 17 or higher.
- If neither player nor dealer busts or gets BlackJack, the player with the highest score wins the round.
- If we run out of cards, we shuffle the deck and start over.
This project touches on: Object Oriented Design, ArrayLists, Collections, Algorithms, and ENUMs.
Sample Output
This is what the program looks like when you run it. In this example round, it looks like I have won.
Welcome to BlackJack.
The dealer's hand looks like this:
[Ace of Spades] (11)
The second card is face down.
Your hand looks like this:
[Two of Hearts] (2) - [Ten of Clubs] (10) - Your Value: 12
Would you like to: 1) Hit or 2) Stand
1
The dealer gives you a card from the deck.
Your hand looks like this:
[Two of Hearts] (2) - [Ten of Clubs] (10) - [Nine of Clubs] (9) - Your Value: 21
Dealer hand looks like this:
[Ace of Spades] (11) - [Ace of Hearts] (11) - Dealer Value: 12
Dealer draws a card.
Dealer hand looks like this:
[Ace of Spades] (11) - [Ace of Hearts] (11) - [Jack of Diamonds] (10) - Dealer Value: 12
Dealer draws a card.
Dealer hand looks like this:
[Ace of Spades] (11) - [Ace of Hearts] (11) - [Jack of Diamonds] (10) - [Five of Spades] (5) - Dealer Value: 17
You have won.
This round is over.
Starting Next Round... Wins: 1 Losses: 0 Pushes: 0
The dealer's hand looks like this...
Come Up With a Game Plan
Planning is an essential part of the development process! Before you even open your IDE and start writing code, come up with a game plan. Since Java’s object-oriented, I usually start by thinking about what kinds of objects I’ll need to create. Since we’re modeling a game of blackjack, what objects do we need for a game?
Well, a game of blackjack in real life needs a player, a dealer, a deck of cards, a set of rules, and a card table to play on. So for this project, I’m going to be creating classes that model these objects. I’ve created a Java program with the following classes.
- Player class – to handle player specific operations, such as deciding to hit or stand.
- Dealer class – to handle dealer specific operations, such as drawing cards to 16 and standing on 17 or above.
- Person class – to act as a parent class of Dealer and Player. They both need a set of cards, a name, a way to print their hands to the console, etc.
- Card class – to represent a card and handle card operations. Each card needs a suit and a rank.
- Rank enum – to hold the ranks, such as 1 through 10, Jack, King, Queen, and Ace, along with their numerical values (1 through 11)
- Suit enum – to hold the suits such as Club, Diamond, Heart, and Spade.
- Deck class – to hold multiple cards and perform operations such as shuffling the deck
- Hand class – to represent the cards the player and the dealer are holding, and get the total value of the cards in their hand.
- Game class – to handle the bulk of the game logic, starting new rounds, keeping track of score, etc.
- Main class – to start the Game.
As you practice more, you’ll get better at determining the structure of your program beforehand. You may not know exactly how you’re going to implement each class and method at the start, and that’s okay. We can always add code, test it, and remove or modify methods as needed during the development process.
First Steps
Begin by creating a new Java project in your favorite IDE. You may call it whatever you would like, but I’m calling mine Blackjack. You may start with a command line template, or create the main method yourself. I’ve started with a console template and have added a line that prints out the message “Welcome to Blackjack.”
Main.java
package com.kevinsguides;
public class Main {
public static void main(String[] args) {
//Say hi to the user
System.out.println("Welcome to Blackjack");
}
}
Code language: Java (java)
All the main method is going to do is create a new Game object for us to start the game. So create a new class within the same package and name it Game. The only variables we’re going to create to start off with are ints to store the score. So declare the ints wins, losses, and pushes to store this information. These can be private ints, as we will only want to use them within the scope of this class.
Game.java
package com.kevinsguides;
public class Game {
//Create variables used by the Game class
private int wins, losses, pushes;
}
Code language: Java (java)
Next, we will need to create a constructor for the Game class. This will handle all the things that happen when we start a Game. In this case, we want to set our instance variables to zero.
Game.java
package com.kevinsguides;
public class Game {
//Create variables used by the Game class
private int wins, losses, pushes;
//Constructor for the Game class
public Game(){
//Set the score to 0
wins = 0; losses = 0; pushes = 0;
}
}
Code language: PHP (php)
Now that we have a Game class ready to go. We can create a new Game object in the main method of our Main class.
Main.java
package com.kevinsguides;
public class Main {
public static void main(String[] args) {
//Say hi to the user
System.out.println("Welcome to Blackjack");
//Create and start the Game
Game blackjack = new Game();
}
}
Code language: JavaScript (javascript)
Congratulations! You’ve just finished with the Main class, as all it’s going to do is create the Game. Now, we need to think about what else needs to be added to the Game to start making it function.
Building The Cards
We’re going to need to create some more classes now. The Game will require a deck to hold the cards, a discard deck to hold discarded cards, a dealer, and a player.
Let’s take this one at a time and start with the Deck. A deck will need to be made up of cards. So create two new classes – one called Deck and one called Card.
Since each deck is made of cards, and each card needs a rank and a suit, let’s also create two new Enums called Suit and Rank.
If you’re using IntelliJ – you can create a new Enum by right clicking your package and selecting New → Class → Enum. In Eclipse you right click the package and go to New → Enum.
Let’s start by working on the Suit enum, since that one’s a bit easier. Each type of Suit will have just one value – a String to hold the suit’s name. So create a constructor for the Suit enum that takes a String value suitName. Declare the String suitName as well, along with a toString method that returns the name of the suit.
Suit.java
package com.kevinsguides;
public enum Suit {
String suitName;
Suit(String suitName) {
this.suitName = suitName;
}
public String toString(){
return suitName;
}
}
Code language: JavaScript (javascript)
Now all that’s left is to create the four Suits along with their value:
Suit.java
package com.kevinsguides;
/**
* Contains the suits of a Card, Names
*/
public enum Suit {
CLUB("Clubs"),
DIAMOND("Diamonds"),
HEART("Hearts"),
SPADE("Spades");
String suitName;
Suit(String suitName) {
this.suitName = suitName;
}
public String toString(){
return suitName;
}
}
Code language: JavaScript (javascript)
Now that we’ve created the Suit class, let’s test it out. Return to the main method and add the following line:
System.out.println(Suit.CLUB);
Code language: CSS (css)
Clubs
Hooray! Our toString() method is working right. You may delete the test line once you’re done with it.
Next, we need to set up our ranks. Like suits, our ranks will also have a String name, which I’ve opted to call rankName. Additionally, the Ranks will have a specific value attached to them. So we need to create an int called value to hold the value of each rank.
Just like we did with Suits, create a constructor that gives each Rank a name, and add an int to store the value.
Rank.java
String rankName;
int rankValue;
Rank(String rankName, int rankValue){
this.rankName = rankName;
this.rankValue = rankValue;
}
Code language: JavaScript (javascript)
Next, create a toString method that returns the name.Rank.java
public String toString(){
return rankName;
}
Code language: JavaScript (javascript)
Finally, create all the different ranks along with their name and value. Remember, 1-10 will have a value equal to their number. Face cards like Jack, King, and Queen are all worth 10. Ace will be worth 11. We will work on the logic that sets aces to 1 or 11 later. For our enum – make them 11.
When everything’s said and done, your Rank enum should look very similar to the following:
Rank.java
package com.kevinsguides;
/**
* Contains the Ranks of Cards, Names, and Values
*/
public enum Rank {
ACE("Ace", 11),
TWO("Two", 2),
THREE("Three", 3),
FOUR("Four",4),
FIVE("Five",5),
SIX("Six",6),
SEVEN("Seven",7),
EIGHT("Eight",8),
NINE("Nine",9),
TEN("Ten",10),
JACK("Jack",10),
QUEEN("Queen",10),
KING("King",10);
String rankName;
int rankValue;
Rank(String rankName, int rankValue){
this.rankName = rankName;
this.rankValue = rankValue;
}
public String toString(){
return rankName;
}
}
Code language: JavaScript (javascript)
Now you can test out the rank enum by adding the following line to your main method:
System.out.println(Rank.ACE + " has a value of " + Rank.ACE.rankValue);
Code language: CSS (css)
Ace has a value of 11
Great! That’s working too. Now that we’ve got our suits and ranks ready to go, we can start working our way up by working on the Card class.
Q: Where else could we have placed the test line to have it executed?
The Card class needs a constructor, along with some instance variables. Each Card needs to have a suit and a rank, so create the private instance variables rank and suit of type Rank and Suit. Then, create a constructor that takes a Suit and a Rank as its parameters, and sets the variables accordingly.
Card.java
package com.kevinsguides;
public class Card {
//vars
private Suit suit;
private Rank rank;
//create a card given a suit and a rank
public Card(Suit suit, Rank rank){
this.suit = suit;
this.rank = rank;
}
}
Code language: PHP (php)
Our Card class will be useless if we don’t provide methods to figure out the cards rank, suit, and value. So create getter methods for these values. Additionally, create a toString method that returns a String representation of the Card, with its Suit, Rank, and Value all in one. The toString String should look something like “RANK of SUIT (Value),” or however you want to format it to look nice. There is no need to create setter methods for these variables, as once a Card is created, we’re never going to need to change its rank, suit, or value. Just like in real life, you can’t take a Queen of Hearts and turn it into a King of Diamonds.
Card.java
//you should be making comments
public int getValue(){
return rank.rankValue;
}
public Suit getSuit(){
return suit;
}
public Rank getRank(){
return rank;
}
public String toString(){
return ("["+rank+" of "+ suit + "] ("+this.getValue()+")");
}
Code language: PHP (php)
So at this point the entire file should look something like this:
package com.kevinsguides;
public class Card {
//vars
private Suit suit;
private Rank rank;
//create a card given a suit and a rank
public Card(Suit suit, Rank rank){
this.suit = suit;
this.rank = rank;
}
public int getValue(){
return rank.rankValue;
}
public Suit getSuit(){
return suit;
}
public Rank getRank(){
return rank;
}
public String toString(){
return ("["+rank+" of "+ suit + "] ("+this.getValue()+")");
}
}
Code language: PHP (php)
Now we have enough things in place to test out the Card class. In either the main method or the Game() constructor method, create a new Card and see if it’s toString method is working right. Try doing this yourself, but if you need help, here is the solution. Remember, you can assign the necessary enum values using Rank.RANK and Suit.SUIT, where RANK is the rank and SUIT is the suit. You may create the test card with whatever kind of suit and rank you would like.
Once you have tested the Card class, it’s time to move on to making the Deck. You may delete any code you used to test the Card class.
Creating The Deck
We’re starting to get somewhere! Now that we have Cards to work with, we can start building Decks. Our Deck class will be used to manage an ArrayList of Cards. So start by going to your Deck class, and create an instance variable called deck of type ArrayList Card. Note that you will need to import ArrayLists into this class.
private ArrayList<Card> deck;
Code language: HTML, XML (xml)
Next, build a constructor for the Deck. It should create an empty ArrayList of cards for us to use later.
public Deck(){
deck = new ArrayList<Card>();
}
Code language: PHP (php)
Make sure you put in a getter getCards() to easily get the cards in the deck later.
public ArrayList<Card> getCards() {
return deck;
}
Code language: PHP (php)
Your complete Deck class should now look something like this:
Deck.java
package com.kevinsguides;
import java.util.ArrayList;
public class Deck {
private ArrayList<Card> deck;
public Deck(){
deck = new ArrayList<Card>();
}
public ArrayList<Card> getCards() {
return deck;
}
}
Code language: PHP (php)
Adding Cards
Now a deck is useless without some cards in it. Let’s create an add() method to add a single Card to the deck.
public void addCard(Card card){
deck.add(card);
}
Code language: JavaScript (javascript)
Next, let’s create a toString() method that returns a String containing every single card in the deck. To do this, I’ve created a for-each loop that iterates through each Card in the deck, and adds it to a String that we return.
public String toString(){
//A string to hold everything we're going to return
String output = "";
//for each Card "card" in the deck
for(Card card: deck){
//add the card and the escape character for a new line
output += card;
output += "\n";
}
return output;
}
Code language: JavaScript (javascript)
Now that we have a way to create a deck, a way to add cards to it, and a way to print its contents out, we can test the Deck class. Add the following lines to your main method to create a new deck and add some cards to it.
Main.java
//Make some cards and a deck
Deck testDeck = new Deck();
Card aCard = new Card(Suit.CLUB, Rank.QUEEN);
Card bCard = new Card(Suit.DIAMOND,Rank.ACE);
Card cCard = new Card(Suit.SPADE, Rank.SIX);
//Add the cards to the deck
testDeck.addCard(aCard);
testDeck.addCard(bCard);
testDeck.addCard(cCard);
//Print out the deck
System.out.println(testDeck);
Code language: JavaScript (javascript)
[Queen of Clubs] (10) [Ace of Diamonds] (11) [Six of Spades] (6)
Creating A Standard Deck
Now that we’ve got a working Deck, let’s add some additional methods to it. I’d like to start by adding a method to the Deck class to create a new deck with 52 standard playing cards.
To do this, I have decided to create an overloaded constructor that takes a boolean value of true, indicating that we want to make a new deck of cards with 52 cards. So creating a new Deck() creates an empty deck, and creating a new Deck(true) creates a deck of 52 playing cards.
In order to add all 52 cards to the deck, the easiest way will be to loop through all the suits and all the ranks that we have. Thankfully, there’s a method we can use on enums that returns an array of all their values, allowing us to easily iterate through them. This is the .values()
method.
So we will need to use a nested loop here. In this case, it doesn’t matter if your inner loop is Suits and your outer loop is Ranks, or if your inner loop is Ranks and your outer loop Suits. Since we’re going to shuffle the deck afterwards, it doesn’t make a difference. However, I think it makes a bit more sense to have suits as the outer loop, as this will order them by suits first, then ranks second. So the order will be Ace of Clubs, One of Clubs, Two of Clubs… and so on, instead of Ace of Clubs, Ace of Diamonds, Ace of Hearts, Ace of Spades, One of Clubs… and so on.
My second constructor for the Deck class looks like this:
Deck.java
public Deck(boolean makeDeck){
deck = new ArrayList<Card>();
if(makeDeck){
//Go through all the suits
for(Suit suit : Suit.values()){
//Go through all the ranks
for(Rank rank : Rank.values()){
//add a new card containing each iterations suit and rank
deck.add(new Card(suit, rank));
}
}
}
}
Code language: PHP (php)
Again, let’s test this out in the main method.
//Make a standard deck of 52 cards
Deck testDeck = new Deck(true);
System.out.println(testDeck);
Code language: JavaScript (javascript)
If you did it right, this should print out a deck of all 52 cards.
[Ace of Clubs] (11) [Two of Clubs] (2) [Three of Clubs] (3) [Four of Clubs] (4) [Five of Clubs] (5) [Six of Clubs] (6) ... [Jack of Spades] (10) [Queen of Spades] (10) [King of Spades] (10)
Shuffle The Deck (Long Way)
Next, let’s add a shuffle method to shuffle the deck. I’m going to show you two ways to do this. First, we’ll create a loop that iterates through the number of cards in the deck. Each time the loop executes, it will pull one card at random from the deck ArrayList, and add it to a new shuffled ArrayList. Finally, it will replace the old deck with the newly shuffled ArrayList of cards.
Start by going to the Deck class and creating a new shuffle method. Since we’re going to create a loop that removes a random card from the deck, we can create a while loop that executes while the deck size is greater than zero. So once it runs out of cards to process, it will stop executing. You can get the size of the deck with the .size()
method.
public void shuffle(){
ArrayList<Card> shuffled = new ArrayList<Card>();
//iterate through the size of the deck, so each card can be pulled
while(deck.size()>0){
}
}
Code language: JavaScript (javascript)
Now, we need to pick a card at random from the original deck ArrayList. To do this, we can use the Math.random()
method, which returns a random number between 0 and 1. Since it’s a random number between 0 and 1, we can multiply it by the current size of the deck to get a random index between 0 and the size of the deck. For example, if Math.random() generates the number 0.3243, and the deck size is 52, it would give us a double equal to approximately 16.86. We cast that double to an int and get the number 16. Keep in mind indexes start at zero, but the size() method returns the total size of the deck, including zero. This means if the Random number generator generated the number 1, and our deck size was 52, we would actually want it to pull index 51. If we tried to get index 52 we would get an error. To solve this, we may simply subtract 1 from the random number we generate.
So in the body of the while loop, we can add these lines to get a random index and add it to the shuffled deck.
//Select a random index to pull
int cardToPull = (int)(Math.random()*(deck.size()-1));
//Add this random card to the new shuffled deck
shuffled.add(deck.get(cardToPull));
Code language: JavaScript (javascript)
Finally, we just need to remove the Card from the original ArrayList, so we don’t accidentally pull the same card multiple times. We may do that using the .remove(index)
method.
deck.remove(cardToPull);
Code language: CSS (css)
The last step is to set the old deck equal to the newly shuffled deck. You may do this with the standard assignment operator. At this point, your method should look as follows:
Deck.java
//Shuffle the deck
public void shuffle(){
ArrayList<Card> shuffled = new ArrayList<Card>();
//iterate through the size of the deck, so each card can be pulled
while(deck.size()>0){
//Select a random index to pull
int cardToPull = (int)(Math.random()*(deck.size()-1));
//Add this random card to the new shuffled deck
shuffled.add(deck.get(cardToPull));
//Remove the pulled card from the original deck
deck.remove(cardToPull);
}
deck = shuffled;
}
Code language: JavaScript (javascript)
That’s it! Let’s test it out. Create a new test deck of 52 cards, shuffle it, and print the results.
Main.java
public class Main {
public static void main(String[] args) {
//Say hi to the user
System.out.println("Welcome to Blackjack");
//Create and start the Game
Game blackjack = new Game();
//Make a standard deck of 52 cards
Deck testDeck = new Deck(true);
testDeck.shuffle();
System.out.println(testDeck);
}
}
Code language: JavaScript (javascript)
Welcome to Blackjack [Queen of Hearts] (10) [Three of Diamonds] (3) [Jack of Hearts] (10) [Nine of Spades] (9) [Seven of Clubs] (7) ... (continued for all 52 cards)
Shuffle Deck (Short Way)
Now that you’ve seen the logic behind creating a shuffle method, let’s take a look at another, much simpler way to shuffle the deck. The Collections utility class has a .shuffle(list, random)
method. If you’d like, you may delete the previous shuffle method, or just leave it as is. Either one will work fine.
import java.util.Collections;
import java.util.Random;
Code language: CSS (css)
Shuffle method looks like this:
Deck.java
public void shuffle(){
Collections.shuffle(deck, new Random());
}
Code language: JavaScript (javascript)
As always, check that it works by testing it out.
Hand Class
Now that we’ve got a working deck, we’re going to build the objects that handle the dealer’s actions and the player’s choices. Our program will have a Person class that handles the logic shared between the dealer and the player. The Person class will handle this shared logic. Each Person will have a hand of cards and a name. Since the Dealer and the Player are both a Person, the Dealer and the Player will have a name and a hand once we extend them as subclasses of Person.
Since each Person needs a hand, let’s start with creating the Hand class. Like the Deck class we created, the Hand class will be used to manage an ArrayList of Cards. It will contain methods to calculate the value of the hand, take cards from a deck, and discard the hand to a deck.
Create the Hand class and make a private instance variable called hand which is an ArrayList of Cards. You’ll have to import ArrayLists as well, and we might as well start with a constructor that creates an empty Hand.
Hand.java
import java.util.ArrayList;
public class Hand {
private ArrayList<Card> hand;
public Hand(){
hand = new ArrayList<Card>();
}
}
Code language: PHP (php)
Now let’s create a method to add a card from a deck to this hand. To do this, we can use the ArrayList’s add()
method. We have a method to add cards to a Deck in the Deck class, but we haven’t created a method to take cards from the deck yet. So let’s also create a takeCard() method to the Deck class that returns the top card from the deck, and removes it from the deck at the same time.
Hand.java
public void takeCardFromDeck(Deck deck){
hand.add(deck.takeCard());
}
Code language: JavaScript (javascript)
Deck.java
public Card takeCard(){
//Take a copy of the first card from the deck
Card cardToTake = new Card(deck.get(0));
//Remove the card from the deck
deck.remove(0);
//Give the card back
return cardToTake;
}
Code language: PHP (php)
In the above code for takeCard(), I am trying to create a new Card as a copy of another card from deck.get(0). To do this, I’ll need to create a copy constructor in the Card class.
All this does is set the suit and rank of a Card equal to that of another Card provided in the parameters.
Card.java
public Card(Card card){
this.suit = card.getSuit();
this.rank = card.getRank();
}
Code language: JavaScript (javascript)
Next, let’s create a toString() method in the Hand class so we have a way of printing the Dealer or the Player’s current hand.
Hand.java
public String toString(){
String output = "";
for(Card card: hand){
output += card + " - ";
}
return output;
}
Code language: JavaScript (javascript)
Now that we have a way to create a Hand, add cards to it, and print it out, let’s create a test in the Main method.
Main.java
Deck testDeck = new Deck(true);
Hand testHand = new Hand();
testHand.takeCardFromDeck(testDeck);
testHand.takeCardFromDeck(testDeck);
testHand.takeCardFromDeck(testDeck);
System.out.println("testHand now has the following cards:");
System.out.println(testHand);
System.out.println("testDeck now looks like this:");
System.out.println(testDeck);
Code language: JavaScript (javascript)
The above code should create a fresh deck, take the top 3 cards, and print out the results. It then prints out the deck to show that the first 3 cards are now in the Hand.
Welcome to Blackjack testHand now has the following cards: [Ace of Clubs] (11) - [Two of Clubs] (2) - [Three of Clubs] (3) - testDeck now looks like this: [Four of Clubs] (4) [Five of Clubs] (5) [Six of Clubs] (6) ...
Next let’s work on the calculatedValue() method, which returns an int containing the value of the hand. For example, if the hand has two Kings (face cards) it’s worth 20 points, if it has a Queen and a Four, it’s worth 14, etc. The tricky part will be handling Aces, which can be valued at 1 or 11 depending on the situation. We will calculate the value of a hand with aces in a sort of backwards way – we’ll first calculate the hand with Aces valued at 11. If this puts them over 21, we’ll subtract 10 for each ace they have, up to four times depending on how many aces they have. So if they somehow managed to get 4 aces in a row, their hand would be worth the highest possible value combination that keeps them under 21. So 4 aces would be valued at 11, 1, 1, and 1, for a total of 14. Two kings and two aces would be valued at 22, and put them over the 21 limit.
Hand.java
public int calculatedValue(){
//variable to count number of aces, and current total value
int value = 0;
int aceCount = 0;
//For each card in this hand
for(Card card: hand){
//Add the card value to the hand
value += card.getValue();
//Count how many aces have been added
if (card.getValue() == 11){
aceCount ++;
}
}
//if we have a scenario where we have multiple aces, as may be the case of drawing 10, followed by two or more aces, (10+11+1 > 21)
//go back and set each ace to 1 until get back under 21, if possible
if (value > 21 && aceCount > 0){
while(aceCount > 0 && value > 21){
aceCount --;
value -= 10;
}
}
return value;
}
Code language: PHP (php)
Now that we have code to calculate the value of the hand, let’s test it out.
Delete any other test code in the main method and add the following, which creates a deck containing 4 aces, moves those aces to a hand, and checks their value.
It should return a value of 14, as the program calculates its value at 11+11+11+11−10−10−10=14.
Main.java
Deck testDeck = new Deck();
testDeck.addCard(new Card(Suit.CLUB, Rank.ACE));
testDeck.addCard(new Card(Suit.CLUB, Rank.ACE));
testDeck.addCard(new Card(Suit.CLUB, Rank.ACE));
testDeck.addCard(new Card(Suit.CLUB, Rank.ACE));
Hand testHand = new Hand();
testHand.takeCardFromDeck(testDeck);
testHand.takeCardFromDeck(testDeck);
testHand.takeCardFromDeck(testDeck);
testHand.takeCardFromDeck(testDeck);
System.out.println("The value of this hand is: " + testHand.calculatedValue());
Code language: JavaScript (javascript)
Welcome to Blackjack The value of this hand is: 14
Person, Dealer, Player Classes
Now that we have pretty much all the code needed to handle the Cards, Decks, and Hands complete, we can start working on the classes that use these objects. We’ll start with the Person, Dealer, and Player class.
Our game will only have two “Person”s in it, a “Dealer” Person and a “Player” Person. Each “Person” will have their own “Hand” of cards. Each “Person” will be able to “hit” or take a card from a Deck.
We’ll include a boolean hasBlackjack() which returns a value of true or false if the Person is holding Blackjack (a Hand valued at 21). We’ll also include a printHand() method that prints the Person’s hand as a nicely formatted String.
There will be a Dealer specific method to print their first Hand – which prints their hand with one card face down, and a Player specific method to handle the logic when the Player decides to hit or stand.
Based on the UML diagram above, can you complete the Person, Dealer, and Player classes without looking at the code below? With the exception of pershaps the makeDecision method, which you may want to follow along for.
Since both our Player and Dealer classes will be a “Person” we can start by creating an abstract Person class. Recall that abstract classes cannot be directly instantiated. It is abstract because we’re never going to create individual “Person” objects in the game, we’re only going to create a “Player” and a “Dealer.” The “Person” class is used to share the logic between the two.
Start by creating a new abstract Person class, give them an empty Hand and a name, and create a constructor.
Person.java
public abstract class Person {
private Hand hand;
private String name;
/**
* Create a new Person
*/
public Person(){
this.hand = new Hand();
this.name = "";
}
}
Code language: PHP (php)
Next, add some setters and getters for their hand and name.
Person.java
public Hand getHand(){
return this.hand;
}
public void setHand(Hand hand){
this.hand = hand;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
Code language: JavaScript (javascript)
Next, let’s create a Dealer class which extends the Person class. Since a Dealer is a Person, when a Dealer object is created, it will automatically call the constructor for the Person class. We can use the super keyword to call the parent (Person) class’s setName method, and name this Person “Dealer”.
Dealer.java
public class Dealer extends Person{
/**
* Create a new Dealer
*/
public Dealer(){
//Name the dealer "Dealer"
super.setName("Dealer");
}
}
Code language: PHP (php)
Next, let’s test it out to make sure it’s working so far. In the main method, create a new Dealer and print out their name.
Main.java
Dealer myDealer = new Dealer();
System.out.println("The dealer's name is: " + myDealer.getName());
Code language: JavaScript (javascript)
The dealer's name is: Dealer
Since it was able to output the dealer’s name is Dealer, we know that we’ve successfully created a Dealer who is a Person, and that the constructors are working appropriately.
Next, let’s create the Player class the same way we created the Dealer class. Add an empty placeholder method for the makeDecision() method. We will add more code to this later, after we work out some more of the main game logic.
Person.java
public class Player extends Person {
//Create a new Player
public Player() {
super.setName("Player");
}
public void makeDecision() {
//Coming Soon
}
}
Code language: PHP (php)
Finally, add a boolean to the Person class that checks if they have Blackjack using the previously created calculatedValue() method.
Person.java
public boolean hasBlackjack(){
if(this.getHand().calculatedValue() == 21){
return true;
}
else{
return false;
}
}
Code language: JavaScript (javascript)
Starting the Round
Now that we’ve finished, or partially finished, all the other classes, we can finally start working on the main part of the game!
Begin by going to your Game class and adding instance variables to represent the Player and the Dealer. In the constructor for the Game, create two decks (a main deck and a discard deck), shuffle the deck, and start the round by calling a new startRound() method.
Game.java
public class Game {
//Declare variables needed for Game class
private Deck deck, discarded;
private Dealer dealer;
private Player player;
private int wins, losses, pushes;
/**
* Constructor for Game, creates our variables and starts the Game
*/
public Game(){
//Create a new deck with 52 cards
deck = new Deck(true);
//Create a new empty deck
discarded = new Deck();
//Create the People
dealer = new Dealer();
player = new Player();
//Shuffle the deck and start the first round
deck.shuffle();
startRound();
}
//This method will handle the logic for each round
private void startRound(){
}
}
Code language: PHP (php)
Before we continue, let’s take a moment to think about what steps we’re going to have to do for the first round of Blackjack. We’ll worry about the second round later.
First we’ll need to have our Dealer, Player, and Deck ready to go. We’ve already done that part.
Next, we need to give the Dealer and the Player two cards from the main deck. Then we need to show the player their cards, and show the dealer’s cards with one card face down.
After showing the cards, we have to check if either the Dealer or the Player has Blackjack. If either or both of them have Blackjack, the round is over and we need to calculate the score accordingly before starting a new round.
If neither player or dealer has Blackjack, the player must be given the option to hit however many times they’d like (until they go over the limit of 21), or stand on their current hand.
Finally, once the Player stands. The dealer must draw until their hand is valued at 17 or higher. We then calculate a winner based on if anyone busted (went over 21) or who has the highest valued hand. Then we put the cards in the discard pile and start the next round.
So to begin, add code to the startRound() class that draws two cards for the dealer and player.
Game.java
private void startRound(){
//Give the dealer two cards
dealer.getHand().takeCardFromDeck(deck);
dealer.getHand().takeCardFromDeck(deck);
//Give the player two cards
player.getHand().takeCardFromDeck(deck);
player.getHand().takeCardFromDeck(deck);
}
Code language: JavaScript (javascript)
Next, we need to print the first hand for the dealer and the player’s hand. To do this, we’ll add a printHand() method to the Person class, which can be used to print out the Dealer or the Player’s hand.
Person.java
/**
* Prints a formatted version of the Person's hand
*/
public void printHand(){
System.out.println(this.name + "'s hand looks like this:");
System.out.println(this.hand + " Valued at: " + this.hand.calculatedValue());
}
Code language: JavaScript (javascript)
The above code prints out the Person’s hand along with the calculated value of the hand. For the start of the round, we need to use a dealer-specific method that doesn’t show one of the cards.
In order to get the first card from the Dealer’s hand, we’ll have to add a getCard(index) method to the Hand class.
Hand.java
public Card getCard(int idx){
return hand.get(idx);
}
Code language: PHP (php)
Now that we have a way to get just one card from a Hand, we can use the following code to figure out what the first card is, without revealing the second.
Dealer.java
/**
* Prints the dealer's first hand, with one card face down.
*/
public void printFirstHand(){
System.out.println("The dealer's hand looks like this:");
System.out.println(super.getHand().getCard(0));
System.out.println("The second card is face down.");
}
Code language: JavaScript (javascript)
Once you have added the appropriate code to the Dealer and Person class, return to the Game class and print out their hands for the start of the round.
You may also remove any test code from the main method.
Game.java
//This method will handle the logic for each round
private void startRound() {
//Give the dealer two cards
dealer.getHand().takeCardFromDeck(deck);
dealer.getHand().takeCardFromDeck(deck);
//Give the player two cards
player.getHand().takeCardFromDeck(deck);
player.getHand().takeCardFromDeck(deck);
//Print their hands
dealer.printFirstHand();
player.printHand();
}
Code language: JavaScript (javascript)
At this point, the game looks like this when I run it. It should look similar for you, but with different cards, as the randomized order is different each time.
Welcome to Blackjack The dealer's hand looks like this: [Queen of Diamonds] (10) The second card is face down. Player's hand looks like this: [Jack of Hearts] (10) - [Ace of Hearts] (11) - Valued at: 21
Progress Check
At this point, most of your classes should be working. You should be able to create a Game, start a Round with a Player and a Dealer, and have working Hands, Cards, and Decks. If you have run into any issues thus far, click the button below to compare my completed source files up to this point with your own. Once everything is in order, and you’ve identified your mistake(s) or missing code, continue with the guide.
After displaying the cards, the next step is to check if either the dealer or the player has Blackjack. For the sake of this game, we’re not going to worry about things like “Insurance” against the dealer having Blackjack, which is allowed in some games. This part can be done with simple if statements. If the dealer has Blackjack and the player does not, we will count it as a Loss and start another round. If the Player and the Dealer both have Blackjack, we will consider it a tie or a push. If the Player has Blackjack and the Dealer does not, then it counts as a Win. In any of these three scenarios, the counter is updated and we call the startRound() method to start another round.
So the following code goes in the startRound() method after we show the cards.
Game.java
//Check if dealer has BlackJack to start
if(dealer.hasBlackjack()){
//Show the dealer has BlackJack
dealer.printHand();
//Check if the player also has BlackJack
if(player.hasBlackjack()){
//End the round with a push
System.out.println("You both have 21 - Push.");
pushes++;
startRound();
}
else{
System.out.println("Dealer has BlackJack. You lose.");
dealer.printHand();
losses++;
startRound();
}
}
//Check if player has blackjack to start
//If we got to this point, we already know the dealer didn't have blackjack
if(player.hasBlackjack()){
System.out.println("You have Blackjack! You win!");
wins++;
startRound();
}
Code language: JavaScript (javascript)
If all the above code executed without starting a new round, we know that neither Person has Blackjack. So we can now allow the Player to hit or stand. To do this, we’ll call the makeDecision method (which hasn’t been implemented yet) directly after checking for Blackjack in the startRound method.
Game.java
player.makeDecision();
Code language: CSS (css)
Making The Decisions
We could continue adding more code to the startRound() method, but it’s getting pretty long already. So I’ve decided to put all the code for deciding to hit or stand in the Player class.
Recall earlier we created a makeDecision() method in the Player class, but left it blank. Now it’s time to start working on this method.
First, let’s think about what information we’ll need to make a decision. We already have access to the Player’s hand, as the makeDecision method is part of the Player class, which extends the Person class, which has a Hand. We don’t have access to the main Deck, which we’ll need if the player decides to hit. We’ll also need access to the discard pile, so we can shuffle it and use it as the new deck if the main deck runs out of cards. So we should pass the main and discard Deck to the makeDecision method when we use it. Add both decks to the arguments for the method in the Player class.
Player.java
public void makeDecision(Deck deck, Deck discard) {
//coming soon
}
Code language: JavaScript (javascript)
Additionally, update the makeDecision() method in your startRound method of the Game class to pass the decks along.
Game.java
...
player.makeDecision(deck, discarded);
Code language: CSS (css)
Now we need to ask the Player if they want to hit or stand. We’ll do this using a scanner and asking them to enter the number 1 to hit, or 2 to stand. If they enter an invalid choice, we’ll ask them again.
In order to do this, we should open a user input Scanner. This can be done directly in the Player class. Since the game only has one Player, and this is really the only time we’re going to be asking them to make a decision, this is the only part of the code where we’ll need a Scanner. We don’t have to worry about closing it, as we’ll be using it again each round. Import the Scanner to the Player class and create a new input Scanner called input.
Player.java
import java.util.Scanner;
/**
* Handles all Player specific operations
*/
public class Player extends Person {
Scanner input = new Scanner(System.in);
//Create a new Player
public Player() {
super.setName("Player");
}
//Allow the player to make decisions
public void makeDecision(Deck deck, Deck discard) {
}
}
Code language: JavaScript (javascript)
In order to “dummy-proof” or prevent errors, I’ve decided to surround my scanner reader with a generic try-catch block. I have created an int called decision to represent the decision the player makes (1 for hit, 2 for stand) and a boolean called “getNum” that is true while we’re in the process of reading their input. I put this in a while loop with the try/catch. Once we read an int successfully, it sets getNum to false and exits the loop. If it fails to get an int value, getNum remains true, and the loop executes again, allowing the user to try entering a different value.
Player.java
public void makeDecision(Deck deck, Deck discard) {
int decision = 0;
boolean getNum = true;
//while were getting a number...
while(getNum){
try{
System.out.println("Would you like to: 1) Hit or 2) Stand");
decision = input.nextInt();
getNum = false;
}
catch(Exception e){
System.out.println("Invalid");
input.next();
}
//we don't close the scanner, because we will need it later.
}
//test it
System.out.println("You selected: " + decision);
}
Code language: PHP (php)
I also added a line at the end to make sure this works. If you run the program, it should look something like this:
Welcome to Blackjack The dealer's hand looks like this: [Four of Clubs] (4) The second card is face down. Player's hand looks like this: [Ten of Spades] (10) - [Eight of Spades] (8) - Valued at: 18 Would you like to: 1) Hit or 2) Stand bafba Invalid Would you like to: 1) Hit or 2) Stand 2 You selected: 2
As you can see, when I typed gibberish, it said Invalid and asked me to type another answer. When I typed 2, it says I selected 2. You may delete the test line once it’s working properly.
Next we need to check if the player typed 1 to hit. If they hit, we need to take the top card from the deck. If the deck’s out of cards, we need to replace the empty deck with the discard pile, shuffle the deck, and then take the top card. So there’s some work involved.
Since both Players and Dealers are going to want to hit the deck at some point, we should put our hit method in the Person class so the logic can be shared between the two.
Go to the Person class and add a hit method, taking our two decks as parameters.
Person.java
public void hit(Deck deck, Deck discard){
}
Code language: JavaScript (javascript)
Before we can hit, we need to make sure the deck we’re taking from has cards in it. Add a hasCards boolean to the Deck class which returns true if the Deck has 1 or more cards left.
The ArrayList.size() method returns the size of an ArrayList, so we can use this to check if the Deck has any cards left.
Deck.java
public boolean hasCards(){
if (deck.size()>0){
return true;
}
else{
return false;
}
}
Code language: PHP (php)
Now that we can check if there’s cards in the Deck, we’ll also need a way to reload our main deck from the discard pile if it’s empty.
Add another method that adds cards from a discard deck to this deck, shuffles it, and empties the discard pile. You’ll also have to create an emptyDeck() method that empties the deck using the ArrayList.clear() method. We already have an addCard() method, but we also need an addCards() method capable of adding multiple cards at once. The ArrayList.addAll() method can do this for us.
Deck.java
/**
* Empties out this Deck
*/
public void emptyDeck(){
deck.clear();
}
/**
*
* @param cards an arraylist of cards to be added to this deck
*/
public void addCards(ArrayList<Card> cards){
deck.addAll(cards);
}
/**
* Take all the cards from a discarded deck and place them in this deck, shuffled.
* Clear the old deck
* @param discard - the deck we're getting the cards from
*/
public void reloadDeckFromDiscard(Deck discard){
this.addCards(discard.getCards());
this.shuffle();
discard.emptyDeck();
System.out.println("Ran out of cards, creating new deck from discard pile & shuffling deck.");
}
Code language: PHP (php)
Now that we have more useful methods in the Deck class, we can use them in the hit method of the Person class.
Start by returning to the hit method, checking if the deck is out of cards, and reloading the deck if it ran out.
After checking if the deck’s empty and reloading it if necessary, we take the top card from the Deck, add it to the Person’s hand, and print out the hand with the new card in it.
Person.java
public void hit(Deck deck, Deck discard){
//If there's no cards left in the deck
if (!deck.hasCards()) {
deck.reloadDeckFromDiscard(discard);
}
this.hand.takeCardFromDeck(deck);
System.out.println(this.name + " gets a card");
this.printHand();
}
Code language: JavaScript (javascript)
Next, return to the Player class and add the hit functionality. Use conditions to check if they hit or stood, and proceed accordingly. If they stand, we can use the return keyword to exit the method at this point. If they want to hit again, call this same method again.
Player.java
public void makeDecision(Deck deck, Deck discard) {
int decision = 0;
boolean getNum = true;
while(getNum){
try{
System.out.println("Would you like to: 1) Hit or 2) Stand");
decision = input.nextInt();
getNum = false;
}
catch(Exception e){
System.out.println("Invalid");
input.next();
}
//we don't close the scanner, because we will need it later.
}
//if they decide to hit
if (decision == 1) {
//hit the deck using the deck and discard deck
this.hit(deck, discard);
//return (exit the method) if they have blackjack or busted
if(this.getHand().calculatedValue()>20){
return;
}
//if they didnt bust or get 21, allow them to decide to hit or stand again by going back to this same method
else{
this.makeDecision(deck, discard);
}
//if they type any number other than 1, we'll assume they're standing
} else {
System.out.println("You stand.");
}
}
Code language: JavaScript (javascript)
Now that we’ve added hit functionality for the Player, let’s test it out. Simply run the program.
My program looks like this when I tried to hit repeatedly. As you can see, once I went over 21, it returned and exited the loop. Since we haven’t finished the program yet, it just ended here. This is the expected behavior at this point.
Welcome to Blackjack The dealer's hand looks like this: [Jack of Spades] (10) The second card is face down. Player's hand looks like this: [Two of Diamonds] (2) - [Eight of Diamonds] (8) - Valued at: 10 Would you like to: 1) Hit or 2) Stand 1 Player gets a card Player's hand looks like this: [Two of Diamonds] (2) - [Eight of Diamonds] (8) - [Jack of Diamonds] (10) - Valued at: 20 Would you like to: 1) Hit or 2) Stand 1 Player gets a card Player's hand looks like this: [Two of Diamonds] (2) - [Eight of Diamonds] (8) - [Jack of Diamonds] (10) - [King of Clubs] (10) - Valued at: 30 Process finished with exit code 0
We’re finally getting towards the end! Return to the Game class and add code to check if the Player has busted after they’ve made their decision to hit or stand.
Add the following code to the startRound method after the player makes their decision.
Game.java
//Check if they busted
if(player.getHand().calculatedValue() > 21){
System.out.println("You have gone over 21.");
//count the losses
losses ++;
//start the round over
startRound();
}
Code language: JavaScript (javascript)
If we’ve gotten past this point and neither player has Blackjack, and the Player has not busted, it’s the Dealer’s turn to reveal their upside down card and start hitting. Since we already created a hit method, we can use this here. It’s a bit simpler than the Player method, since we’re just automatically hitting until the dealer has a hand valued at 17 or higher. We can place the hit method for the dealer in a while loop.
Game.java
//Now it's the dealer's turn
dealer.printHand();
while(dealer.getHand().calculatedValue()<17){
dealer.hit(deck, discarded);
}
Code language: JavaScript (javascript)
Finally, now that the Player and the Dealer have both completed their turns, it’s time to figure out who wins, count the results, and start another round.
Game.java
//Check who wins
if(dealer.getHand().calculatedValue()>21){
System.out.println("Dealer busts");
wins++;
}
else if(dealer.getHand().calculatedValue() > player.getHand().calculatedValue()){
System.out.println("You lose.");
losses++;
}
else if(player.getHand().calculatedValue() > dealer.getHand().calculatedValue()){
System.out.println("You win.");
wins++;
}
else{
System.out.println("Push.");
}
//Start a new round
startRound();
Code language: JavaScript (javascript)
Let’s run the program and see what happens at this point. Some logic is missing, but do you know what?
Welcome to Blackjack The dealer's hand looks like this: [Five of Clubs] (5) The second card is face down. Player's hand looks like this: [Two of Hearts] (2) - [Four of Spades] (4) - Valued at: 6 Would you like to: 1) Hit or 2) Stand 1 Player gets a card Player's hand looks like this: [Two of Hearts] (2) - [Four of Spades] (4) - [Ten of Diamonds] (10) - Valued at: 16 Would you like to: 1) Hit or 2) Stand 2 You stand. Dealer's hand looks like this: [Five of Clubs] (5) - [Eight of Diamonds] (8) - Valued at: 13 Dealer gets a card Dealer's hand looks like this: [Five of Clubs] (5) - [Eight of Diamonds] (8) - [Queen of Hearts] (10) - Valued at: 23 Dealer busts The dealer's hand looks like this: [Five of Clubs] (5) The second card is face down. Player's hand looks like this: [Two of Hearts] (2) - [Four of Spades] (4) - [Ten of Diamonds] (10) - [King of Diamonds] (10) - [Three of Hearts] (3) - Valued at: 29 Would you like to: 1) Hit or 2) Stand
As you can see in my above example, it started another round without discarding the hands to the discard pile. Additionally, it didn’t announce the score. Finally, what happens if we run out of cards in our Deck to deal the Player and the Dealer their first cards?
To solve this, I added the following code to the start of the startRound() method.
Game.java
if(wins>0 || losses>0 || pushes > 0){
System.out.println();
System.out.println("Starting Next Round... Wins: " + wins + " Losses: "+ losses+ " Pushes: "+pushes);
dealer.getHand().discardHandToDeck(discarded);
player.getHand().discardHandToDeck(discarded);
}
//Check to make sure the deck has at least 4 cards left
if(deck.cardsLeft() < 4){
deck.reloadDeckFromDiscard(discarded);
}
Code language: JavaScript (javascript)
You’ll notice that I made up some new methods as I went along. I created a discardHandToDeck method, which discards a Hand to a Deck, and a cardsLeft integer which returns the amount of cards left in a Deck.
Hand.java
public void discardHandToDeck(Deck discardDeck){
//copy cards from hand to discardDeck
discardDeck.addCards(hand);
//clear the hand
hand.clear();
}
Code language: JavaScript (javascript)
Deck.java
public int cardsLeft(){
return deck.size();
}
Code language: PHP (php)
When complete, my final startRound() method looks like this:
Game.java
//This method will handle the logic for each round
private void startRound() {
if(wins>0 || losses>0 || pushes > 0){
System.out.println();
System.out.println("Starting Next Round... Wins: " + wins + " Losses: "+ losses+ " Pushes: "+pushes);
dealer.getHand().discardHandToDeck(discarded);
player.getHand().discardHandToDeck(discarded);
}
//Check to make sure the deck has at least 4 cards left
if(deck.cardsLeft() < 4){
deck.reloadDeckFromDiscard(discarded);
}
//Give the dealer two cards
dealer.getHand().takeCardFromDeck(deck);
dealer.getHand().takeCardFromDeck(deck);
//Give the player two cards
player.getHand().takeCardFromDeck(deck);
player.getHand().takeCardFromDeck(deck);
//Print their hands
dealer.printFirstHand();
player.printHand();
//Check if dealer has BlackJack to start
if(dealer.hasBlackjack()){
//Show the dealer has BlackJack
dealer.printHand();
//Check if the player also has BlackJack
if(player.hasBlackjack()){
//End the round with a push
System.out.println("You both have 21 - Push.");
pushes++;
startRound();
}
else{
System.out.println("Dealer has BlackJack. You lose.");
dealer.printHand();
losses++;
startRound();
}
}
//Check if player has blackjack to start
//If we got to this point, we already know the dealer didn't have blackjack
if(player.hasBlackjack()){
System.out.println("You have Blackjack! You win!");
wins++;
startRound();
}
//Let the player decide what to do next
player.makeDecision(deck, discarded);
//Check if they busted
if(player.getHand().calculatedValue() > 21){
System.out.println("You have gone over 21.");
//count the losses
losses ++;
//start the round over
startRound();
}
//Now it's the dealer's turn
dealer.printHand();
while(dealer.getHand().calculatedValue()<17){
dealer.hit(deck, discarded);
}
//Check who wins
if(dealer.getHand().calculatedValue()>21){
System.out.println("Dealer busts");
wins++;
}
else if(dealer.getHand().calculatedValue() > player.getHand().calculatedValue()){
System.out.println("You lose.");
losses++;
}
else if(player.getHand().calculatedValue() > dealer.getHand().calculatedValue()){
System.out.println("You win.");
wins++;
}
else{
System.out.println("Push.");
pushes++;
}
//Start a new round
startRound();
}
Code language: JavaScript (javascript)
If you did everything above properly, you should now have a working game of Blackjack. You should also see a message come up when the deck gets reshuffled every time it goes through the whole thing.
Welcome to Blackjack The dealer's hand looks like this: [Queen of Diamonds] (10) The second card is face down. Player's hand looks like this: [Ace of Spades] (11) - [Eight of Hearts] (8) - Valued at: 19 Would you like to: 1) Hit or 2) Stand 2 You stand. Dealer's hand looks like this: [Queen of Diamonds] (10) - [Six of Diamonds] (6) - Valued at: 16 Dealer gets a card Dealer's hand looks like this: [Queen of Diamonds] (10) - [Six of Diamonds] (6) - [Nine of Hearts] (9) - Valued at: 25 Dealer busts Starting Next Round... Wins: 1 Losses: 0 Pushes: 0 The dealer's hand looks like this: [Ace of Hearts] (11) The second card is face down. Player's hand looks like this: [Nine of Spades] (9) - [Three of Hearts] (3) - Valued at: 12 Would you like to: 1) Hit or 2) Stand 2 You stand. Dealer's hand looks like this: [Ace of Hearts] (11) - [Nine of Clubs] (9) - Valued at: 20 You lose.
Download Completed Project
If this was too easy for you, try the following things to challenge yourself.
Add a Betting System: Give users some free money, like $100, and then allow them to put money down on each hand. For each hand they win, double their bet. For each hand they lose, take away their bet. Keep track of how much money have have left at the end of each round. End the game when they run out of money.
Modify the decks so 8 full decks of cards are used in a game instead of just 1, like most Casinos.
Add a GUI using the existing game logic.