mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -08:00
Add Blackjack/java outline with TODO placeholders
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
import static java.util.stream.Collectors.joining;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Blackjack {
|
public class Blackjack {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@@ -28,15 +27,14 @@ public class Blackjack {
|
|||||||
nPlayers = promptInt("NUMBER OF PLAYERS");
|
nPlayers = promptInt("NUMBER OF PLAYERS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Deck deck = new Deck(4); // TODO figure out how many decks the BASIC version uses
|
||||||
System.out.println("RESHUFFLING");
|
System.out.println("RESHUFFLING");
|
||||||
LinkedList<Card> deck = new LinkedList<>();
|
deck.shuffle();
|
||||||
for(Card.Suit suit : Card.Suit.values()) {
|
|
||||||
for(int value = 1; value < 14; value++) {
|
|
||||||
deck.add(new Card(value, suit));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Collections.shuffle(deck);
|
|
||||||
|
|
||||||
|
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.
|
int[] bets = new int[nPlayers]; // empty array initialized with all '0' valuses.
|
||||||
while(!betsAreValid(bets)){
|
while(!betsAreValid(bets)){
|
||||||
System.out.println("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 1 2 DEALER
|
||||||
Player
|
7 10 4
|
||||||
CurrentBet
|
2 A
|
||||||
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
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Prompts the user for a "Yes" or "No" answer.
|
||||||
* @param prompt The prompt to display to the user on STDOUT.
|
* @param prompt The prompt to display to the user on STDOUT.
|
||||||
|
|||||||
40
10_Blackjack/java/src/Deck.java
Normal file
40
10_Blackjack/java/src/Deck.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,9 +2,15 @@ import java.util.LinkedList;
|
|||||||
|
|
||||||
public class Player {
|
public class Player {
|
||||||
|
|
||||||
|
// TODO add 'playerNumber' property. e.g. playerNumber = 1 means "this is Player 1"
|
||||||
private int currentBet;
|
private int currentBet;
|
||||||
private int total;
|
private int total;
|
||||||
private LinkedList<Card> hand;
|
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) {
|
public void setCurrentBet(int currentBet) {
|
||||||
this.currentBet = currentBet;
|
this.currentBet = currentBet;
|
||||||
@@ -14,6 +20,9 @@ public class Player {
|
|||||||
return this.currentBet;
|
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) {
|
public void setTotal(int total) {
|
||||||
this.total = total;
|
this.total = total;
|
||||||
}
|
}
|
||||||
@@ -22,6 +31,9 @@ public class Player {
|
|||||||
return this.total;
|
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) {
|
public void setHand(LinkedList<Card> hand) {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user