shouldPlayDealer & playDealer implementations, formatting to mimic original code

This commit is contained in:
Mitch Peck
2022-03-11 21:12:59 -06:00
parent 34574d60cb
commit 14123c9a4f
4 changed files with 275 additions and 41 deletions

View File

@@ -94,12 +94,14 @@ public class Game {
play(player);
}
// TODO 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);
if(shouldPlayDealer(players)){
playDealer(dealer);
} else {
userIo.println("DEALER HAD " + dealer.getHand().get(1).toProseString() + " CONCEALED.");
}
}
evaluateRound(players, dealer);//TODO: User dealerHand once playHeader implemented
evaluateRound(players, dealer);
}
}
@@ -165,7 +167,7 @@ public class Game {
private void play(Player player, int handNumber) {
String action;
if(player.isSplit()){
action = userIo.prompt("HAND #" + handNumber);
action = userIo.prompt("HAND " + handNumber);
} else {
action = userIo.prompt("PLAYER " + player.getPlayerNumber() + " ");
}
@@ -200,11 +202,13 @@ public class Game {
Card card = deck.deal();
player.dealCard(card, 1);
userIo.println("FIRST HAND RECEIVES " + card.toProseString());
play(player, 1);
card = deck.deal();
player.dealCard(card, 2);
userIo.println("SECOND HAND RECEIVES " + card.toProseString());
play(player, 2);
userIo.println("SECOND HAND RECEIVES " + card.toProseString());
if(player.getHand().get(0).getValue() > 1){ //Can't play after splitting aces
play(player, 1);
play(player, 2);
}
return; // Don't fall out of the while loop and print another total
} else {
userIo.println("SPLITTING NOT ALLOWED");
@@ -218,9 +222,38 @@ public class Game {
}
}
}
userIo.println("TOTAL IS " + ScoringUtils.scoreHand(player.getHand(handNumber)));
int total = ScoringUtils.scoreHand(player.getHand(handNumber));
if(total == 21) {
userIo.println("BLACKJACK");
} else {
userIo.println("TOTAL IS " + total);
}
}
/**
* Check the Dealer's hand should be played out. If every player has either busted or won with natural Blackjack,
* the Dealer doesn't need to play.
*
* @param players
* @return boolean whether the dealer should play
*/
protected boolean shouldPlayDealer(List<Player> players){
for(Player player : players){
int score = ScoringUtils.scoreHand(player.getHand());
if(score < 21 || (score == 21 && player.getHand().size() > 2)){
return true;
}
if(player.isSplit()){
int splitScore = ScoringUtils.scoreHand(player.getHand(2));
if(splitScore < 21 || (splitScore == 21 && player.getHand(2).size() > 2)){
return true;
}
}
}
return false;
}
/**
* Play the dealer's hand. The dealer draws until they have >=17 or busts. Prints each draw as in the following example:
*
@@ -232,9 +265,25 @@ public class Game {
* @param dealerHand
* @return
*/
private LinkedList<Card> playDealer(LinkedList<Card> dealerHand, Deck deck) {
// TODO implement playDealer
return null;
protected void playDealer(Player dealer) {
int score = ScoringUtils.scoreHand(dealer.getHand());
userIo.println("DEALER HAS " + dealer.getHand().get(1).toProseString() + " CONCEALED FOR A TOTAL OF " + score);
if(score < 17){
userIo.print("DRAWS ");
}
while(score < 17) {
Card dealtCard = deck.deal();
dealer.dealCard(dealtCard);
score = ScoringUtils.scoreHand(dealer.getHand());
userIo.print(dealtCard.toString() + " ");
}
if(score > 21) {
userIo.println("...BUSTED\n");
} else {
userIo.println("---TOTAL IS " + score + "\n");
}
}
/**
@@ -280,18 +329,18 @@ public class Game {
userIo.print("PLAYER " + player.getPlayerNumber());
if(totalBet < 0) {
userIo.print(" LOSES ");
userIo.print(" LOSES " + String.format("%6s", formatter.format(Math.abs(totalBet))));
} else if(totalBet > 0) {
userIo.print(" WINS ");
userIo.print(" WINS " + String.format("%6s", formatter.format(totalBet)));
} else {
userIo.print(" PUSHES");
userIo.print(" PUSHES ");
}
player.recordRound(totalBet);
dealer.recordRound(totalBet*-1);
userIo.println(String.format("%6s", formatter.format(Math.abs(totalBet))) + " TOTAL= " + formatter.format(player.getTotal()));
userIo.println(" TOTAL= " + formatter.format(player.getTotal()));
player.resetHand();
}
userIo.println("DEALER'S TOTAL= " + formatter.format(dealer.getTotal()));
userIo.println("DEALER'S TOTAL= " + formatter.format(dealer.getTotal()) + "\n");
}
/**

View File

@@ -1,7 +1,7 @@
import java.util.List;
public final class ScoringUtils {
/**
* Calculates the value of a hand. When the hand contains aces, it will
* count one of them as 11 if that does not result in a bust.
@@ -9,15 +9,16 @@ public final class ScoringUtils {
* @param hand the hand to evaluate
* @return The numeric value of a hand. A value over 21 indicates a bust.
*/
public static final int scoreHand(List<Card> hand){
public static final int scoreHand(List<Card> hand) {
int nAces = (int) hand.stream().filter(c -> c.getValue() == 1).count();
int value = hand.stream()
.mapToInt(Card::getValue)
.filter(v -> v != 1) // start without aces
.map(v -> v > 10 ? 10 : v) // all face cards are worth 10. The 'expr ? a : b' syntax is called the 'ternary operator'
.sum();
.mapToInt(Card::getValue)
.filter(v -> v != 1) // start without aces
.map(v -> v > 10 ? 10 : v) // all face cards are worth 10. The 'expr ? a : b' syntax is called the
// 'ternary operator'
.sum();
value += nAces; // start by treating all aces as 1
if(nAces > 0 && value <= 11) {
if (nAces > 0 && value <= 11) {
value += 10; // We can use one of the aces to an 11
// You can never use more than one ace as 11, since that would be 22 and a bust.
}
@@ -25,27 +26,35 @@ public final class ScoringUtils {
}
/**
* Compares two hands accounting for natural blackjacks using the
* Compares two hands accounting for natural blackjacks and busting using the
* java.lang.Comparable convention of returning positive or negative integers
*
* @param handA hand to compare
* @param handB other hand to compare
* @return a negative integer, zero, or a positive integer as handA is less than, equal to, or greater than handB.
* @return a negative integer, zero, or a positive integer as handA is less
* than, equal to, or greater than handB.
*/
public static final int compareHands(List<Card> handA, List<Card> handB) {
int scoreA = scoreHand(handA);
int scoreB = scoreHand(handB);
if(scoreA == 21 && scoreB == 21){
if(handA.size() == 2 && handB.size() != 2){
return 1; //Hand A wins with a natural blackjack
} else if (handA.size() != 2 && handB.size() == 2) {
return -1; //Hand B wins with a natural blackjack
if (scoreA == 21 && scoreB == 21) {
if (handA.size() == 2 && handB.size() != 2) {
return 1; // Hand A wins with a natural blackjack
} else if (handA.size() != 2 && handB.size() == 2) {
return -1; // Hand B wins with a natural blackjack
} else {
return 0; //Tie
return 0; // Tie
}
} else if (scoreA > 21 || scoreB > 21) {
if (scoreA > 21 && scoreB > 21) {
return 0; // Tie, both bust
} else if (scoreB > 21) {
return 1; // A wins, B busted
} else {
return -1; // B wins, A busted
}
} else {
return Integer.compare(scoreA, scoreB);
return Integer.compare(scoreA, scoreB);
}
}