// CMPU-101-51, Spring 2007
// Asmt 8 Solutions

// ---------------------------
//  The BlackjackHand class
// ---------------------------

class BlackjackHand {

  // -------------------------
  //   Object-oriented data
  // -------------------------
  
  // An array to hold the cards in the hand
  private Card[] cards = new Card[10];
  // The number of cards currently in the hand
  private int numCards = 0;
  // Indicates whether the hand currently contains an ace
  private boolean hasAce = false;
  // The deck from which all cards will be dealt
  // The deck is declared final so that the user can't switch
  //   to a different deck of cards halfway through!
  private final Deck theDeck;
  
  // ------------------
  //  constructor
  // ------------------  

  //  Includes deck as an argument.  The deck can't
  //  be changed once it is set.  Also, deals the first
  //  two cards to the hand.
  
  BlackjackHand(Deck d) {
    this.theDeck = d;
    this.hitMe();
    this.hitMe();
  }
  
  // ---------------------------
  //  Object-Oriented Methods
  // ---------------------------
  
  //  hardValue
  // ------------------------------------
  //   Sums the values of the cards in the hand
  //   counting all aces as 1.
  
  int hardValue() {
    int hv = 0;
    for (int i=0; i<this.numCards; i++)
      hv += this.cards[i].value();
    return hv;
  }
  
  //  value 
  // ---------------------------------------------
  //  same as hardValue except that if the hand contains
  //  an ace, it may be counted as 11 if it wouldn't cause
  //  the hand to bust.
  
  int value() {
    int hv = this.hardValue();
    if (hv <= 11 && this.hasAce) return hv+10;
    else return hv;
  }
  
  //  isBusted
  // ---------------------------
  //  returns true if the value of the hand is over 21
  
  boolean isBusted() {
    return this.value() > 21;
  }
  
  //  hitMe
  // -------------------
  //  deals a card from the deck, adding it to the hand.
  
  BlackjackHand hitMe() {
    if (isBusted()) 
      System.out.println("Hey!  You're busted!  Can't hit you!");
    else {
      // deal a card
      this.cards[this.numCards] = this.theDeck.deal();
      // if the card is an ace, set hasAce to true
      if (this.cards[this.numCards].isAce()) this.hasAce = true;
      // increment the number of cards in the hand
      this.numCards += 1;
    }
    return this;
  }
 
  // toString
  public String toString() {
    String str = "Hand:  ";
    // only want to display slots that actually hold cards
    for (int i=0; i<this.numCards; i++)
      str += this.cards[i] + ", ";
    // report the value of the hand
    str += "\n       (value = " + this.value() + ")";
    // and let us know if it is busted!
    if (this.isBusted()) str += " ====> BUSTED!";
    return str + "\n";
  }
  
  //  playLikeDealer
  // -----------------------
  //  Continue "hitting" the hand until the value of the hand
  //  is 17 or better.
  
  BlackjackHand playLikeDealer() {
    while (this.value() < 17) {
      this.hitMe();
      System.out.println("HITTING: " + this);
    }
    return this;
  }
  
}