private void compareHandsToDealerHand() { boolean dealerBusted = HandUtilities.bust(this.dealerHand); int dealerHandValue = HandUtilities.value(this.dealerHand); for (Seat seat : this.seats) { for (CardsAndBet hand : seat.hands) { if (!hand.isDone()) { int playerHandValue = HandUtilities.value(hand.cards()); if (dealerBusted || dealerHandValue < playerHandValue) { hand.setResult(Result.PLAYER_WIN); } else if (dealerHandValue > playerHandValue) hand.setResult(Result.DEALER_WIN); else hand.setResult(Result.PUSH); } } } }
private void offerAndResolveInsurance() { for (int seatIndex = 0; seatIndex < seats.size(); seatIndex++) { Seat seat = this.seats.get(seatIndex); if (seat.hands.size() > 0) { seat.insuranceBet = seat.player.insureHand(seat.hands.get(0).cards(), this.dealerHand.get(0)); for (BlackjackObserver observer : this.observers) observer.insuranceDecision( seatIndex, seat.hands.get(0).cards(), this.dealerHand.get(0), seat.insuranceBet); } } boolean dealerBlackjack = HandUtilities.blackjack(this.dealerHand); for (int seatIndex = 0; seatIndex < this.seats.size(); seatIndex++) { Seat seat = this.seats.get(seatIndex); if (seat.insuranceBet) { double insuranceBet = seat.hands.get(0).bet() / 2; if (dealerBlackjack) this.take -= insuranceBet * 2; else this.take += insuranceBet; for (BlackjackObserver observer : this.observers) observer.insuranceResult( seatIndex, insuranceBet, seat.hands.get(0).cards(), this.dealerHand.get(0), dealerBlackjack); } } }
// returns true if at least one bet, false otherwise public boolean playRound() { boolean atLeastOneBet = this.takeBetsAndDealInitialCards(); if (!atLeastOneBet) return false; if (this.dealerHand.get(0).value() == Value.ACE) offerAndResolveInsurance(); if (HandUtilities.blackjack(this.dealerHand)) { // share dealer's hole card that is now visible) for (BlackjackObserver observer : this.observers) observer.faceUpCard(this.dealerHand.get(1)); for (Seat seat : this.seats) { if (seat.hands.size() > 0) { CardsAndBet hand = seat.hands.get(0); if (HandUtilities.blackjack(hand.cards())) hand.setResult(Result.PUSH); else hand.setResult(Result.DEALER_WIN); } } } else { for (int seatIndex = 0; seatIndex < seats.size(); seatIndex++) this.playSeat(seatIndex); // share dealer's hole card that is now visible) for (BlackjackObserver observer : this.observers) observer.faceUpCard(this.dealerHand.get(1)); boolean unresolvedBet = false; for (int seatIndex = 0; seatIndex < this.seats.size() && !unresolvedBet; seatIndex++) { Seat seat = this.seats.get(seatIndex); for (CardsAndBet hand : seat.hands) { if (!hand.isDone()) unresolvedBet = true; } } if (unresolvedBet) { while (HandUtilities.value(this.dealerHand) < DEALER_MAX) this.dealerHand.add(dealFaceUpCard()); this.compareHandsToDealerHand(); } } List<Card> discards = new ArrayList<>(); for (int seatIndex = 0; seatIndex < this.seats.size(); seatIndex++) { for (CardsAndBet hand : this.seats.get(seatIndex).hands) { for (BlackjackObserver observer : this.observers) observer.result( seatIndex, hand.bet(), new LinkedList<Card>(hand.cards()), new LinkedList<Card>(this.dealerHand), hand.result()); if (hand.result() != Result.SOURCE_OF_SPLIT) discards.addAll(hand.cards()); } } discards.addAll(this.dealerHand); this.cardSource.discard(discards); if (this.cardSource.justShuffled()) for (BlackjackObserver observer : observers) observer.shuffle(); this.settleBets(); for (Seat seat : this.seats) seat.hands.clear(); this.dealerHand.clear(); return true; }
private void playSeat(int seatIndex) { Seat seat = this.seats.get(seatIndex); for (int i = 0; i < seat.hands.size(); i++) { CardsAndBet hand = seat.hands.get(i); if (i == 0 && HandUtilities.blackjack(hand.cards())) { hand.setResult(Result.PLAYER_BLACKJACK); } else { List<PlayerAction> allowedActions = new ArrayList<PlayerAction>(Arrays.asList(PlayerAction.values())); if (hand.cards().size() == 1) // hand is result of splitting { if (hand.cards().get(0).value() == Value.ACE) // hand is result of splitting aces { allowedActions.remove(PlayerAction.HIT); allowedActions.remove(PlayerAction.DOUBLE); } allowedActions.remove(PlayerAction.SURRENDER); hand.dealCardTo(dealFaceUpCard()); } if (i != 0 || hand.cards().size() != 2) allowedActions.remove(PlayerAction.SURRENDER); if (hand.cards().size() != 2 || seat.hands.size() == 7 || // 7 hands means 4 valid hands (rest are sources of splits) (hand.cards().get(0).value().numericValue() != hand.cards().get(1).value().numericValue())) allowedActions.remove(PlayerAction.SPLIT); // TODO: player should not be asked to make a decision if split hand is 21 // TODO: why does this only happen in the observer, not the basic player when just playing? if (HandUtilities.value(hand.cards()) == HandUtilities.MAX_VALUE) allowedActions.clear(); while (allowedActions.size() >= 2) // player still has at least 1 decision to make { ArrayList<PlayerAction> allowedActionsCopy = new ArrayList<PlayerAction>(allowedActions); PlayerAction action = seat.player.act(hand.cards(), this.dealerHand.get(0), allowedActionsCopy); if (!allowedActions.contains(action)) throw new IllegalActionException( seat.player.id() + " attempted to " + action + " when not allowed."); for (BlackjackObserver observer : this.observers) observer.decision( seatIndex, hand.cards(), this.dealerHand.get(0), allowedActionsCopy, action); allowedActions.clear(); switch (action) { case HIT: hand.dealCardTo(dealFaceUpCard()); if (HandUtilities.value(hand.cards()) < HandUtilities.MAX_VALUE) { allowedActions.add(PlayerAction.HIT); allowedActions.add(PlayerAction.STAND); } break; case DOUBLE: hand.dealCardTo(dealFaceUpCard()); hand.doubleBet(); break; case STAND: break; case SURRENDER: hand.setResult(Result.SURRENDER); break; case SPLIT: List<Card> cards = hand.cards(); hand.setResult(Result.SOURCE_OF_SPLIT); seat.hands.add(i + 1, new CardsAndBet(hand.bet())); seat.hands.get(i + 1).dealCardTo(cards.get(0)); seat.hands.add(i + 2, new CardsAndBet(hand.bet())); seat.hands.get(i + 2).dealCardTo(cards.get(1)); break; } } if (!hand.isDone() && HandUtilities.bust(hand.cards())) hand.setResult(Result.DEALER_WIN); } } }