import java.applet.* ;
import java.awt.* ;
import java.lang.* ;
import java.util.* ;

public class Magic1 extends Applet
{
   private GCanvas   game ;
   private HCanvas   h ;
   private Button    b1, b2, b3 ;
   private Panel     p ;

   public void init()
   {
      GridBagConstraints c ;
      GridBagLayout     g ;

      p = new Panel() ;
      g = new GridBagLayout() ;
      setLayout(g) ;
      c = new GridBagConstraints() ;
      p.setLayout(new BorderLayout()) ;

      b1 = new Button("Col 1") ;
      b2 = new Button("Col 2") ;
      b3 = new Button("Col 3") ;
      game = new GCanvas() ;
      h = new HCanvas() ;

      p.add("West", b1) ;
      p.add("Center", b2) ;
      p.add("East", b3) ;

      c.fill = GridBagConstraints.BOTH ;
      c.gridwidth = 1 ;
      c.gridheight = 2 ;
      c.weighty = 1.0 ;
      c.weightx = 0.0 ;

      g.setConstraints(h, c) ;
      c.gridwidth = GridBagConstraints.REMAINDER ;
      c.gridheight = 1 ;
      g.setConstraints(game, c) ;
      c.fill = GridBagConstraints.NONE ;
      c.weighty = 0.0 ;
      g.setConstraints(p, c) ;
      add(h) ;
      add(game) ;
      add(p) ;
   }

   public String getAppletInfo()
   {
      return 
         "The 7 Column Card Game v 1.0\n" +
         "Author: Subhabrata Biswas\n" +
         "        subhabrata.biswas@citicorp.com\n" +
         "URL   : http://cosl-online.cosl.in.citicorp.com/~biswas/" ;
   }

   public boolean action(Event e, Object what)
   {
      if (e.target == b1)
      {
         if (game.deal(1) > 0)
         {
            remove(p) ;
            h.help = h.done3 ;
            h.repaint() ;
         }
         return true ;
      }
      if (e.target == b2)
      {
         if (game.deal(2) > 0)
         {
            remove(p) ;
            h.help = h.done3 ;
            h.repaint() ;
         }
         return true ;
      }
      if (e.target == b3)
      {
         if (game.deal(3) > 0)
         {
            remove(p) ;
            h.help = h.done3 ;
            h.repaint() ;
         }
         return true ;
      }
      return false ;
   }

   public boolean mouseDown(Event e, int x, int y)
   {
      Rectangle r ;

      if (game.state == 3)
      {
         h.help = h.chose2 ;
         h.repaint() ;
         return true ;
      }
      if (game.state == 5)
      {
         h.help = h.chose1 ;
         h.repaint() ;
         return true ;
      }
      if (game.state == 7)
      {
         h.help = h.card2 ;
         h.repaint() ;
         return true ;
      }
      if (game.state == 10)
      {
         h.help = h.alldone ;
         h.repaint() ;
         return true ;
      }

      return false ;
   }
}

class GCanvas extends Canvas
{
   private int n[][] ;
   private int n1[], n2[], n3[] ;
   private int dealnum ;
   public  int state ;
   public  int yournum ;

   public  Rectangle rect[][][] ;

   private int s1, s2, s3, c1, c2, c3 ;
   private int clx, cly ;

   public GCanvas()
   {
      resize(240, 300) ;
      init() ;
   }

   public void drawcards(int i, int j, int all, Graphics g)
   {
      int x, y ;

      x = i*110 + 60 ; y = j*110 + 60 ;
      if (all == 0)
      {
         g.setColor(Color.black) ;
         g.drawRect(x-15, y-50, 30, 50) ;
         g.setColor(Color.white) ;
         g.fillRect(x-14, y-49, 29, 49) ;
         rect[i][j][0] = new Rectangle(x-15, y-50, 30, 50) ;

         g.setColor(Color.black) ;
         g.drawRect(x, y-15, 50, 30) ;
         g.setColor(Color.white) ;
         g.fillRect(x+1, y-14, 49, 29) ;
         rect[i][j][1] = new Rectangle(x, y-15, 50, 30) ;

         g.setColor(Color.black) ;
         g.drawRect(x-15, y, 30, 50) ;
         g.setColor(Color.white) ;
         g.fillRect(x-14, y+1, 29, 49) ;
         rect[i][j][2] = new Rectangle(x-15, y, 30, 50) ;

         g.setColor(Color.black) ;
         g.drawRect(x-50, y-15, 50, 30) ;
         g.setColor(Color.white) ;
         g.fillRect(x-49, y-14, 49, 29) ;
         rect[i][j][3] = new Rectangle(x-50, y-15, 50, 30) ;
      }
      else
      {
         g.drawRect(rect[i][j][all-1].x, rect[i][j][all-1].y, rect[i][j][all-1].width, rect[i][j][all-1].height) ;
         g.setColor(Color.white) ;
         g.fillRect(rect[i][j][all-1].x+1, rect[i][j][all-1].y+1, rect[i][j][all-1].width-1, rect[i][j][all-1].height-1) ;
      }

      g.setColor(Color.black) ;
   }

