Black-Jack

This program is based on the following reading:

http://www.ibiblio.org/obp/thinkCSjav/chap11.htm

Read at least the first half of this chapter before working on
the program below (practice questions at the bottom of this program).


public class BlackJack
{
   public static void main(String[] args)
   {
      new BlackJack();
   }
   
   public BlackJack()
   {
      Card c1 = randomCard();
      Card c2 = randomCard();
      printCard(c1);
      printCard(c2);
      if (sameCard(c1,c2))
      {  System.out.println("CHEATER!!!"); }
      if (  (c1.rank == 11 && c2.rank == 1)
          || (c1.rank == 1 && c2.rank == 11)
         )
      {  System.out.println("BLACKJACK!!"); }
   }   
   
   class Card
   {
      int suit, rank;

      public Card ()
      {
       this.suit = 0;  this.rank = 0;
      }

      public Card (int suit, int rank)
      {
         this.suit = suit;  this.rank = rank;
      }
   }
   
   public Card randomCard()
   {
      int suit = (int)(Math.random()*4);
      int rank = (int)(Math.random()*13 + 1);
      Card card = new Card (suit, rank);
      return card;
   }
   
   public void printCard (Card c)
   {
      String[] suits = { "Clubs", "Diamonds", "Hearts", "Spades" };
      String[] ranks = { "narf", "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };

      System.out.println (ranks[c.rank] + " of " + suits[c.suit]);
   }
   
   public boolean sameCard (Card c1, Card c2)
   {
      return (c1.suit == c2.suit && c1.rank == c2.rank);
   }
   
}

/******************************************************

This program uses some of the code from Chapter 11 of
the book "Think Like a Computer Scientist".  The code
demonstrates sensible use of an INNER CLASS (Card).
The program is a basic start for a Black-Jack simulation.

- Black-Jack -
The rules of Black-Jack are:
(1) Each player receives 2 cards.
(2) The first player may take one more card, then one more,
     trying to get as close to 21 total as possible.
(3) When the first player stops taking cards, the second
     player takes cards to get closer to 21.
(4) If either player goes over 21, they lose immediately.
(5) If both players stay under 21, the player with the
     higher total wins.
(6) At the beginning, if a player has 21 in two cards,
     that is "Black Jack" and they win immediately.
(7) The totals are added-up as follows:
      Cards 2-10 count their face value (rank).
      Face cards (king, queen, jack) count 10.
      An ace counts either 11 or 1, depending on
         which is better for the player.
         
Examples:

    10 , 8  -->  18
    Jack, Queen --> 20
    Ace , 6 -->  either 7 or 17
    Queen , Ace --> Black-Jack (win)
    Queen , 5 , 8 --> 23  (busted = lose)
    
= The Program =

The program above chooses 2 cards at random and prints them.

(0) Run the program lots of times until BLACKJACK is printed.
    Also run it many times until it prints CHEATER.

(1) The check for BLACKJACK is wrong.  It only says BLACKJACK
    if a Jack and Ace are dealt.  It must also accept
    10 and Ace, Queen and Ace, or King and Ace.
    Create a METHOD that checks for BlackJack and returns
    a boolean TRUE or FALSE.  It should accept 2 cards as parameters.
    
(2) Create a METHOD that returns the VALUE of a card, as follows:

      2 --> 2      10 --> 10          Ace --> 11
      3 --> 3      Jack --> 10
      ...          Queen --> 10
      9 --> 9      King --> 10
      
    It must accept one CARD as a parameter.  Do NOT use a number (rank)
    as the parameter - give the entire card to the method.

(3) Create a METHOD called TOTAL that adds up the total value
    of 2 Cards.  It should call the VALUE method twice,
    add the values, and return the answer.
    
(4) Create a new CLASS called HAND.  This contains an ARRAY of CARDS.
     The array should be big enough for 5 cards - more is not needed.

(5) Create a method called DEAL - this should choose 5 random cards,
     and "deal" these into a HAND.  That means the HAND class
     needs a CONSTRUCTOR that accepts 5 cards as parameters.
     Then it must copy them into its array of 5 cards.

(6) Create a method called PRINTHAND to print out 5 cards.
    It should accept a HAND as a parameter.
     
(7) In POKER, a HAND has 5 cards.  If ALL 5 cards are the same suit
    (5 hearts or 5 spades, etc) that is called a FLUSH.  That is
    a very good hand.  Write a method called CHECKFLUSH that
    accepts a HAND as a parameter, and checks whether all 5 cards
    have the same suit.  Then it returns TRUE or FALSE.

*******************************************************/


== Solutions ==

   public boolean checkBlackJack(Card first, Card second)
   {
      if ( (first.rank >= 10 && second.rank == 1)
         ||(first.rank == 1 && second.rank >= 10) )
      { return true; }
      else
      { return false; }
   }
   
   public int value(Card c)
   { if (c.rank > 10)
     { return 10; }
     else if (c.rank == 1)
     { return 11; }
     else
     { return c.rank; }
   }
   
   public int total(Card first, Card second)
   { int v1 = value(first);
     int v2 = value(second);
     return v1+v2;
   }
   
   class Hand
   {
     Card[] cards = new Card[5];
     
     public Hand(Card first, Card second)
     {
        cards[0] = first;
        cards[1] = second;       
     }
     
     public Hand(Card c0, Card c1, Card c2, Card c3, Card c4)
     {
        cards[0] = c0;
        cards[1] = c1;
        cards[2] = c2;
        cards[3] = c3;
        cards[4] = c4;
     }
   }

   
   public Hand deal()
   {
      Hand these = new Hand(randomCard(), randomCard(),
                     randomCard(), randomCard(), randomCard());
      return these;
   }

   public void printHand(Hand h)
   {
      for (int c=0; c < 5; c++)
      {
        printCard(h.cards[c]);
      }
   }
   
   public boolean checkFlush(Hand h)
   {
      if (   h.cards[0].suit == h.cards[1].suit
          && h.cards[1].suit == h.cards[2].suit    
          && h.cards[2].suit == h.cards[3].suit    
          && h.cards[3].suit == h.cards[4].suit    
         )
      { return true; }
      else
      { return false; }
   }