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

public class panex extends Applet implements Runnable{

    int mtbd[][] = {{9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
                    {9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9},
                    {9,4,4,4,4,4,4,4,4,9,0,0,0,0,0,0,0,0,9,8,8,8,8,8,8,8,8,9},
                    {9,9,3,3,3,3,3,3,9,9,9,0,0,0,0,0,0,9,9,9,7,7,7,7,7,7,9,9},
                    {9,9,9,2,2,2,2,9,9,9,9,9,0,0,0,0,9,9,9,9,9,6,6,6,6,9,9,9},
                    {9,9,9,9,1,1,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,5,5,9,9,9,9},
                    {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9}};
    int mtd[][] = new int[7][28];
    int pxb[] = {4,3,2,1,22,21,20,19};
    int pyb[] = {5,4,3,2,5,4,3,2};
    int pwb[] = {2,4,6,8,2,4,6,8};
    int px[] = new int[8],py[] = new int[8],pw[] = new int[8];
    int mx,my,sx,sy,tx,ty,pp,pl,ch = 0;
    Color pc[] = new Color[8];
    Color bg,oc;
    Button rep;
    Thread th = null;
    Image os;
    Graphics og;

    public void init(){

        setBackground(Color.white);
        os = createImage(600,300);
        og = os.getGraphics();
        for(int idx = 0;idx < 28;idx ++){
            for(int idy = 0;idy < 7;idy ++){
                mtd[idy][idx] = mtbd[idy][idx];
            }
        }
        for(int pd = 0;pd < 8;pd ++){
            px[pd] = pxb[pd] ; py[pd] = pyb[pd] ; pw[pd] = pwb[pd];
        }
        for(int ic = 0;ic < 4;ic ++){
            pc[ic] = new Color(255 - 20 * ic,0,0);
            pc[ic + 4] = new Color(0,0,255 - 20 * ic);
        }
        bg = new Color(230,230,230);
        oc = new Color(100,80,100);
        setLayout(new BorderLayout());
        Panel pan = new Panel();
        pan.setLayout(new FlowLayout());
        pan.add(rep = new Button("  replay  "));
        add("South",pan);
        rep.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                for(int idx = 0;idx < 28;idx ++){
                    for(int idy = 0;idy < 7;idy ++){
                         mtd[idy][idx] = mtbd[idy][idx];
                    }
                }
                for(int pd = 0;pd < 8;pd ++){
                    px[pd] = pxb[pd];py[pd] = pyb[pd];py[pd] = pyb[pd];
                }
                repaint();
            }
        });

        addMouseListener(
            new MouseAdapter(){
                public void mousePressed(MouseEvent e){
                     sx = (e.getX() - 20) / 20;
                     sy = e.getY() / 40;
                     pp = mtd[sy][sx];
                     tx = px[pp - 1] ; ty = py[pp - 1] ; pl = pw[pp - 1];
                }
            }
        );

        addMouseMotionListener(
            new MouseMotionAdapter(){
                public void mouseDragged(MouseEvent e){
                     mx = (e.getX() - 20) / 20;
                     my = e.getY() / 40;
                     if((mx != sx) || (my != sy)){
                         if((mx == sx) && (my == sy - 1)){
                             for(int ck = 0;ck < pl;ck ++){
                                 if(mtd[ty - 1][tx + ck] != 0){ch = 1;}
                             }
                             if(ch == 0){
                                 for(int ik = 0;ik < pl;ik ++){
                                     mtd[ty - 1][tx + ik] = pp;
                                     mtd[ty][tx + ik] = 0;
                                 }
                                 sx = mx ; sy = my;
                                 py[pp - 1] = py[pp - 1] - 1;
                                 ty = ty - 1;
                                 repaint();
                             }else{
                                 ch = 0;
                             }
                         }
                         if((mx == sx) && (my == sy + 1)){
                             for(int ck = 0;ck < pl;ck ++){
                                 if(mtd[ty + 1][tx + ck] != 0){ch = 1;}
                             }
                             if(ch == 0){
                                 for(int ik = 0;ik < pl;ik ++){
                                     mtd[ty + 1][tx + ik] = pp;
                                     mtd[ty][tx + ik] = 0;
                                 }
                                 sx = mx ; sy = my;
                                 py[pp - 1] = py[pp - 1] + 1;
                                 ty = ty + 1;
                                 repaint();
                             }else{
                                 ch = 0;
                             }
                         }
                         if((mx == sx - 1) && (my == sy)){
                             if(mtd[ty][tx - 1] != 0){ch = 1;}
                             if(ch == 0){
                                 mtd[ty][tx - 1] = pp;
                                 mtd[ty][tx + pl - 1] = 0;
                                 sx = mx ; sy = my;
                                 px[pp - 1] = px[pp - 1] - 1;
                                 tx = tx - 1;
                                 repaint();
                             }else{
                                 ch = 0;
                             }
                         }
                         if((mx == sx + 1) && (my == sy)){
                             if(mtd[ty][tx + pl] != 0){ch = 1;}
                             if(ch == 0){
                                 mtd[ty][tx + pl] = pp;
                                 mtd[ty][tx] = 0;
                                 sx = mx ; sy = my;
                                 px[pp - 1] = px[pp - 1] + 1;
                                 tx = tx + 1;
                                 repaint();
                             }else{
                                 ch = 0;
                             }
                         }
                         if((mx == sx - 2) && (my == sy)){
                             if((mtd[ty][tx - 1] != 0) || (mtd[ty][tx - 2] != 0)){ch = 1;}
                             if(ch == 0){
                                 mtd[ty][tx - 1] = pp ; mtd[ty][tx - 2] = pp ;
                                 mtd[ty][tx + pl - 1] = 0 ; mtd[ty][tx + pl - 2] = 0 ;
                                 sx = mx ; sy = my;
                                 px[pp - 1] = px[pp - 1] - 2;
                                 tx = tx - 2;
                                 repaint();
                             }else{
                                 ch = 0;
                             }
                         }
                         if((mx == sx + 2) && (my == sy)){
                             if((mtd[ty][tx + pl] != 0) || (mtd[ty][tx + pl + 1] != 0)){ch = 1;}
                             if(ch == 0){
                                 mtd[ty][tx + pl] = pp ; mtd[ty][tx + pl + 1] = pp ;
                                 mtd[ty][tx] = 0 ; mtd[ty][tx + 1] = 0 ;
                                 sx = mx ; sy = my;
                                 px[pp - 1] = px[pp - 1] + 2;
                                 tx = tx + 2;
                                 repaint();
                             }else{
                                 ch = 0;
                             }
                         }
                    }
                }
            }
        );
    }

    public void paint(Graphics g){
        og.setColor(Color.white); 
        og.fillRect(0,0,600,300);
        og.setColor(oc);
        og.fillRoundRect(20,20,560,240,20,20);
        for(int ix = 1;ix < 27;ix ++){
            for(int iy = 1;iy < 6;iy ++){
                if(mtd[iy][ix] < 1){
                    og.setColor(bg);
                }else if(mtd[iy][ix] < 9){
                    og.setColor(pc[mtd[iy][ix] - 1]);
                }else{
                    og.setColor(oc);
                }
                og.fillRect(ix * 20 + 20,iy * 40,20,40);
            }
        }
        og.setColor(Color.blue);
        og.fillOval(40,200,40,40);
        og.setColor(Color.red);
        og.fillOval(520,200,40,40);
        g.drawImage(os,0,0,this );
    }
    public void start(){    
        if(th == null){
            th = new Thread(this);
            th.start();
        }
    }

    public void stop(){
        th = null;
    }

    public void run(){
        while (th != null){
            try {
                Thread.sleep(20);
            }
            catch (InterruptedException e){ }
        }
    }
    public void update( Graphics g )
    {
        paint( g ) ;
    }
}