   public void paint(Graphics g)
   {
      int x, y, i, j ;

      g.setColor(Color.black) ;
      if (state == 0)
      {
         g.clearRect(0, 0, 200, 150) ;
         for (i = 0 ; i < 7 ; i++)
            for (j = 0 ; j < 3 ; j++)
               g.drawString(String.valueOf(n[i][j]), (j+1)*50, (i+1)*13) ;
         return ;
      }
      if (state == 1 || state == 2)
      {
         g.clearRect(0, 0, 200, 150) ;
         for (i = 0 ; i < 2 ; i++)
            for (j = 0 ; j < 2 ; j++)
            {
               drawcards(i, j, 0, g) ;
            }
         state = 2 ;
         return ;
      }
      if (state == 3 || state == 4)
      {
         g.clearRect(0, 0, 200, 150) ;
         if (s1 == 1 || s2 == 1)
            drawcards(0, 0, 0, g) ;
         if (s1 == 2 || s2 == 2)
            drawcards(0, 1, 0, g) ;
         if (s1 == 3 || s2 == 3)
            drawcards(1, 0, 0, g) ;
         if (s1 == 4 || s2 == 4)
            drawcards(1, 1, 0, g) ;
         state = 4 ;
      }
      if (state == 5 || state == 6)
      {
         g.clearRect(0, 0, 200, 150) ;
         if (s3 == 1)
            drawcards(0, 0, 0, g) ;
         if (s3 == 2)
            drawcards(0, 1, 0, g) ;
         if (s3 == 3)
            drawcards(1, 0, 0, g) ;
         if (s3 == 4)
            drawcards(1, 1, 0, g) ;
         state = 6 ;
      }
      if (state == 7 || state == 8)
      {
         j = (s3-1)%2 ;
         i = (s3-1)/2 ;
         if (c1 < c2)
         {
            drawcards(i, j, c1, g) ;
            drawcards(i, j, c2, g) ;
         }
         else
         {
            drawcards(i, j, c2, g) ;
            drawcards(i, j, c1, g) ;
         }
         state = 8 ;
      }
      if (state == 10)
      {
         g.drawRect(75, 75, 50, 30) ;
         g.setColor(Color.white) ;
         g.fillRect(76, 76, 49, 29) ;
         g.setColor(Color.red) ;
         i = g.getFontMetrics().stringWidth(String.valueOf(yournum)) ;
         g.drawString(String.valueOf(yournum), 75 + (50-i)/2, 95) ;
         g.setColor(Color.black) ;
      }
      if (state == 100)
      {
         g.drawString(String.valueOf(clx), 10, 250) ;
         g.drawString(String.valueOf(cly), 10, 265) ;
      }
   }


   public void init()
   {
      n  = new int[7][3] ;
      n1 = new int[7] ;
      n2 = new int[7] ;
      n3 = new int[7] ;
      rect = new Rectangle[2][2][4] ;

      shuffle() ;
      state = 0 ;
      s1 = s2 = s3 = c1 = c2 = c3 = 0 ;
   }

