TwentyOne.java

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class TwentyOne extends Applet implements ActionListener,
                                                 ItemListener    {

   Tie tie;
   BetAmount betAmount;
   Buttons buttonGroup;
   Choice holdOn;
   QuitFrame quitting;
   Panel p, p2;
   Image cardImage[];
   MediaTracker tracker;
   Hand house, you;
   DeckOfCards deck;
   int money = 100, houseSum, youSum, bets = 10, oldBet = 10, holdAmount = 17;
   boolean bust, over, first, houseGetsTie, message;

   /*********************************************************************
   **********************************************************************
   ******               Applet methods                             ******
   **********************************************************************
   *********************************************************************/


   public void init() {

      /***  Applet uses border layout  ***/
      setLayout (new BorderLayout(10,10));

      /***  south panel contains radio buttons for who gets a tie  ***
      ***   and how much is bet each game                         ***/ 
      p = new Panel();
      p.setLayout(new GridLayout(3,1));
      tie = new Tie();
      p.add(tie);
      betAmount = new BetAmount();
      p.add(betAmount);
      add("South",p);
      /***  add listeners so that radio buttons can function   ***/
      betAmount.ten.addItemListener(this);
      betAmount.twenty.addItemListener(this);
      betAmount.thirty.addItemListener(this);
      tie.youTie.addItemListener(this);
      tie.houseTie.addItemListener(this);

      /***  north panel contains buttons that control the game and a  ***
      ***   choice list that determines what the house sticks on     ***/
      p2 = new Panel();
      buttonGroup = new Buttons();
      buttonGroup.hit.addActionListener(this);
      buttonGroup.stick.addActionListener(this);
      buttonGroup.cont.addActionListener(this);
      p2.add(buttonGroup);
      Label lHold = new Label("House sticks on:");
      p2.add(lHold);
      /***  set up the choice list  ***/
      holdOn = new Choice();
      holdOn.add(" 13 ");
      holdOn.add(" 14");
      holdOn.add(" 15");
      holdOn.add(" 16");
      holdOn.add(" 17");
      holdOn.add(" 18");
      holdOn.add(" 19");
      holdOn.add(" 20");
      holdOn.add(" 21");
      holdOn.select(" 17");
      holdOn.addItemListener(this);
      p2.add(holdOn);
      add("North", p2);

      /***  Create the frame for asking if you really want to quit.  ***
      ***   Only actually quits in appletviewer (earlier versions of ***
      ***   the jdk (1.1.5)                                         ***/
      tie.quit.addActionListener(this);
      quitting = new QuitFrame("Quit?");

      /***  Load all the images for the deck of cards.  ***/
      tracker = new MediaTracker(this);
      cardImage = new Image[53];
      for (int i=0; i <= 52; i++) {
         cardImage[i] = getImage(getCodeBase(), i + ".jpg");
         tracker.addImage(cardImage[i], 1);
      }

      /***  Wait until they are loaded  ***/
      try {
         tracker.waitForID(1);
      }
      catch (InterruptedException e) { 
         // do nothing if there is an exception
      }

      /***  Initialize the hands and the deck  ***/
      house = new Hand(5);
      you = new Hand(5);
      deck = new DeckOfCards();

      /***  Initialize the flags   ***/
      over = true;
      first = true;
      message = false;
      houseGetsTie = true;
   }


   public void paint (Graphics g) {

      int i;
      
      buttonGroup.setBank();
      g.setColor(Color.green);
      g.fillRect(0,0,600,500);
      if (message) {
         g.setColor(Color.red);
         g.drawString("Option changes take effect after this hand is over",
                       150, 290);
      }
      if (first) {
         g.setColor(Color.red);
         g.drawString("Press Continue to start playing",150,270);
      }
      if (!first) {
         g.setColor(Color.black);
         g.drawString("House:",20,100);
         if (!over)
            g.drawImage(cardImage[0], 20, 110, this);
         else
            g.drawImage(cardImage[house.getCard(1)], 20, 110, this);

         g.drawRect(20,110,70,95);
         for (i = 2; house.getCard(i) != Hand.NO_CARD; i++) {
            g.drawImage(cardImage[house.getCard(i)], 20 + 80*(i-1), 110, this);
            g.drawRect(20+80*(i-1),110,70,95);
         }
         g.drawString("You:",20, 340);
         for (i = 1; i <= you.getNum(); i++) {
            g.drawImage(cardImage[you.getCard(i)],- 60 + 80*i, 350, this);
            g.drawRect(- 60 + 80*i, 350,70,95);
         }
      }
   }

   /****  update   ******************************************************
   *  Override the applet's update method so the screen doesn't get     *
   *  erased every time.  Cuts down on the flickering                   *
   *********************************************************************/
   public void update(Graphics g) {

      paint(g);
   }


   /*********************************************************************
   **********************************************************************
   ******    Implementation of ActionListener interface            ******
   **********************************************************************
   *********************************************************************/

   public void actionPerformed(ActionEvent e) {

      /***  the user has pressed the hit button  ***/
      if (e.getSource() == buttonGroup.hit) {
         /***  check if it was an appropriate time to press it  ***/
         if (!over) {
            you.setNext(deck.deal());  //*** get another card
            youSum = sum(you);
            if (youSum > 21)           //*** check if you now went bust
               bust = over = true;
            repaint();
         }
      }

      /***  the user has pressed the stick button  ***/
      if (e.getSource() == buttonGroup.stick) {
         while (sum(house) < holdAmount && !over) {
            house.setNext(deck.deal());
            if (sum(house) > 21)
               over = true;
          }
          over = true;
          repaint();
      }
      if (e.getSource() == buttonGroup.cont) {
         if (over) {
            if (!first) {
               if (houseGetsTie && sum(house) == sum(you))
                  money -= oldBet;
               else if (!houseGetsTie && sum(house) == sum(you))
                  money += oldBet;
               else if (sum(house) > 21)
                  money += oldBet;
               else if (sum(you) > 21)
                  money -= oldBet;
               else if (sum(house) < sum (you))
                  money += oldBet;
               else
                  money -= oldBet;
               oldBet = bets;
            }
            startGame();
            message = false;
            first = false;
            repaint();  // this is essentially the repaint
         }
            
      }
      if (e.getSource() == tie.quit) {
       
         quitting.setVisible(true);
      }
  
   }

   /*********************************************************************
   **********************************************************************
   ******    Implementation of ItemListener interface              ******
   **********************************************************************
   *********************************************************************/

   public void itemStateChanged(ItemEvent e) {
      if (e.getItemSelectable() == betAmount.ten) {
         bets = 10;
         message = true;
         repaint();
      }
      if (e.getItemSelectable() == betAmount.twenty) {
         bets = 20;
         message = true;
         repaint();
      }
      if (e.getItemSelectable() == betAmount.thirty) {
         bets = 30;
         message = true;
         repaint();
      }
      if (e.getItemSelectable() == tie.youTie)
         houseGetsTie = false;
      if (e.getItemSelectable() == tie.houseTie)
         houseGetsTie = true;
      if (e.getItemSelectable() == holdOn)
         holdAmount = holdOn.getSelectedIndex() + 13;

   }

   /*********************************************************************
   **********************************************************************
   ******    Methods for this particular applet                    ******
   **********************************************************************
   *********************************************************************/



   public void startGame() {
      over = false;
      bust = false;
      deck.shuffle();  // may want to continue with existing deck until a
                       // certain number of cards are gone
      house.emptyHand();
      you.emptyHand();
      house.setNext(deck.deal());
      house.setNext(deck.deal());
      you.setNext(deck.deal());
      you.setNext(deck.deal());
      houseSum = sum(house);
      youSum = sum(you);
   }

   public int getValue(int card) {
      if (card % 13 < 11 && card % 13 != 0)
         return card % 13;
      else
         return 10;
   }

   public int sum (Hand h) {
      int i, total = 0, aceCount = 0;
      for (i = 1; i <= h.getNum(); i++) {
         total += getValue(h.getCard(i));
         if (getValue(h.getCard(i)) == 1) {
            aceCount++;
            total += 10;
         }
      }
      while (aceCount > 0 && total > 21) {
         total -= 10;
         aceCount--;
      }
      return total;
   }
   /*********************************************************************
   **********************************************************************
   ******    Inner class Tie                                       ******
   **********************************************************************
   *********************************************************************/



   class Tie extends Panel {
      CheckboxGroup groupTie;
      Checkbox youTie, houseTie;
      Label l = new Label("Tie goes to:   ");
      Label l2 = new Label("                        End game:");
      Button quit;

      Tie() {
         add(l);
         groupTie = new CheckboxGroup();
         add(youTie = new Checkbox("You", groupTie, false));
         add(houseTie = new Checkbox ("House", groupTie, true));
         quit = new Button("  quit  ");
      //   add(l2);
      //   add(quit);
      }
   }

   /*********************************************************************
   **********************************************************************
   ******    Inner class BetAmount                                 ******
   **********************************************************************
   *********************************************************************/

   class BetAmount extends Panel {
      CheckboxGroup groupAmount;
      Checkbox ten, twenty, thirty;
      Label l = new Label("Amount of Bet: ");

      BetAmount() {
         groupAmount = new CheckboxGroup();
         add(l);
         add(ten = new Checkbox("$10", groupAmount, true));
         add(twenty = new Checkbox("$20", groupAmount, false));
         add(thirty = new Checkbox("$30", groupAmount, false));
      }
   }

   /*********************************************************************
   **********************************************************************
   ******    Inner class Buttons                                   ******
   **********************************************************************
   *********************************************************************/

   class Buttons extends Panel {
      Button hit, stick, cont;
      Label b = new Label("             Bank:");
      TextField bankField = new TextField(8);

      Buttons() {
         add(b);
         add(bankField);
         hit = new Button("  hit   ");
         add(hit);
         stick = new Button(" stick  ");
         add(stick);
         cont = new Button("continue");
         add(cont);

      }

      public void setBank() {
         bankField.setText("$ " + money);
      }

   }


   /*********************************************************************
   **********************************************************************
   ******    Inner class QuitFrame                                 ******
   **********************************************************************
   *********************************************************************/

   class QuitFrame extends Frame implements ActionListener {
      Button yesButton, noButton;
      Label l = new Label ("Do you really want to quit?");

      QuitFrame (String title) {
         super(title);
         setSize(300, 75);
         setLayout(new FlowLayout());
         yesButton = new Button("   yes   ");
         noButton = new Button("   no    ");
         yesButton.addActionListener(this);
         noButton.addActionListener(this);
         add(l);
         add(yesButton);
         add(noButton);
      }

      public void actionPerformed(ActionEvent e) {
         if (e.getSource() == yesButton) {
            setVisible(false);
            System.exit(0);
         }
         else if (e.getSource() == noButton) {
            setVisible(false);
         }
      }
   }

}