Question

Laboratory 4: Black Jack! Java API ArrayList Lab 04 Documentation Included matrix package "external" documentation Included...

Laboratory 4: Black Jack!
Java API ArrayList Lab 04 Documentation Included matrix package "external" documentation Included
Download Lab04.zip for all of the additional supporting files that you will need to compile and run. Extract the files into your working directory
You can find the rules of blackjack all over the Internet. To get an idea of what you are trying to accomplish in this lab, I’ll demonstrate the final solution. The dealer stands on all 17s. Doubling after splitting is always allowed. Multiple splitting is always allowed.
The yellow highlighting in BlackJack represents the optimal decision given your cards and the dealer's up card. Refer to the table below for the complete optimal strategy for blackjack. Across is the dealer's up card (T means a 10 or any face card). Down is your hand value. The table entries are as follows:
• S = Stand
• H = Hit
• D = Double Down
• P = Split The A/ table entries represent soft hands of two or more cards (where one card is an ace). Splitting is only relevant at the bottom of the table where the possible duplicate card values are listed.
The row value listed next to the hand total indicates the row in the strategy array (see BlackJackPlayer) where the desired move for the corresponding hand total can be found. After the row has been determined by the hand total, simply go to the column corresponding to the dealer's up card. Note: the hand totals begin with 2 (two aces, row 0) and go up to 21 (row 19).
Dealer's Up Card
2
3
4
5
6
7
8
9
T
A
<= 8 (row 0 - 6)
H
H
H
H
H
H
H
H
H
H
9 (row 7)
H
D
D
D
D
H
H
H
H
H
10 (row 8)
D
D
D
D
D
D
D
D
H
H
11 (row 9)
D
D
D
D
D
D
D
D
D
H
12 (row 10)
H
H
S
S
S
H
H
H
H
H
13 (row 11)
S
S
S
S
S
H
H
H
H
H
14 (row 12)
S
S
S
S
S
H
H
H
H
H
15 (row 13)
S
S
S
S
S
H
H
H
H
H
16 (row 14)
S
S
S
S
S
H
H
H
H
H
>= 17 (row 15 - 19)
S
S
S
S
S
S
S
S
S
S
A/2 (row 20)
H
H
H
D
D
H
H
H
H
H
A/3 (row 21)
H
H
H
D
D
H
H
H
H
H
A/4 (row 22)
H
H
D
D
D
H
H
H
H
H
A/5 (row 23)
H
H
D
D
D
H
H
H
H
H
A/6 (row 24)
H
D
D
D
D
H
H
H
H
H
A/7 (row 25)
S
D
D
D
D
S
S
H
H
H
A/8 (row 26)
S
S
S
S
S
S
S
S
S
S
A/9 (row 27)
S
S
S
S
S
S
S
S
S
S
A/10 (row 28)
S
S
S
S
S
S
S
S
S
S
2/2 (row 29)
P
P
P
P
P
P
H
H
H
H
3/3 (row 30)
P
P
P
P
P
P
H
H
H
H
4/4 (row 31)
H
H
H
P
P
H
H
H
H
H
5/5 (row 32)
D
D
D
D
D
D
D
D
H
H
6/6 (row 33)
H
P
P
P
P
H
H
H
H
H
7/7 (row 34)
P
P
P
P
P
P
H
H
H
H
8/8 (row 35)
P
P
P
P
P
P
P
P
P
P
9/9 (row 36)
P
P
P
P
P
S
P
P
S
S
10/10 (row 37)
S
S
S
S
S
S
S
S
S
S
A/A (row 38)
P
P
P
P
P
P
P
P
P
P
Lab:
• Randomizing Object Arrays (Shuffling)
• For-Each Statement
• Object Arrays as Parameters/Return Values
• ArrayList (Using Generics)
• Primitive Arrays
Part I: Decks of Cards
For this part and the subsequent parts of this lab, refer both to the instructions below and the instructions given in the .java files.
Download the Card class (it's in the zip file). Although not necessary for this lab, the compareTo method for the Card class will compare by face value first, then by suit. A sorted Deck of Cards will have all the Aces first in the order Spades, Hearts, Clubs, Diamonds. Then the 2s in the same suit order, and so forth.
Complete the constructor in the Decks class. Create the requested number of standard 52 card decks (check user input). You will need to use a nested for loop. After you have all the required Cards, shuffle all of the of Cards together.
Complete the shuffle method in the Decks class. Use the Permutation class, which requires the Random class. After all of the Cards are shuffled, reset count so that all of the Cards in the Decks are again available.
Look at the deal method (the code for this method has been given to you). The deal method uses the count instance variable to return the next Card in the Decks. After a Card has been selected from the Decks, count is decremented in preparation for the next call to deal. If there are no more Cards left to deal, shuffle is called to reset the Decks.
Part II: BlackJackHand
Complete the BlackJackHand class. A BlackJackHand object holds a minimum of two Cards, but the maximum number that the hand will hold is not known. Thus, it is convenient to use an ArrayList to hold the Cards in the BlackJackHand. Make your ArrayList able to hold only Card objects. The constructor will accept two Cards, which are placed in the ArrayList. You must also determine whether the hand is a soft hand or not. Simply determine if one of the two Cards is an Ace, in which case the hand is soft. In addition to the constructor, complete the following methods:
• public void drawDealerHand(Graphics g, int x, int y, boolean done)
o Draws this BlackJackHand (a player hand) to the screen.
• private int[] sum()
o Helper method to computes the value of this BlackJackHand.
o Two values are determined (can be computed simultaneously).
o The first total is obtained with all aces being counted as 1.
o The second total is obtained with one ace being counted as 11, if there is at least one ace.
o Both totals are returned in an integer array!
o This is to help the calling method (see the next method) to determine if this BlackJackHand is soft or not.
• public int handValue()
o Computes the value of this BlackJackHand.
o Determines whether this BlackJackHand is soft or not using both totals returned from the helper sum method.
o If the second total is less than 21 but the second total and the first total are the same,
o either total is used and this BlackJackHand is not soft.
o Otherwise, the second total is used and this BlackJackHand is soft.
o If the second total is greater than 21, the first total is used and this BlackJackHand is not soft.
o Remember to set soft to true if the hand is soft.
• public void hit(Card card)
o Hits this BlackJackHand by adding the Card passed in
o to the ArrayList storing the Cards in this BlackJackHand.
o This method should be very short.
• public boolean canSplit()
o This method determines whether the BlackJackHand can be split or not.
o In order qualify for a possible split, the BlackJackHand can only have two Cards, and they must have the same value.
o This means that any two cards with value 10 can be split, i.e. a King and a Queen can be split.
• public BlackJackHand[] split(Card card1, Card card2)
o If the BlackJackHand can be split, this method will split the BlackJackHand.
o The two Cards in the current BlackJackHand become one Card each for two new BlackJackHands.
o The next two Cards for the two new BlackJackHands are passed in as parameters.
o You will need to create new BlackJackHands.
Part III: BlackJackPlayer
Complete the BlackJackPlayer class. The BlackJackPlayer class holds all of the player's hands. Like the number of cards in a BlackJackHand, the maximum number of hands that the player will have is not known (due to splitting). BlackJackPlayer keeps track (through the index instance variable) of which hand the player is currently playing. The BlackJackPlayer class also has-a BlackJackStrategy which must be instantiated in the constructor. Complete the following methods:
• public void draw(Graphics g, int width, int height)
• public void split(Card card1, Card card2)
o The player wants to split.
o You need to remove the hand that is being split from the ArrayList.
o Create two new hands and insert them into the appropriate place in the ArrayList.
• public void doubleDown(Card dealt)
o call a method located in BlackJackHand
• public int result(BlackJackHand dealer)
Part IV: BlackJackStrategy
Complete the BlackJackStrategy class to obtain the desired move given a player's hand total and the dealer's up card. The desired strategy is read in from a text file and stored in a matrix (BasicMatrixInterface, done for you). Use the row and column information provided above to determine the optimal strategy. Your result will be highlighted in yellow when the game is running. The user is not required to use the optimal strategy, however. Assume a BlackJackHand method isSoft() is available, which you will write in the next part. Note the following convention when reading from the text file:
• 1 = Stand
• 2 = Hit
• 3 = Double
• 4 = Split
Complete the following methods within BlackJackStrategy:
• public char getMove(BlackJackHand player, BlackJackHand dealer)
o Extracts the desired move (excluding splits) from the strategy array for hard and soft hands.
o Use the hand value to make it easier to identify the necessary row from the strategy array.
o Returns a 'S' if the correct play is to stand.
o Returns an 'H' if the correct play is to hit.
o Returns a 'D' if the correct play is to double.
o Hint: if the player's hand is soft, you need to add 7 to the player's hand value to get the row for the correct play, otherwise 2 should be subtracted from the hand value.
o Hint: if the dealer's up card is an Ace (which has the value of 1) you need to extract the correct play from column 9, otherwise a 2 should be subtracted from the up-card value.
o Note: the game will interpret a 'D' as an 'H' if the hand cannot be doubled.
o This class only has the responsibility of reading from the matrix.
• public boolean shouldSplit(BlackJackHand player, BlackJackHand dealer)
o Determines if a split is the desired move if the first two cards in a hand have the same value.
o Use the (modified) hand value to make it easier to identify the necessary row from the strategy matrix.
o Returns a false if a split is not the correct play or true if a split is the correct play according to the strategy.
o Hint: if the player's hand is soft, you need to extract the correct play from row 38, otherwise 27 should be added to the face value.
o Hint: if the dealer's up card is an Ace (which has the value of 1) you need to extract the correct play from column 9, otherwise a 2 should be subtracted from the up-card value.
Only one submission per team is necessary, but please make sure to include both names at the top of your source code, as well as in the comments section when submitting the lab, so both people can get credit.

Homework Answers

Answer #1

ActionValidator.java

package main;
/* Action validator - makes sure player's action is a valid action
*/

import java.util.ArrayList;

public class ActionValidator {

public static String ACTION_HIT = "hit";
public static String ACTION_STAND = "stand";
private ArrayList<String> actions;
/**
* Constructor
*/
public ActionValidator() {
this.actions = new ArrayList<>();
this.actions.add(ACTION_HIT);
this.actions.add(ACTION_STAND);
}

/**
* Ensures given action is valid action
* @param action Action in String format
* @return true/false depending on whether action is valid or invalid, respectively
*/
public boolean isValid(String action) {
return this.actions.contains(action);
}
}

CardValidator.java

package main;
/* elements.Card validator - checks for valid cards
*/

import elements.Card;

import java.util.ArrayList;

public class CardValidator {

private ArrayList<String> indexes;
private ArrayList<String> suits;

public CardValidator() {
// list initialisation
indexes = new ArrayList<>();
suits = new ArrayList<>();
// valid card indexes
this.indexes.add("2");
this.indexes.add("3");
this.indexes.add("4");
this.indexes.add("5");
this.indexes.add("6");
this.indexes.add("7");
this.indexes.add("8");
this.indexes.add("9");
this.indexes.add("T");
this.indexes.add("J");
this.indexes.add("Q");
this.indexes.add("K");
this.indexes.add("A");

// valid card suits
this.suits.add("d");
this.suits.add("c");
this.suits.add("h");
this.suits.add("s");
}

public int isCardValid(Card card) {
if ( this.indexes.contains( card.getId() ) ) {
if ( this.suits.contains( card.getSuit() ) ) {
// card is valid
return 1;
}
}

// didn't pass the above checks, therefore card is invalid
return 0;
}

}

Game.java

package main;
/* elements.Card validator - checks for valid cards
*/

import elements.Card;

import java.util.ArrayList;

public class CardValidator {

private ArrayList<String> indexes;
private ArrayList<String> suits;

public CardValidator() {
// list initialisation
indexes = new ArrayList<>();
suits = new ArrayList<>();
// valid card indexes
this.indexes.add("2");
this.indexes.add("3");
this.indexes.add("4");
this.indexes.add("5");
this.indexes.add("6");
this.indexes.add("7");
this.indexes.add("8");
this.indexes.add("9");
this.indexes.add("T");
this.indexes.add("J");
this.indexes.add("Q");
this.indexes.add("K");
this.indexes.add("A");

// valid card suits
this.suits.add("d");
this.suits.add("c");
this.suits.add("h");
this.suits.add("s");
}

public int isCardValid(Card card) {
if ( this.indexes.contains( card.getId() ) ) {
if ( this.suits.contains( card.getSuit() ) ) {
// card is valid
return 1;
}
}

// didn't pass the above checks, therefore card is invalid
return 0;
}

}

RewardCalculator.java

package main;
/* Reward calculator - calculates winnings of a player
*/

import participants.Dealer;
import participants.GamePlayer;
import participants.Player;

import java.util.ArrayList;

public class RewardCalculator {

/**
* Empty constructor
*/
public RewardCalculator() {

}

/**
* Calculates a multiplier by which player's stake should be multiplied
* to give total reward value ('stake' x 'multiplier')
* @param score Player's hand score
* @return Stake multiplier
*/
public Float calculate(Integer score) {
if (score.equals(ScoreCalculator.blackJack)) {
return 2.5f;
} else {
return 2.0f;
}
}

public void processWinnings(Dealer dealer, ArrayList<Player> players) {
if (dealer.getState().equals(GamePlayer.STATE_GAME_BUST)) {
for (Player p : players) {
if (!p.getState().equals(GamePlayer.STATE_GAME_BUST)) {
Float multiplier = this.calculate(p.getScore());
Float winnings = p.getStake() * multiplier;
System.out.println(p.getName() + " wins: " + winnings);
p.updateBalance(winnings);
} else {
System.out.println(p.getName() + " loses: " + p.getStake());
}
}
} else {
for (Player p : players) {
if (p.getState().equals(GamePlayer.STATE_GAME_BUST)) {
// loses
System.out.println(p.getName() + " loses: " + p.getStake());
} else {
if (p.getScore() > dealer.getScore()) {
// wins
Float multiplier = this.calculate(p.getScore());
Float winnings = p.getStake() * multiplier;
System.out.println(p.getName() + " wins: " + winnings);
p.updateBalance(winnings);
} else if (p.getScore() < dealer.getScore()) {
// loses
System.out.println(p.getName() + " loses: " + p.getStake());
} else {
// draw (pay back the stake)
// also, technically a win
System.out.println(p.getName() + " wins: " + p.getStake());
p.updateBalance(p.getStake());
}
}
}
}
}
}

ScoreCalculator.java

package main;
/* elements.Card score calculator
*/

import elements.Card;

import java.util.ArrayList;
import java.util.HashMap;

public class ScoreCalculator {

// Format: key = 'card index', value = 'card value'
private static HashMap<String, Integer> values;
public static Integer blackJack = 50;

public ScoreCalculator() {
// initialise hashmap for 'values'
values = new HashMap<>();
// initialise card values
values.put("2", 2);
values.put("3", 3);
values.put("4", 4);
values.put("5", 5);
values.put("6", 6);
values.put("7", 7);
values.put("8", 8);
values.put("9", 9);
values.put("T", 10);
values.put("J", 10);
values.put("Q", 10);
values.put("K", 10);
values.put("A", 11);
}

public Integer getCardValue(Card card) {
return values.get(card.getId());
}

public Integer getHandValue(ArrayList<Card> hand) {
Integer score = 0;
int num_aces = 0;
for (Card c : hand) {
// special case for card 'Ace'
if (c.getId().equals("A")) {
num_aces++;
} else {
score += values.get(c.getId());
}
}

// add values of 'aces'
for (int i = 0; i < num_aces; i++) {
if (score + values.get("A") > 21) {
score += 1;
} else {
score += values.get("A");
}
}

// detect a blackjack (2 cards, total value = 21)
if (hand.size() == 2 && score == 21) {
score = blackJack;
}

return score;
}
}

main.java

package main;

import participants.Player;

import java.util.Scanner;

public class main {

public static void main (String[] args) {
ActionValidator actionValidator = new ActionValidator();
RewardCalculator rewards = new RewardCalculator();
Scanner scanner = new Scanner(System.in);

/*while (true) {
System.out.println("=== Enter a card ===");
elements.Card c = new elements.Card(scanner.nextLine());
int validResult = validator.isCardValid(c);
if (validResult == 1) {
System.out.println("Your card is: " + c.getId() + c.getSuit());
System.out.println("Validation result: valid");
} else {
System.out.println("Your card is: " + c.getId() + c.getSuit());
System.out.println("Validation result: invalid");
}
}*/

Game game = new Game();
Player p = new Player("Vaidas", 5000f);
game.addPlayer(p);
while (true) {
System.out.println("\n************************************************\n");
System.out.println("Your current balance is: " + p.getBalance());
System.out.println("*** Enter your stake ***");
float stake = scanner.nextFloat();
// prevent stake being bigger than player's balance
while (stake > p.getBalance()) {
stake = scanner.nextFloat();
}
System.out.println("Stake: " + stake);
p.setStake(stake);

game.startGame();
game.printHands();
System.out.println(p.getAction().get());

while(!p.getAction().get().equals(ActionValidator.ACTION_STAND)) {
System.out.println("*** Choose your action ***");
System.out.println("*** [hit, stand] ***");

String action = "none";
while (!actionValidator.isValid(action)) {
action = scanner.nextLine();
}
p.getAction().set(action);
System.out.println("Your action: " + p.getAction().get());

if (p.getAction().get().equals(ActionValidator.ACTION_HIT)) {
game.dealCardToPlayer();
}
}

while(!game.getDealer().getAction().get().equals(ActionValidator.ACTION_STAND)) {
game.dealerAction();
}

rewards.processWinnings(game.getDealer(), game.getPlayers());
}
}
}

Know the answer?
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for?
Ask your own homework help question
Similar Questions
Using Java, please implement the Poker and PokerHand classes to provide the expected output using the...
Using Java, please implement the Poker and PokerHand classes to provide the expected output using the CardDemo class. Rules are the following: - Deck and PockerHand should be Iterable (note that you may just reuse one of the underlying iterators to provide this functionality) - Poker should implement 2 methods checking for two possible poker hands , see the comments inside the classes for details. Hint: remember how one can count the frequency of words in text? - whenever you...
Hi, I'm writing a Java program that prints a grid with circles and squares that have...
Hi, I'm writing a Java program that prints a grid with circles and squares that have letters in them and it is also supposed to print the toString() function to the console window each time the application runs. This toString() function is supposed to show the tile's shape, letter, and color component (or components). Could someone please review and debug my code to help me figure out why my toString() function is not working? import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JButton;...
Complete a Java program named ARMgr that maintains customer accounts receivable in a database. The code...
Complete a Java program named ARMgr that maintains customer accounts receivable in a database. The code to initialize the CustomerAccountsDB database table and add a set of customer accounts is provided. Finish the code in these 3 methods in CustomerAccountDB.java to update or query the database: -purchase(double amountOfPurchase) -payment(double amountOfPayment) -getCustomerName() Hint: For getCustomerName(), look at the getAccountBalance() method to see an example of querying data from the database. For the purchase() and payment() methods, look at the addCustomerAccount() method...
In Chapter 9, you created a Contestant class for the Greenville Idol competition. The class includes...
In Chapter 9, you created a Contestant class for the Greenville Idol competition. The class includes a contestant’s name, talent code, and talent description. The competition has become so popular that separate contests with differing entry fees have been established for children, teenagers, and adults. Modify the Contestant class to contain a field that holds the entry fee for each category, and add get and set accessors. Extend the Contestant class to create three subclasses: ChildContestant, TeenContestant, and AdultContestant. Child...
What tools could AA leaders have used to increase their awareness of internal and external issues?...
What tools could AA leaders have used to increase their awareness of internal and external issues? ???ALASKA AIRLINES: NAVIGATING CHANGE In the autumn of 2007, Alaska Airlines executives adjourned at the end of a long and stressful day in the midst of a multi-day strategic planning session. Most headed outside to relax, unwind and enjoy a bonfire on the shore of Semiahmoo Spit, outside the meeting venue in Blaine, a seaport town in northwest Washington state. Meanwhile, several members of...
ADVERTISEMENT
Need Online Homework Help?

Get Answers For Free
Most questions answered within 1 hours.

Ask a Question
ADVERTISEMENT