Add Blackjack/java outline with TODO placeholders

This commit is contained in:
Dave Burke
2022-01-25 21:16:26 -06:00
parent 080d6ccee4
commit ff2859e0d0
3 changed files with 161 additions and 35 deletions

View File

@@ -1,8 +1,7 @@
import static java.util.stream.Collectors.joining;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class Blackjack {
public static void main(String[] args) {
@@ -28,15 +27,14 @@ public class Blackjack {
nPlayers = promptInt("NUMBER OF PLAYERS");
}
Deck deck = new Deck(4); // TODO figure out how many decks the BASIC version uses
System.out.println("RESHUFFLING");
LinkedList<Card> deck = new LinkedList<>();
for(Card.Suit suit : Card.Suit.values()) {
for(int value = 1; value < 14; value++) {
deck.add(new Card(value, suit));
}
}
Collections.shuffle(deck);
deck.shuffle();
List<Player> players = new ArrayList<>();
// TODO instantiate Player instances and update below to set their current bets. Finish TODOs in Player.java first.
while(true) { // TODO is there a w
int[] bets = new int[nPlayers]; // empty array initialized with all '0' valuses.
while(!betsAreValid(bets)){
System.out.println("BETS:");
@@ -47,25 +45,101 @@ public class Blackjack {
}
}
printInitialDeal();
for(Player player : players){
// TODO deal two cards to each player from the deck.
}
// Consider adding a Dealer class to track the dealer's hand and running total.
LinkedList<Card> dealerHand = new LinkedList<>();
// TODO deal two cards to the dealer
// TODO handle 'insurance' if the dealer's card is an Ace.
for(Player player : players){
play(player, deck);
}
// only play the dealer if at least one player has not busted or gotten a natural blackjack (21 in the first two cards)
// otherwise, just print the dealer's concealed card
dealerHand = playDealer(dealerHand, deck);
evaluateRound(players, dealerHand);
}
}
private static void printInitialDeal() {
// TODO implement printInitialDeal()
// Print the initial deal in the following format:
/*
Note that LinkedList is a Deque: https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html
Player
CurrentBet
Total
Hand
Hand
cards LinkedList<Card>
evaluate() // see 300 in blackjack.bas for eval subroutine logic
Deck // note the game is played with more than one deck
cards LinkedList<Card> // instantiate cards and randomize in constructor via Collections.shuffle()
List<Hand> dealHands(n)
discardPile Queue<Card>
Card
Value
Suit
PLAYER 1 2 DEALER
7 10 4
2 A
*/
}
/**
* Plays the players turn. Prompts the user to hit (H), stay (S), or if
* appropriate, split (/) or double down (D), and then performs those
* actions. On a hit, prints "RECEIVED A [x] HIT? "
*
* @param player
* @param deck
*/
private static void play(Player player, Deck deck) {
// TODO implement play(player, deck)
// If the player hits, deal another card. If the player stays, return. If the player busts, return.
// delegate to evaluateHand(hand) to determine whether the player busted.
// Use promptBoolean and promptInt as examples to start with for prompting actions
// initially prompt with "PLAYER [x] ?" where x is the player number and accept H, S, D, or /
// after hitting, prompt "RECEIVED A [c] HIT? " where c is the card received and only accept H or S
// handle splitting and doubling down, or feel free to skip implementing
// split/double down for now, but leave a todo if that is unfinished
// after the first pass.
}
private static int evaluateHand(LinkedList<Card> hand){
// TODO implement evaluateHand
// 'int' is maybe the wrong return type. We need to indicate a bust and somehow communicate the ambiguity of aces.
// OR maybe we stick with 'int' and use -1 for a bust and otherwise determine the value of aces that gives the highest non-bust score.
// but note that we also need a distinction between a natural Blackjack (21 in only 2 cards) and a 21 with more than 2 cards (the natural blackjack wins)
return 0;
}
/**
* Play the dealer's hand. The dealer draws until they have >=17 or busts. Prints each draw as in the following example:
*
* DEALER HAS A 5 CONCEALED FOR A TOTAL OF 11
* DRAWS 10 ---TOTAL IS 21
*
* TODO find out if the dealer draws on a "soft" 17 (17 using an ace as 11) or not in the original basic code.
*
* @param dealerHand
* @return
*/
private static LinkedList<Card> playDealer(LinkedList<Card> dealerHand, Deck deck) {
// TODO implement playDealer
return null;
}
/**
* Evaluates the result of the round, prints the results, and updates player/dealer totals.
* @param players
* @param dealerHand
*/
private static void evaluateRound(List<Player> players, LinkedList<Card> dealerHand) {
// TODO implement evaluateRound
// print something like:
/*
PLAYER 1 LOSES 100 TOTAL=-100
PLAYER 2 WINS 150 TOTAL= 150
DEALER'S TOTAL= 200
*/
// this should probably take in a "Dealer" instance instead of just the dealer hand so we can update the dealer's total.
// remember to handle a "PUSH" when the dealer ties and the bet is returned.
}
/**
* Prompts the user for a "Yes" or "No" answer.
* @param prompt The prompt to display to the user on STDOUT.

View File

@@ -0,0 +1,40 @@
import java.util.LinkedList;
public class Deck {
LinkedList<Card> cards;
/**
* Initialize the game deck with the given number of standard decks.
* e.g. if you want to play with 2 decks, then {@code new Decks(2)} will
* initialize 'cards' with 2 copies of a standard 52 card deck.
*
* @param nDecks
*/
public Deck(int nDecks) {
// TODO implement Deck constructor
// See line 33 of Blackjack.java for the current version of this code
/* for each suit
* for each value 1-13
* add new Card(value, suit) to cards
*/
}
/**
* Deals one card from the deck, removing it from this object's state.
* @return The card that was dealt.
*/
public Card deal() {
// TODO implement Deck.deal()
return null;
}
/**
* Shuffle the cards in this deck.
*/
public void shuffle() {
// TODO implement Deck.shuffle()
// Probably just call Collections.shuffle(cards);
}
}

View File

@@ -2,9 +2,15 @@ import java.util.LinkedList;
public class Player {
// TODO add 'playerNumber' property. e.g. playerNumber = 1 means "this is Player 1"
private int currentBet;
private int total;
private LinkedList<Card> hand;
// TODO we'll need to decide how to deal with a split hand or doubled down bet.
public Player() {
// TODO initilize 'total' to zero and 'hand' to an empty List
}
public void setCurrentBet(int currentBet) {
this.currentBet = currentBet;
@@ -14,6 +20,9 @@ public class Player {
return this.currentBet;
}
// TODO replace Player.setTotal with recordWin and recordLoss
// recordWin adds 'currentBet' to 'total' and then sets 'currentBet' to zero
// recordLoss subtracts 'currentBet' to 'total' and then sets 'currentBet' to zero
public void setTotal(int total) {
this.total = total;
}
@@ -22,6 +31,9 @@ public class Player {
return this.total;
}
// TODO replace Player.setHand with 'dealCard(Card card)' and resetHand()
// dealCard adds the given card to the player's hand
// resetHand resets 'hand' to an empty list
public void setHand(LinkedList<Card> hand) {
this.hand = hand;
}