Exemplo n.º 1
0
  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);
      }
    }
  }