The purpose of this assignment is to practice using ArrayLists and Interfaces. The specific goals are to:
Blackjack is a popular card game, common as a table game at casinos. The goal of blackjack is to draw cards, scoring as close to 21 points without going over.
Blackjack uses a standard deck of 52 cards, with 4 possible suits, Hearts, Diamonds, Clubs, and Spades, and 13 possible values. These are shown in the image below.
Each card has a "score". All the cards in a hand are added up in hopes of reaching 21 without going over.
In blackjack, a player plays against a dealer, or "house". Often the dealer plays on behalf of a managing casino. If a player's hand is closer to 21 than the dealer without going over, the player wins. If the player goes over 21, or is further from 21 than the house, they lose. In the case both the player and the house have the same score under or equal to 21, it's called a "push", or a tie.
The best situation for the player is to get dealt an Ace and a card worth 10 points. If this happens, the player already has 21 points with two cards, and automatically wins (even if the dealer also has 21). This hand is called a blackjack.
In most cases of blackjack, both the player and the dealer start with 2 cards in their hand, with the player having both cards face up, so their value and suit is visible, while the dealer shows only one card face up, and the other "hidden" face down. The player then decides to "hit" (draw another card to add to their hand) or "stand" (draw no more cards and end their turn. Once you stand, you can no longer draw any cards. However, if you "hit", and your total goes over 21, you lose automatically, and the dealer never has to take their turn, winning automatically.
In blackjack the player must always play their turn before the dealer. This means the decision for the player to "hit" is based on the risk of going over 21. If a player has a 17, for example, it is unlikely they should "hit", as there is roughly a 10/13 chance that the player will "bust" (go over 21). Likewise, if you have a total score of 5, you absolutely should hit, since it's almost certain the dealer will have a higher score just with two cards alone. That is, unless you like to live dangerously.
Because the dealer always goes after the player, the "house" (or casino) has a slight advantage, winning about 5% more often than the player. Hey, gambling is a business.
In this assignment, you will write a Card
, Hand
, and Deck
class. Each class implements an interface, HW8Card
, HW8Hand
and HW8Deck
respectively. You will implement all of the methods in the interfaces in their respective class files.
hw8.zip
and
decompress it into your folder for this homework
assignment. This zip file contains the three files you will edit, as well
as three interfaces (HW8Card
, HW8Hand
, and HW8Deck
) and
Blackjack.java
, which executes a game of blackjack using the code you will write.
HW8Card
, HW8Hand
, HW8Deck
, or Blackjack.java
at all.HW8Card
, HW8Hand
, and HW8Deck
are Blackjack.java
is the "Main" class in this program, which uses the other files (including yours) to run a Blackjack program. This
file will only work when you complete the homework and you can run the file to simulate a blackjack game.Card
ClassIn this section, you will write a new java file, Card.java
,
implementing HW8Card
.
HW8Card
interfacehw8.zip
contains
the HW8Card
interface that represents a standard card from a deck of 52. The API is
as follows:
public interface HW8Card ------------------------------------------------------------------------------------------------------ String getSuit() // return the suit of the card (i.e. "Hearts", "Spades", etc.) String getValue() // return the value of the card (i.e. "2", "10", "J", "A" int getBlackjackScore() // returns the blackjack score of a card. Number cards are worth // their number. Face cards worth 10. Aces worth 1 (not 11) boolean isAce() // return true if card is ace, false otherwise. boolean equals(Object o) // return true if this and o is a Card and both the calling instance // and o have the same Suit and Value. String toString() // Prints card as a string (i.e. "A of Spades", "2 of Diamonds")
Card
classYou are given method stubs for all the above methods. Implement these by determining what fields you need and then writing the methods.
In addition, you must write a constructor that takes in a value and a suit.
IllegalArgumentException
with a useful error message.IllegalArgumentException
with a useful error message. It is vital that your toString()
method be correct. This means a two of hearts should print, exactly:
2 of Hearts
Remember that an Ace is "A", so for an ace of clubs, you should print.
A of Clubs
The same is true of other "face" cards, so Jack, Queen, and King should be J, Q, and K, respectively.
Hand
ClassImplement the HW8Hand
class by writing Hand.java
The hand class will have a single field, an ArrayList<HW8Card>
that contains
the cards in the hand. Remember that because Card
implements the HW8Card
interface, every instance of Card
is an
instance of a HW8Card
. Thus, we can fill an ArrayList
of HW8Card
s with Card
s
Required Methods:
public interface HW8Hand ------------------------------------------------------------------------------------------------------ void addCard(HW8Card card) // Adds a card object to the hand int getHardScore() // Gets the blackjack score of the hand with all aces treated as 1 point int getSoftScore() // Gets the blackjack score of the hand with the FIRST ace treated as 11. // (If there are no aces, gives same result as getHardScore int getScore() // Returns the best score possible for the hand (between Soft and Hard score) boolean isBust() // Returns true if all possible scores are greater than 21 int getNumCards() // Return the number of cards in the hand HW8Card getDealerShowing() // Return the SECOND (index 1) card in the hand. String toString() // Prints the hand (see below for details)
The hand should have a zero-argument constructor that initializes the instance's ArrayList
.
To add a card, use the List
function add(E e)
, where E
is
the type HW8Card
.
For the scoring functions, consider the hand "Ace of Hearts, Ace of Diamonds, 9 of Hearts". The hard score of this hand is 1 + 1 + 9, or 11, since every Ace is treated as worth 1 point. The soft score is 21, since the first ace is treated as 11, so 11 + 1 + 9. This means the overall score of the hand is 21.
By contrast, consider a hand of three kings. Here, both the hard and the soft score are 30, since there is
no Ace, meaning the overall score is 30. Since every score is greater than 21, this hand is
Don't overthink getDealerShowing()
. Both player and dealer hands are represented with the
HW8Hand
. This method should simply use the List get(int i)
method to return the second
card in the hand (that is, the card at index 1). Don't worry about "proving" the hand belongs to a dealer. Just
simply return the second card. The game handles this function correctly.
Finally, make sure the toString() method works. This method is used in our grading tests. For example, assume the hand in the picture above (with the cards indexed from left to right) should print exactly: "2 of Spades, 5 of Spades, 2 of Hearts, 7 of Hearts". Note the comma followed by the single space between every card. Also note that there is no comma or whitespace after the last card.
Deck
classImplement the HW8Deck
class in a file called Deck.java
The deck class, like hand, will have a single field, an ArrayList<HW8Card>
that contains
the cards in the Deck. Remember that because Card
implements the HW8Card
interface, every instance of Card
is an
instance of a HW8Card
. Thus, we can fill an ArrayList
of HW8Card
s with Card
s.
Required Methods:
public interface HW8Deck ------------------------------------------------------------------------------------------------------ void resetDeck() // Resets the deck of cards to an initial state of 52 Cards. These cards // should NOT be shuffled. void shuffle() // randomizes the order of the cards in the deck. HW8Card drawCard() // Remove the first card from the deck and return it. Throw an IllegalStateException // if the deck is empty (has zero cards left). String toString // Returns a string of the form "Deck has [x] cards"
resetDeck
should reset the deck back to a starting state (as though you just opened a fresh pack of 52 cards). This means
you will have one card for each value of each suit. Example, 2 of Spades, 2 of Hearts, 2 of Clubs, 2 of Diamonds, 3 of Spades,
3 of Hearts, 3 of Clubs, 3 of Diamonds, etc. For all values 2-10, J, Q, K, and A. Do not write 52 lines of code. Find
a systematic way to do this. Write resetDeck() before writing and testing any other methods
The constructor of deck should have zero arguments, and should both initialize the ArrayList
of cards
and fill the deck with 52 standard cards. Do not write duplicate code from resetDeck
. Use the method resetDeck
in
the constructor.
For the shuffle
method, use the static function Collections.shuffle(List l)
. This function randomizes the order of elements in
a list in place, and returns nothing.
For drawCard
, consider the functions we went over in class related to the List
interface and use the correct one to draw one card from the top of the deck.
After you draw
a card, the number of cards in the deck should decrease by 1. If there are no cards to draw, throw an IllegalStateException
The toString
must return a string containing the number of cards in the deck.
DO NOT return a string containing the String representations of all the cards in the deck. Simply say the size of the deck.
Before submitting, run Blackjack.java
. This is a fully functional Blackjack game. All commands are entered with "y/n" (y for yes, n for no).
Complete readme_blackjack.txt
in the same way that you have done for previous assignments.
Submit Card.java
, Hand.java
, Deck.java
and
readme_blackjack.txt
on the course website.
Do not submit your Blackjack.java, HW8Card.java, HW8Hand.java, or HW8Deck.java files.