5 files in total
Card.java
Deck.java
Hand.java
BlackjackGame.java
A PDF that contains your self-assessment & reflection
Homeworks are an opportunity to engage with the material and practice your programming skills. To support you, solutions will be available on moodle. It is your responsibility to engage with them in a way that strategically moves your learning forward. You should:
Attempt the homework without looking at the solutions.
Review the solutions; if you were stuck, you may revise your homework. You may find yourself iteratively reviewing and revising to best support your learning.
When you submit your homework, you will be required to complete a self-assessment and reflection:
Give yourself an assessment mark on the initial attempt:
✘ if you did not complete it
✓- if you completed it, but were very far from the solution
✓ if you completed it and essentially had the solution
✓+ if you completed it correctly, including precise communication
? if you are unsure as to whether or not you completed it
Provide a short reflection as to why you earned that mark, such as:
I did not understand how to get started, and it was too close to the deadline to visit support hours.
I got stumped by a bug where my program entered an infinite loop.
If you used the solutions to revise your work, describe what you needed to change, as in:
I modified the style of my conditional when I saw a simpler approach in the solutions.
I was so stuck that the majority of my submission is based on the solutions.
Ask specific questions on portions that are still confusing, such as:
Why does it cause an error when I returned "1" instead of 1?
[Optional] Provide one hint for the homework (to your past self or future student).
For this mini project, you will not have solutions to compare with. Please be strategic around how you approach the project and make sure you have time to take breaks and get support!
You'll be implementing a simplified version of Blackjack (one player vs the house and only one round), practicing OOP and the transition to the Java programming languages.
You'll support a single-player interactive version of Blackjack.
There is a design provided below, which will guide you (and allow for automated testing). Since this is a robust project, you should be testing as you go. That being said, you can also use the autograding feature on Gradescope to give you additional testing checkpoints; remember, you can submit to gradescope as many times as you want.
The design relies on 4 classes:
A Card class that represents a single playing card with a suit and rank, which can be face up or face down
A Deck class that starts off with the 52 playing cards and can shuffle/deal cards out of the deck
A Hand class that maintains a hand of cards for the Blackjack game
A BlackjackGame class that contains the main logic for the Blackjack game
You'll notice the design is described "bottom-up" (classes only depend on previously described classes). For each class below, the design is generally described "top-down" (methods depend on methods that are described later). This matches my design process, but if you are careful with your stubs, you can implement in any order!
Here are some sample runs of the game to give you an idea of what you're aiming for:
Sample run 1
Player: [♢A, ♡10], House: [♡Q, 🂠]
(H)it or (S)tand? s
Player: [♢A, ♡10], House: [♡Q, ♧4]
Player: [♢A, ♡10], House: [♡Q, ♧4, ♡K]
The house's hand's a bust!
Congrats, you won!
Sample run 2
Player: [♤4, ♤9], House: [♡3, 🂠]
(H)it or (S)tand? h
Player: [♤4, ♤9, ♡7], House: [♡3, 🂠]
(H)it or (S)tand? s
Player: [♤4, ♤9, ♡7], House: [♡3, ♢K]
Player: [♤4, ♤9, ♡7], House: [♡3, ♢K, ♧9]
The house's hand's a bust!
Congrats, you won!
Sample run 3
Player: [♡Q, ♡9], House: [♧3, 🂠]
(H)it or (S)tand? s
Player: [♡Q, ♡9], House: [♧3, ♢4]
Player: [♡Q, ♡9], House: [♧3, ♢4, ♤A]
Congrats, you won!
Sample run 4
Player: [♤4, ♡8], House: [♢A, 🂠]
(H)it or (S)tand? h
Player: [♤4, ♡8, ♢2], House: [♢A, 🂠]
(H)it or (S)tand? h
Player: [♤4, ♡8, ♢2, ♤3], House: [♢A, 🂠]
(H)it or (S)tand? s
Player: [♤4, ♡8, ♢2, ♤3], House: [♢A, ♤J]
Aww, the house won.
Sample run 5
Player: [♢K, ♡2], House: [♤5, 🂠]
(H)it or (S)tand? h
Player: [♢K, ♡2, ♢2], House: [♤5, 🂠]
(H)it or (S)tand? h
Player: [♢K, ♡2, ♢2, ♧K], House: [♤5, 🂠]
Player: [♢K, ♡2, ♢2, ♧K], House: [♤5, ♢10]
Your hand's a bust...
Aww, the house won.
Refer to the Resources page for sample code and tips around:
lists in Java
user input in Java
testing equality of String values in Java
Develop a little, test a little...
Be thoughtful of your process; you may want to think about the design vs implementation phases
Resist the temptation to write the entire program all at once! Otherwise, the debugging process becomes so much more difficult and time-consuming!
First, create the skeleton of your program files by writing "stubs" (declarations of the classes, instance methods and functions with "placeholder" implementations).
Then implement one part at a time and test as you go.
Remember you have different types of debugging strategies:
Print statements help you peek at memory during program execution.
Tracing your program on paper helps you understand when the execution doesn't match your intended logic.
The Debugger can help you do both!
Be strategic!
Be intentional around your approach to working on the project:
Start early!
Ask questions!
Leave time for questions by... starting early :)
When you're stuck, pause and evaluate what could be going on. Consider the self-regulated learning cycle!
Do you have a plan?
Are you evaluating your plan? How will you test your code as you go?
How will you revise? What will you do when you're confused? Stuck?
Define a class that represents an playing card with a suit and rank that can be flipped over (or not).
The class should be named Card.
There should be a three instance properties:
A String to track the suit; we'll use the unicode characters "♤", "♡", "♢", "♧" for card playing suits (which you can copy/paste from here)
If your terminal doesn't support unicode, use "S", "H", "D", "C"
A String to track the rank "A", "2",... ,or "J", "Q", "K"
A boolean to track if the card is face up showing the suit/rank (true) or face down showing the back with unicode character 🂠 (false)
If your terminal doesn't support unicode, use "?" as the back
There should be a constructor that:
Requires two parameters for the suit and rank
Should initialize the instance properties; the card should start face down
There should be getters for the suit, rank and whether the card is face up (with appropriate return types), named:
getSuit
getRank
isFaceUp
There should be an instance method called getValue that:
Requires no parameters
Has a return type of int
Should return the value of a card
An ace will default to the value 1
Jack, Queen, King are valued at 10
All others are the value of the rank ("2" -> 2, etc.)
There should be an instance method called flip that:
Requires no parameters
Has a return type of void
Should flip the card (face up -> face down; face down -> face up)
There should be an instance method called toString that:
Requires no parameters
Has a return type of String
Should return a String representation of the card.
If the card is face up, return the suit and the rank, as in ♤5
If the card is face down, return the unicode character for the back of a card (copy from here) 🂠
Define a class that represents a deck of 52 cards.
The class should be named Deck.
In order to support automated testing, use the following starting code for the class. This makes it so that we can "seed" how the deck is shuffled to get the same ordering.
Starting code
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
/** Represents a deck of 52 cards. */
public class Deck
{
// class variable (denoted by static) -- for testing purposes!
public static Random shuffler = new Random(); // use this Random object for shuffling
/****** YOUR CODE GOES HERE *******/
/**
* (Instance method to) Shuffle the cards in this deck.
*/
public void shuffle()
{
Collections.shuffle(cards, shuffler);
}
}
Define a class that represents a deck of 52 cards.
There should be a one instance property:
A List<Card> named cards to maintain the Card instances in this deck
There should be a constructor that:
Requires one parameters for whether to shuffle the deck initially (true) or leave it in order (false)
Should initialize the instance property by constructing a new instance of an ArrayList<Card> that is empty
Relies on the helper instance methods:
add52Cards, described below
shuffle, given in the starter code
There should be an instance method called isEmpty that:
Requires no parameters
Has a return type of boolean
Should return true if there are no cards left in the deck (HINT: use the List method isEmpty)
There should be an instance method called add52Cards that:
Requires no parameters
Has a return type of void
Should create 52 Card objects and add them to the deck
HINT: If you're stuck, you can use this sample code to get started. Wondering what it does? Check out this visualization.
// initalize an array with the 4 suits
String[] suits = {"♤","♡","♢","♧"};
// we'll store 13 ranks in an array
String[] ranks = new String[13];
// set the first index to hold the ace
ranks[0] = "A";
// numbers 2 through 10
for (int i = 2; i <= 10; i++ )
ranks[i-1] = Integer.toString( i );
// add the jack, queen and king
ranks[10] = "J";
ranks[11] = "Q";
ranks[12] = "K";
There should be an instance method called dealCard that:
Requires no parameters
Has a return type of Card
Should deal a card by removing it and returning it. (HINT: use the List method remove(0) to remove and return the first card)
There should be an instance method called toString that:
Requires no parameters
Has a return type of String
Should return a String representation of the deck by invoking the List's built-in toString method
Define a class that represents a Blackjack hand.
The class should be named Hand.
There should be a one instance property:
A List<Card> named cards to maintain the Card instances in this deck
There should be a constructor that:
Requires no parameters
Should initialize the instance property by constructing a new instance of an ArrayList<Card> that is empty
There should be an instance method called add that:
Requires one parameter of type Card
Has a return type of void
Should add the card to the hand
There should be an instance method called revealCards that:
Requires no parameters
Has a return type of void
Should reveal all cards by making sure they are all set as face up
Iterate over the list of cards and flip any that are face down
There should be an instance method called busted that:
Requires no parameters
Has a return type of boolean
Should check if the hand is busted -- return true if it has a value of more than 21.
Relies on the helper instance method:
determineValue, described below
There should be an instance method called determineValue that:
Requires no parameters
Has a return type of int
Should determine the best (Blackjack) value of the hand
If there is an ace and treating it as an 11 keeps the sum <= 21 (inclusive), returns that value.
Otherwise, treats the ace as a 1.
Relies on the helper instance method:
containsRank, described below
There should be an instance method called containsRank that:
Requires a single parameter of type String
Has a return type of boolean
Should checks if this hand has a card with the given rank and returns true if so.
There should be an instance method called toString that:
Requires no parameters
Has a return type of String
Should return a String representation of the deck by invoking the List's built-in toString method
Define a class that implements the game of Blackjack, supporting one player versus the house.
The class should be named BlackjackGame.
There should be a three instance properties:
A Deck instance to maintain the deck of cards
A Hand instance to maintain the house's hand
A Hand instance to maintain the player's hand
There should be a constructor that:
Requires no parameters
Should initialize the instance properties by constructing new instances of the appropriate class for each
There should be an instance method called playGame that:
Requires no parameters
Has a return type of void
Should play the game, printing the status along the way
Relies on the helper instance methods described below:
toString to print the current state of the game
deal to deal out initial cards
playerTurn to prompt the user hitting/standing
houseTurn to have the house hit if required
determineOutcome to end the game (determining the outcome and printing results)
There should be an instance method called deal that:
Requires no parameters
Has a return type of void
Should start the game by dealing out the cards
deal one card to the player, face up
deal one card to the house, face up
deal one card to the player, face up
deal one card to the house, face down
Relies on the helper instance method described below:
dealCardTo to deal a card to a particular hand
There should be an instance method called dealCardTo that:
Requires two parameters
A Hand instance for the hand to deal into
A boolean for whether the card should be face up (true) or down (false)
Has a return type of void
Should deal a card from the deck to the given hand. If faceUp is true, flip the card so it's face up.
There should be an instance method called playerTurn that:
Requires no parameters
Has a return type of void
Should have the player take their turn. This should:
Use a Scanner to receive input (refer to Resources for sample code)
While the player hasn't busted
Prompt them to hit or stand by entering "H"/"h" or "S"/"s"
If they hit, deal them a card with the instance method dealCardTo
There should be an instance method called houseTurn that:
Requires no parameters
Has a return type of void
Should execute the house's turn.
While the house's hand is valued < 17, deal a card with the instance method dealCardTo and print the current state of the game using toString
There should be an instance method called determineOutcome that:
Requires no parameters
Has a return type of int
Should determine the outcome of the game: -1 if the player loses, 0 if there is a tie, 1 if the player wins
If the player busted, print out the following and return -1
Your hand's a bust...
Aww, the house won.
If the house busted, print out the following and return 1
The house's hand's a bust!
Congrats, you won!
If it's a tie, print out the following and return 0
Tie!
If neither hand is a bust and the player is closer to 21, print out the following and return 1
Congrats, you won!
If neither hand is a bust and the house is closer to 21, print out the following and return -1
Aww, the house won.
There should be an instance method called toString that:
Requires no parameters
Has a return type of String
Should return a String representation of the current state of the game, as in:
Player: [♤7, ♢8], House: [♧10, 🂠]