   public boolean mouseDown(Event e, int x, int y)
   {
      int i, j, k ;

      if (state == 2)
      {
         for (i = 0 ; i < 2 ; i++)
            for (j = 0 ; j < 2 ; j++)
               for (k = 0 ; k < 4 ; k++)
               {
                  if (x >= rect[i][j][k].x && x <= (rect[i][j][k].x + rect[i][j][k].width) &&
                      y >= rect[i][j][k].y && y <= (rect[i][j][k].y + rect[i][j][k].height))
                  {
                     if (s1 == 0)
                     {
                        s1 = i+1 + j+i ;
                        return true ;
                     }
                     else
                     {
                        if ((i+1 + j+i) == s1)
                           return false ;
                        s2 = i+1 + j+i ;
                        state = 3 ;
                        repaint() ;
                        return false ;
                     }
                  }
               }
         return false ;
      }

      if (state == 4)
      {
         for (i = 0 ; i < 2 ; i++)
            for (j = 0 ; j < 2 ; j++)
               for (k = 0 ; k < 4 ; k++)
               {
                  if (x >= rect[i][j][k].x && x <= (rect[i][j][k].x + rect[i][j][k].width) &&
                      y >= rect[i][j][k].y && y <= (rect[i][j][k].y + rect[i][j][k].height))
                  {
                     if (s3 == 0)
                     {
                        if ((i+1 + j+i) != s1 && (i+1 + j+i) != s2)
                           return false ;

                        s3 = i+1 + j+i ;
                        state = 5 ;
                        repaint() ;
                        return false ;
                     }
                  }
               }
         return false ;
      }

      if (state == 6)
      {
         for (i = 0 ; i < 2 ; i++)
            for (j = 0 ; j < 2 ; j++)
               for (k = 3 ; k >= 0 ; k--)
               {
                  if (x >= rect[i][j][k].x && x <= (rect[i][j][k].x + rect[i][j][k].width) &&
                      y >= rect[i][j][k].y && y <= (rect[i][j][k].y + rect[i][j][k].height))
                  {
                     if ((i+1 + j+i) != s3)
                        return false ;

                     if (c1 == 0)
                     {
                        c1 = k+1 ;
                        return true ;
                     }
                     else
                     {
                        if (c1 == (k+1))
                           return false ;
                        c2 = k+1 ;
                        state = 7 ;
                        repaint() ;
                        return false ;
                     }
                  }
               }
         return false ;
      }

      if (state == 8)
      {
         for (i = 0 ; i < 2 ; i++)
            for (j = 0 ; j < 2 ; j++)
               for (k = 3 ; k >= 0 ; k--)
               {
                  if (x >= rect[i][j][k].x && x <= (rect[i][j][k].x + rect[i][j][k].width) &&
                      y >= rect[i][j][k].y && y <= (rect[i][j][k].y + rect[i][j][k].height))
                  {
                     if ((i+1 + j+i) != s3)
                        return false ;
                     if ((k+1) != c1 && (k+1) != c2)
                        return false ;

                     c3 = k + 1 ;
                     state = 10 ;
                     repaint() ;
                     return false ;
                  }
               }
         return false ;
      }
      return false ;
   }

   public void shuffle()
   {
      int  i, j, num, in1, in2, in3 ;

      dealnum = 1 ;

      for (i = 0 ; i < 7 ; i ++)
      {
         n1[i] = n2[i] = n3[i] = 0 ;
      }

      for (in1 = 0 ; in1 < 7 ; in1++)
      {
         do
         {
            num = (int)(Math.random()*100) ;
            if (num <= 0)
               continue ;
         } while (!checknum(num)) ;
         n[in1][0] = n1[in1] = num ;
      }
      for (in2 = 0 ; in2 < 7 ; in2++)
      {
         do
         {
            num = (int)(Math.random()*100) ;
            if (num <= 0)
               continue ;
         } while (!checknum(num)) ;
         n[in2][1] = n2[in2] = num ;
      }
      for (in3 = 0 ; in3 < 7 ; in3++)
      {
         do
         {
            num = (int)(Math.random()*100) ;
            if (num <= 0)
               continue ;
         } while (!checknum(num)) ;
         n[in3][2] = n3[in3] = num ;
      }
   }

