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

public class t_over2 extends Applet implements Runnable{

   Thread th = null;
   Image os;
   Graphics og;
   int td[][] = new int[3][3];
   int bd[][] = new int[3][3];
   int f_x[] = {20,60,70,55,35,35,50,50,55,55,50,50,35,35,40,40,20,20,25,25,20};
   int f_y[] = {10,10,20,15,15,35,35,30,30,45,45,40,40,65,65,70,70,65,65,15,10};
   int dfx[] = new int[21],dfy[] = new int[21],lx[] = new int[21],ly[] = new int[21];
   int mx,my,sx,sy,px,py;
   int h1x,h1y,h2x,h2y;
   int sw,ch,ra,re,co,cl;
   double pi = 3.141592;
   double st,sm;
   Button sh,rt;
   Label spa;

   public void init(){
      setLayout(new BorderLayout());
      Panel pan = new Panel();
      pan.setLayout(new FlowLayout());
      pan.add(sh = new Button("  shuffle  "));
      pan.add(spa = new Label("    "));
      pan.add(rt = new Button("   retry   "));
      add("South",pan);
      os = createImage(280,300);
      og = os.getGraphics();

      for(int ix = 0;ix < 3;ix ++){
         for(int iy = 0;iy < 3;iy ++){
            td[iy][ix] = 1;
            bd[iy][ix] = 1;
         }
      }

      sh.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            for(int ss = 0;ss < 20;ss ++){
               ra = (int)(6 * Math.random());
               ch = td[ra/3][ra%3];
               switch (td[ra/3+1][ra%3]){
                  case 1 : td[ra/3][ra%3] = 3;break;
                  case 2 : td[ra/3][ra%3] = 4;break;
                  case 3 : td[ra/3][ra%3] = 1;break;
                  case 4 : td[ra/3][ra%3] = 2;break;
               }
               switch (ch){
                  case 1 : td[ra/3+1][ra%3] = 3;break;
                  case 2 : td[ra/3+1][ra%3] = 4;break;
                  case 3 : td[ra/3+1][ra%3] = 1;break;
                  case 4 : td[ra/3+1][ra%3] = 2;break;
               }
               ch = td[ra%3][ra/3];
               switch (td[ra%3][ra/3+1]){
                  case 1 : td[ra%3][ra/3] = 2;break;
                  case 2 : td[ra%3][ra/3] = 1;break;
                  case 3 : td[ra%3][ra/3] = 4;break;
                  case 4 : td[ra%3][ra/3] = 3;break;
               }
               switch (ch){
                  case 1 : td[ra%3][ra/3+1] = 2;break;
                  case 2 : td[ra%3][ra/3+1] = 1;break;
                  case 3 : td[ra%3][ra/3+1] = 4;break;
                  case 4 : td[ra%3][ra/3+1] = 3;break;
               }
            }
            for(int b1 = 0;b1 < 3;b1 ++){
               for(int b2 = 0;b2 < 3;b2 ++){
                  bd[b2][b1] = td[b2][b1];
               }
            }
            co = 0;cl = 0;
            repaint();
         }
      });

      rt.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            for(int b1 = 0;b1 < 3;b1 ++){
               for(int b2 = 0;b2 < 3;b2 ++){
                  td[b2][b1] = bd[b2][b1];
               }
            }
            co = 0;cl = 0;
            repaint();
         }
      });

      addMouseListener(
         new MouseAdapter(){
            public void mousePressed(MouseEvent e){
               if((co < 6)&&(cl == 0)){
                  if(sw == 0){
                     px = e.getX() / 40;
                     py = e.getY() / 40;
                     if(((sx == 2)||(sx == 4))&&(sy%2 == 1)){
                        h1x = px/2-1;h1y = (py-1)/2;h2x = px/2;h2y = (py-1)/2;
                        sw = 1;
                     }else if(((sy == 2)||(sy == 4))&&(sx%2 == 1)){
                        h1x = (px-1)/2;h1y = py/2-1;h2x = (px-1)/2;h2y = py/2;
                        sw = 2;
                     }
                     repaint();
                  }
               }
            }
         } 
      );

      addMouseMotionListener(
         new MouseMotionAdapter(){
            public void mouseMoved(MouseEvent e){
               mx = e.getX();
               my = e.getY();
               sx = e.getX() / 40;
               sy = e.getY() / 40;
               repaint();
            }
         }
      );

   }

   public void paint(Graphics g){
      og.setColor(Color.white);
      og.fillRect(0,0,280,300);

      for(int ix = 0;ix < 3;ix ++){
         for(int iy = 0;iy < 3;iy ++){
            if((sw == 0)||(((ix != h1x)||(iy != h1y))&&((ix != h2x)||(iy != h2y)))){
               og.setColor(Color.black);
               og.drawRoundRect(ix*80+20,iy*80+20,80,80,10,10);
               inp_f(td[iy][ix],ix*80+22,iy*80+22);
               og.setColor(Color.gray);
               og.fillPolygon(dfx,dfy,21);
               inp_f(td[iy][ix],ix*80+20,iy*80+20);
               og.setColor(Color.blue);
               og.fillPolygon(dfx,dfy,21);
            }
         }
      }

      if(sw == 1){
         og.setColor(Color.black);
         og.drawRoundRect(px*40+20,py*40-20,(int)(80*Math.cos(st)),80,10,10);
         inp_f(td[h2y][h2x],0,0);
         for(int cv = 0;cv < 21;cv ++){
            lx[cv] = (int)(dfx[cv]*Math.cos(st)) + 80*h2x+20;
            ly[cv] = dfy[cv] + 80*h2y+20;
         }
         og.setColor(Color.blue);
         og.fillPolygon(lx,ly,21);
         og.setColor(Color.black);
         og.drawRoundRect(px*40+20-(int)(80*Math.cos(st)),py*40-20,(int)(80*Math.cos(st)),80,10,10);
         inp_f(td[h1y][h1x],0,0);
         for(int cv = 0;cv < 21;cv ++){
            lx[cv] = 80*h2x+20 + (int)((dfx[cv]-80)*Math.cos(st));
            ly[cv] = dfy[cv] + 80*h2y+20;
         }
         og.setColor(Color.blue);
         og.fillPolygon(lx,ly,21);
      }else if(sw == 2){
         og.setColor(Color.black);
         og.drawRoundRect(px*40-20,py*40+20,80,(int)(80*Math.cos(st)),10,10);
         inp_f(td[h2y][h2x],0,0);
         for(int cv = 0;cv < 21;cv ++){
            lx[cv] = dfx[cv] + 80*h2x+20;
            ly[cv] = (int)(dfy[cv]*Math.cos(st)) + 80*h2y+20;
         }
         og.setColor(Color.blue);
         og.fillPolygon(lx,ly,21);
         og.setColor(Color.black);
         og.drawRoundRect(px*40-20,py*40+20-(int)(80*Math.cos(st)),80,(int)(80*Math.cos(st)),10,10);
         inp_f(td[h1y][h1x],0,0);
         for(int cv = 0;cv < 21;cv ++){
            lx[cv] = dfx[cv] + 80*h2x+20;
            ly[cv] = 80*h2y+20 + (int)((dfy[cv]-80)*Math.cos(st));
         }
         og.setColor(Color.blue);
         og.fillPolygon(lx,ly,21);
      }

      og.setFont(new Font("",Font.BOLD,18));
      if((co < 6)&&(cl == 0)){
         if((sx+sy)%2 == 1){
            if(((sx == 2)||(sx == 4))&&(sy%2 == 1)){
               og.setColor(Color.red);
               og.fillArc(sx*40+22,sy*40,40,40,150,60);
               og.fillArc(sx*40-22,sy*40,40,40,-30,60);
               og.setColor(Color.black);
               og.drawString(""+(co+1),sx*40+16,sy*40+26);
            }else if(((sy == 2)||(sy == 4))&&(sx%2 == 1)){
               og.setColor(Color.red);
               og.fillArc(sx*40,sy*40-22,40,40,240,60);
               og.fillArc(sx*40,sy*40+22,40,40,60,60);
               og.setColor(Color.black);
               og.drawString(""+(co+1),sx*40+16,sy*40+26);
            }
         }
      }
      ch = 1;
      for(int ix = 0;ix < 3;ix ++){
         for(int iy = 0;iy < 3;iy ++){
            ch = ch * td[iy][ix];
         }
      }
      if(ch == 1){
         cl = 1;
         og.setColor(Color.red);
         og.drawRoundRect(10,10,260,260,30,30);
         og.drawRoundRect(12,12,256,256,28,28);
      }

      g.drawImage(os,0,0,this);

   }

   public void inp_f(int fd,int dx,int dy){
      switch (fd){
         case 1 : for(int i1 = 0;i1 < 21;i1 ++){
                     dfx[i1] = f_x[i1] + dx;
                     dfy[i1] = f_y[i1] + dy;
                  }
                  break;
         case 2 : for(int i1 = 0;i1 < 21;i1 ++){
                     dfx[i1] = 80 - f_x[i1] + dx;
                     dfy[i1] = f_y[i1] + dy;
                  }
                  break;
         case 3 : for(int i1 = 0;i1 < 21;i1 ++){
                     dfx[i1] = f_x[i1] + dx;
                     dfy[i1] = 80 - f_y[i1] + dy;
                  }
                  break;
         case 4 : for(int i1 = 0;i1 < 21;i1 ++){
                     dfx[i1] = 80 - f_x[i1] + dx;
                     dfy[i1] = 80 - f_y[i1] + dy;
                  }
                  break;
      }
   }

   public void start(){
      if(th == null){
         th = new Thread(this);
         th.start();
      }
   }

   public void stop(){
      th = null;
   }

   public void run(){
      while(th != null){
         try{
            if(sw != 0){
               sm = sm + pi/30;
               if(sm < pi){
                  if(sm < pi/2){
                     st = sm;
                  }else{
                     if(re == 0){
                        if(sw == 1){
                           ch = td[h1y][h1x];
                           switch (td[h2y][h2x]){
                              case 1 : td[h1y][h1x] = 2;break;
                              case 2 : td[h1y][h1x] = 1;break;
                              case 3 : td[h1y][h1x] = 4;break;
                              case 4 : td[h1y][h1x] = 3;break;
                           }
                           switch (ch){
                              case 1 : td[h2y][h2x] = 2;break;
                              case 2 : td[h2y][h2x] = 1;break;
                              case 3 : td[h2y][h2x] = 4;break;
                              case 4 : td[h2y][h2x] = 3;break;
                           }
                        }else if(sw == 2){
                           ch = td[h1y][h1x];
                           switch (td[h2y][h2x]){
                              case 1 : td[h1y][h1x] = 3;break;
                              case 2 : td[h1y][h1x] = 4;break;
                              case 3 : td[h1y][h1x] = 1;break;
                              case 4 : td[h1y][h1x] = 2;break;
                           }
                           switch (ch){
                              case 1 : td[h2y][h2x] = 3;break;
                              case 2 : td[h2y][h2x] = 4;break;
                              case 3 : td[h2y][h2x] = 1;break;
                              case 4 : td[h2y][h2x] = 2;break;
                           }
                        }
                        re = 1;
                     }
                     st = pi - sm;
                  }
               }else{
                  sm = 0;
                  sw = 0;
                  re = 0;
                  co ++;
               }
            }
            Thread.sleep(30);
         }
         catch (InterruptedException e){
         }
         repaint();
      }
   }

   public void update( Graphics g ){
      paint( g ) ;
   }
}