   public int deal(int col)
   {
      int j, i, in1, in2, in3 ;

      if (dealnum > 3)
         return 1 ;

      dealnum++ ;
      in1 = in2 = in3 = 0 ;

      if (col == 1)
      {
         in1 = 1 ;
         in2 = 0 ;
         in3 = 2 ;
      }
      if (col == 2)
      {
         in1 = 2 ;
         in2 = 1 ;
         in3 = 0 ;
      }
      if (col == 3)
      {
         in1 = 0 ;
         in2 = 2 ;
         in3 = 1 ;
      }

      if (dealnum > 3)
      {
         yournum = n[3][in2] ;
         state = 1 ;
         repaint() ;
         return 1 ;
      }

      for (i = 0 ; i < 7 ; i++)
      {
         n1[i] = n[i][in1] ;
         n2[i] = n[i][in2] ;
         n3[i] = n[i][in3] ;
      }
      for (i = j = in1 = 0 ; in1 < 7 ; in1++)
      {
         n[i][j] = n1[in1] ;
         j++ ;
         if (j == 3)
         {
            j = 0 ;
            i++ ;
         }
      }
      for (in2 = 0 ; in2 < 7 ; in2++)
      {
         n[i][j] = n2[in2] ;
         j++ ;
         if (j == 3)
         {
            j = 0 ;
            i++ ;
         }
      }
      for (in3 = 0 ; in3 < 7 ; in3++)
      {
         n[i][j] = n3[in3] ;
         j++ ;
         if (j == 3)
         {
            j = 0 ;
            i++ ;
         }
      }

      repaint() ;
      if (dealnum > 3)
      {
         state = 1 ;
         return 1 ;
      }

      return 0 ;
   }

   private boolean checknum(int num)
   {
      int   i ;

      for (i = 0 ; i < 7 ; i++)
      {
         if (n1[i] == num)
            return false ;
         if (n2[i] == num)
            return false ;
         if (n3[i] == num)
            return false ;
      }

      return true ;
   }
}

class HCanvas extends Canvas
{
   public String   intro = "I will show you some numbers in 3 columns. All " +
                   "you have to do is select a number, remember it " +
                   "and tell me which column it is in. I will shuffle " +
                   "the numbers and ask you again. " +
                   "We will repeat this process 3 times and after the " +
                   "3rd round, I will tell you the number you chose. " +
                   "\n\nSo, let's start. " +
                   "Just click the appropriate button to tell me the " +
                   "column number. \n\nCheerio." ;
   public String   done3 = "\n\n\nThat was nice. Now I have written some " +
                    "numbers on the cards in the next pane. Choose any " +
                    "two groups of cards in the next pane (click on them)." ;
   public String   chose2 = "\n\n\nSo, you are fond of these two groups. " +
                    "I removed the rest and made it easy for you. Now you " +
                    "have just two groups left. Choose one." ;
   public String   chose1 = "\n\n\nThat was terrific. You have just 4 cards " +
                    "left to choose from. Let's see if you still remember " +
                    "your favourite number. Click on any two of the 4 " +
                    "remaining cards." ;
   public String   card2  = "\n\n\nNow you have only two cards left. Choose one." ;
   public String   alldone = "\n\n\n\nCongrats! You cracked it !!" ;

   public String   help ;

   int      mw, mh ;
   int      lm, rm ;

   public HCanvas()
   {
      mw = 250 ; mh = 200 ;
      lm = rm = 20 ;
      help = intro ;
      resize(mw, mh) ;
   }

   public void paint(Graphics g)
   {
      int    pos, i, j, n, pj ;

      g.clearRect(0, 0, mw, mh) ;
      i = 0 ;
      pos = 20 ;
      while (i < help.length())
      {
         pj = j = i ;
         if (help.charAt(j+1) == '\n')
         {
            while (help.charAt(j+1) == '\n')
            {
               j++ ;
               pos += 20 ;
            }
            j++ ;
            pj = i = j ;
         }
         while (true)
         {
            try
            {
               j = help.indexOf(' ', j) ;
               n = g.getFontMetrics().stringWidth(help.substring(i, j)) ;
            }
            catch(StringIndexOutOfBoundsException e)
            {
               g.drawString(help.substring(i), lm, pos) ;
               i = 99999 ;
               break ;
            }
            if (n < (mw - (lm+rm)))
            {
               pj = j ;
               j++ ;
               if (help.charAt(j) == '\n')
               {
                  g.drawString(help.substring(i, pj), lm, pos) ;
                  i = pj+1 ;
                  pos += 20 ;
                  break ;
               }
            }
            else
            {
               g.drawString(help.substring(i, pj), lm, pos) ;
               i = pj+1 ;
               pos += 20 ;
               break ;
            }
         }
      }
   }
}