import java.applet.*;
import java.awt.*;
import java.lang.StringBuffer;
public class engine extends Applet {
   private int last_x=0;
   private int last_y=0;
   private int moves=0;
   private int i;
   private int j;
   private char ctemp;
   private int xold;
   private int yold;
   private int xnew;
   private int ynew;
   private int cobj=1;
   private int xclick;
   private int yclick;
   private Color current_color=Color.black;
   private Button draw_button;
   private Button new_button;
   private Button bkw_button;
   private Button frw_button;
   private int sqsize=40;
   private int bishsize=6;
   private int pawnsize=5;
   private int kingsize=17;
   private int queesize=5;
   private int knigsize=7;
   private int rooksize=9;
   private int[] xrook=new int[rooksize];
   private int[] yrook=new int[rooksize];
   private int[] xbish=new int[bishsize];
   private int[] ybish=new int[bishsize];
   private int[] xpawn=new int[pawnsize];
   private int[] ypawn=new int[pawnsize];
   private int[] xking=new int[kingsize];
   private int[] yking=new int[kingsize];
   private int[] xquee=new int[queesize];
   private int[] yquee=new int[queesize];
   private int[] xknig=new int[knigsize];
   private int[] yknig=new int[knigsize];
   private int[] xset=new int[17];
   private int[] yset=new int[17];
   private int[] kills=new int[120];
   private String game1;
   private String gameout;
   private StringBuffer gamebuffer;
   
   private boolean castle=false;
   private boolean kside=true;
   private TextField textln;
   private TextArea texta;
   private Panel textm;
   


     private class Piece implements Cloneable{
                 
                 public int xplace=0;
                 public int yplace=0;
                 public int xkill=0;
                 public int ykill=0;
                 public int rank=0;

                  public Object clone(){ //begin clone
                    try{ //begin try
                        Piece cp=(Piece)super.clone();
                        return cp;
                        } catch(CloneNotSupportedException e){
                           return null;
                          }//end catch

                    } //end cloning structure for chess piece 
  
   
           } //end virtual chess piece def

      public Piece upiece=new Piece(); 
      public Piece wset[]=new Piece[16];
      public Piece bset[]=new Piece[16];

//init applet
   public void init(){
// get parameters
           game1=getGameParameter("game");



//set backgd color
           this.setBackground(Color.white);

//create redo button
    draw_button=new Button("Draw/Redraw");
    draw_button.setForeground(Color.black);
    draw_button.setBackground(Color.lightGray);
    this.add(draw_button);

// create a new board
     new_button=new Button("Clear");
     new_button.setForeground(Color.black);
     new_button.setBackground(Color.lightGray);
     this.add(new_button);
      

//create backward button
     bkw_button=new Button("<<");
     bkw_button.setForeground(Color.black);
     bkw_button.setBackground(Color.lightGray);
     this.add(bkw_button);


// create forward button
     frw_button=new Button(">>");
     frw_button.setForeground(Color.black);
     frw_button.setBackground(Color.lightGray);
     this.add(frw_button);


// create text window

  textln = new TextField(15);
  texta = new TextArea(20,20);
  texta.setEditable(false);
  textm = new Panel();
  textm.setBackground(Color.white);
  add(textm);
  texta.setEditable(false);
  texta.setText(" ");
  textm.add(texta);
      upiece.xplace=0;
      upiece.yplace=0;
      upiece.xkill=0;
      upiece.ykill=0;
      upiece.rank=0;

  for(i=0;i<16;i++){ 
          wset[i]=(Piece)upiece.clone();
          bset[i]=(Piece)upiece.clone();
                    }

   for(i=0;i<100;i++){kills[i]=32;}

    for(i=0;i<8;i++){
         wset[i].xplace=i+1;
         bset[i].xplace=i+1;
         wset[i].yplace=7;
         bset[i].yplace=2;
         wset[i].xkill=0;
         wset[i].ykill=i;
         bset[i].xkill=9;
         bset[i].ykill=i+1;
         wset[i].rank=1;
         bset[i].rank=1;  
           } //defines pawns in set


   for(i=8;i<16;i++){
         wset[i].xplace=i-7;   
         wset[i].yplace=8;
         wset[i].xkill=i-7;
         wset[i].ykill=0; 
         bset[i].xplace=i-7;
         bset[i].yplace=1;
         bset[i].xkill=i-7;
         bset[i].ykill=9;
      if((i==8)|(i==15)){wset[i].rank=4; bset[i].rank=4;}
      if((i==9)|(i==14)){wset[i].rank=2; bset[i].rank=2;}
      if((i==10)|(i==13)){wset[i].rank=3; bset[i].rank=3;}
      if(i==11){wset[i].rank=6; bset[i].rank=6;}
      if(i==12){wset[i].rank=5; bset[i].rank=5;}
            } // defines back row

 

// define rook
xrook[0]=2;
xrook[1]=18;
xrook[2]=15;
xrook[3]=18;
xrook[4]=18;
xrook[5]=2;
xrook[6]=2;
xrook[7]=5;
xrook[8]=2;
yrook[0]=30;
yrook[1]=30;
yrook[2]=15;
yrook[3]=15;
yrook[4]=10;
yrook[5]=10;
yrook[6]=15;
yrook[7]=15;
yrook[8]=30;

//define bish
xbish[0]=0;
xbish[1]=16;
xbish[2]=13;
xbish[3]=8;
xbish[4]=3;
xbish[5]=0;
ybish[0]=30;
ybish[1]=30;
ybish[2]=10;
ybish[3]=17;
ybish[4]=10;
ybish[5]=30;

//define pawn
 xpawn[0]= 0;
 xpawn[1]= 10;
 xpawn[2]= 7;
 xpawn[3]= 3;
 xpawn[4]= 0;
 ypawn[0]= 30;
 ypawn[1]= 30;
 ypawn[2]= 20;
 ypawn[3]= 20;
 ypawn[4]= 30;
             
//define king
 xking[0]= 0;
 xking[1]= 16;
 xking[2]= 13;
 xking[3]= 10;
 xking[4]= 10;
 xking[5]= 13;
 xking[6]= 13;
 xking[7]= 10;
 xking[8]= 10;
 xking[9]= 6;
 xking[10]= 6;
 xking[11]= 3;
 xking[12]= 3;
 xking[13]= 6;
 xking[14]= 6;
 xking[15]= 3;
 xking[16]= 0;
 yking[0]= 30;
 yking[1]= 30;
 yking[2]= 10;
 yking[3]= 10;
 yking[4]= 8;
 yking[5]= 8;
 yking[6]= 6;
 yking[7]= 6;
 yking[8]= 4;
 yking[9]= 4;
 yking[10]= 6;
 yking[11]= 6;
 yking[12]= 8;
 yking[13]= 8;
 yking[14]= 10;
 yking[15]= 10;
 yking[16]= 30;

//define knight

xknig[0]=0;
xknig[1]=16;
xknig[2]=13;
xknig[3]=18;
xknig[4]=16;
xknig[5]=3;
xknig[6]=0;
yknig[0]=30;
yknig[1]=30;
yknig[2]=18;
yknig[3]=18;
yknig[4]=10;
yknig[5]=10;
yknig[6]=30;

//define queen
 xquee[0]= 0;
 xquee[1]= 16;
 xquee[2]= 13;
 xquee[3]= 3;
 xquee[4]= 0;
 yquee[0]= 30;
 yquee[1]= 30;
 yquee[2]= 10;
 yquee[3]= 10;
 yquee[4]= 30;

   }
//end init applet

    // Read the specified parameter 
    protected String getGameParameter(String name){
            String value=this.getParameter(name);
             
            return new String(value);
        } // end get game string


// called to draw pawn
   public boolean dPawn(Color pc, int xp, int yp){
          Graphics g=this.getGraphics();
             for(j=0;j<5;j++){
             xset[j]=xpawn[j]+ xp;
             yset[j]=yp+ypawn[j]; 
                     } //end for j 
   if(pc==Color.white){g.setColor(Color.white);} 
          else { g.setColor(Color.black);}             
                g.fillPolygon(xset,yset,pawnsize);
                g.fillArc(xset[3]-1,yset[3]-5,5,5,0,360);
   if(pc==Color.white){g.setColor(Color.black);} 
          else { g.setColor(Color.white);}             
                g.drawArc(xset[3]-1,yset[3]-5,5,5,0,360);
                g.drawPolygon(xset,yset,pawnsize);    
   
   return true;
    }
//called to draw rook
    public boolean dRook(Color pc, int xp, int yp){
          Graphics g=this.getGraphics();
           for(j=0; j<rooksize;j++){
             xset[j]=xrook[j]+xp;
             yset[j]=yp+yrook[j]; 
                 } //end for j
   if(pc==Color.white){g.setColor(Color.white);} 
          else { g.setColor(Color.black);}             
                 g.fillPolygon(xset,yset,rooksize);
   if(pc==Color.white){g.setColor(Color.black);} 
          else { g.setColor(Color.white);}             
                g.drawPolygon(xset,yset,rooksize);
              return true;
     }

//called to draw knight
    public boolean dKnig(Color pc, int xp, int yp){
          Graphics g=this.getGraphics();
           for(j=0; j<knigsize;j++){
             xset[j]=xknig[j]+xp;
             yset[j]=yp+yknig[j]; 
                 } //end for j
   if(pc==Color.white){g.setColor(Color.white);} 
          else { g.setColor(Color.black);}             
                 g.fillPolygon(xset,yset,knigsize);
   if(pc==Color.white){g.setColor(Color.black);} 
          else { g.setColor(Color.white);}             
                g.drawPolygon(xset,yset,knigsize);
              return true;
     }

//called to draw bishop
    public boolean dBish(Color pc, int xp, int yp){
          Graphics g=this.getGraphics();
           for(j=0; j<bishsize;j++){
             xset[j]=xbish[j]+xp;
             yset[j]=yp+ybish[j]; 
                 } //end for j
   if(pc==Color.white){g.setColor(Color.white);} 
          else { g.setColor(Color.black);}             
                 g.fillPolygon(xset,yset,bishsize);
   if(pc==Color.white){g.setColor(Color.black);} 
          else { g.setColor(Color.white);}             
                g.drawPolygon(xset,yset,bishsize);
              return true;
     }

//called to draw king
    public boolean dKing(Color pc, int xp, int yp){
          Graphics g=this.getGraphics();
           for(j=0; j<kingsize;j++){
             xset[j]=xking[j]+xp;
             yset[j]=yp+yking[j]; 
                 } //end for j
   if(pc==Color.white){g.setColor(Color.white);} 
          else { g.setColor(Color.black);}             
                 g.fillPolygon(xset,yset,kingsize);
   if(pc==Color.white){g.setColor(Color.black);} 
          else { g.setColor(Color.white);}             
                g.drawPolygon(xset,yset,kingsize);
              return true;
     }

//called to draw Queen
    public boolean dQuee(Color pc, int xp, int yp){
          Graphics g=this.getGraphics();
           for(j=0; j<queesize;j++){
             xset[j]=xquee[j]+xp;
             yset[j]=yp+yquee[j]; 
                 } //end for j
   if(pc==Color.white){g.setColor(Color.white);} 
          else { g.setColor(Color.black);}             
                g.fillPolygon(xset,yset,queesize);
                g.fillArc(xset[3]+1,yset[3]-7,7,7,0,360);
    if(pc==Color.white){g.setColor(Color.black);} 
          else { g.setColor(Color.white);}             
                g.drawPolygon(xset,yset,queesize);
                g.drawArc(xset[3]+1,yset[3]-7,7,7,0,360);

              return true;
     }

//called to draw board
     public boolean dBoard(){
               gameout="";
             for(i=0;i<moves+1;i++){
             if((i+1)/2==i/2){
               gameout=gameout+String.valueOf(i/2+1)+ ". " + 
                         game1.substring(4*i,4*i+4)+ " ";
                 }  // end if
               else {
                    gameout=gameout +": " + game1.substring(4*i,4*i+4) + "\n";
                  } // end else
                }  // end for i
              
           texta.setText(gameout);
               Graphics g=this.getGraphics();
               Rectangle r=this.bounds();
               g.setColor(this.getBackground());
               g.fillRect(r.x,r.y,r.width,r.height);
               g.setColor(Color.gray);
               g.fillRect(0,0,10*sqsize,10*sqsize);
               for (i=0;i<8;i++){
               for (j=0;j<8;j++){
               if((int)(i+j)/2==(int)(i+j+1)/2){
               g.setColor(Color.white); 
               g.fillRect( sqsize+j*sqsize,sqsize + i*sqsize,sqsize,sqsize);                
                 } // end parity true
              else {
               g.setColor(Color.black); 
               g.fillRect(sqsize+j*sqsize,sqsize + i*sqsize,sqsize,sqsize);                
                 } // else   
             } // end j draw board
             } //end  i draw board

for(i=0;i<8;i++){
  dPawn(Color.white,16+wset[i].xplace*40,wset[i].yplace*40);
  dPawn(Color.black,16+bset[i].xplace*40,bset[i].yplace*40);
               } //end i draw pawns

 dRook(Color.white,10+wset[8].xplace*40,wset[8].yplace*40);
 dRook(Color.black,10+bset[8].xplace*40,bset[8].yplace*40);
 dKnig(Color.white,10+wset[9].xplace*40,wset[9].yplace*40);
 dKnig(Color.black,10+bset[9].xplace*40,bset[9].yplace*40);
 dBish(Color.white,10+wset[10].xplace*40,wset[10].yplace*40);
 dBish(Color.black,10+bset[10].xplace*40,bset[10].yplace*40);
 dKing(Color.white,10+wset[12].xplace*40,wset[12].yplace*40);
 dKing(Color.black,10+bset[12].xplace*40,bset[12].yplace*40);
 dQuee(Color.white,10+wset[11].xplace*40,wset[11].yplace*40);
 dQuee(Color.black,10+bset[11].xplace*40,bset[11].yplace*40);
 dBish(Color.white,10+wset[13].xplace*40,wset[13].yplace*40);
 dBish(Color.black,10+bset[13].xplace*40,bset[13].yplace*40);
 dKnig(Color.white,10+wset[14].xplace*40,wset[14].yplace*40);
 dKnig(Color.black,10+bset[14].xplace*40,bset[14].yplace*40);
 dRook(Color.white,10+wset[15].xplace*40,wset[15].yplace*40);
 dRook(Color.black,10+bset[15].xplace*40,bset[15].yplace*40);



       return true;
     }


//user clicks button 
     public boolean action(Event event, Object arg){
          // in case of click
          if(event.target==new_button){
    for(i=0;i<8;i++){
         wset[i].xplace=i+1;
         bset[i].xplace=i+1;
         wset[i].yplace=7;
         bset[i].yplace=2;
         wset[i].rank=1;
         bset[i].rank=1;  
           } //defines pawns in set


   for(i=8;i<16;i++){
         wset[i].xplace=i-7;
         wset[i].yplace=8;
         bset[i].xplace=i-7;
         bset[i].yplace=1;
      if((i==8)|(i==15)){wset[i].rank=4; bset[i].rank=4;}
      if((i==9)|(i==14)){wset[i].rank=2; bset[i].rank=2;}
      if((i==10)|(i==13)){wset[i].rank=3; bset[i].rank=3;}
      if(i==11){wset[i].rank=6; bset[i].rank=6;}
      if(i==12){wset[i].rank=5; bset[i].rank=5;}
            } // defines back row

               Graphics g=this.getGraphics();
               Rectangle r=this.bounds();
               g.setColor(this.getBackground());
               g.fillRect(r.x,r.y,r.width,r.height);
               moves=0;


            } // end new button

          if(event.target==draw_button){
 
            dBoard();

              } // draw button


          if(event.target==frw_button){

if(moves<(int)(game1.length()/4)){
        // game defines current object 
    if(game1.charAt(4*moves+0)=='a'){xold=1;}
    if(game1.charAt(4*moves+0)=='b'){xold=2;}
    if(game1.charAt(4*moves+0)=='c'){xold=3;}
    if(game1.charAt(4*moves+0)=='d'){xold=4;}
    if(game1.charAt(4*moves+0)=='e'){xold=5;}
    if(game1.charAt(4*moves+0)=='f'){xold=6;}
    if(game1.charAt(4*moves+0)=='g'){xold=7;}
    if(game1.charAt(4*moves+0)=='h'){xold=8;}
    if(game1.charAt(4*moves+0)=='o'){castle=true;}
    if(game1.charAt(4*moves+1)=='8'){yold=1;}
    if(game1.charAt(4*moves+1)=='7'){yold=2;}
    if(game1.charAt(4*moves+1)=='6'){yold=3;}
    if(game1.charAt(4*moves+1)=='5'){yold=4;}
    if(game1.charAt(4*moves+1)=='4'){yold=5;}
    if(game1.charAt(4*moves+1)=='3'){yold=6;}
    if(game1.charAt(4*moves+1)=='2'){yold=7;}
    if(game1.charAt(4*moves+1)=='1'){yold=8;}

    if(game1.charAt(4*moves+2)=='a'){xnew=1;}
    if(game1.charAt(4*moves+2)=='b'){xnew=2;}
    if(game1.charAt(4*moves+2)=='c'){xnew=3;}
    if(game1.charAt(4*moves+2)=='d'){xnew=4;}
    if(game1.charAt(4*moves+2)=='e'){xnew=5;}
    if(game1.charAt(4*moves+2)=='f'){xnew=6;}
    if(game1.charAt(4*moves+2)=='g'){xnew=7;}
    if(game1.charAt(4*moves+2)=='h'){xnew=8;}
    if(game1.charAt(4*moves+3)=='x'){kside=true;}
    if(game1.charAt(4*moves+3)=='o'){kside=false;}
    if(game1.charAt(4*moves+3)=='8'){ynew=1;}
    if(game1.charAt(4*moves+3)=='7'){ynew=2;}
    if(game1.charAt(4*moves+3)=='6'){ynew=3;}
    if(game1.charAt(4*moves+3)=='5'){ynew=4;}
    if(game1.charAt(4*moves+3)=='4'){ynew=5;}
    if(game1.charAt(4*moves+3)=='3'){ynew=6;}
    if(game1.charAt(4*moves+3)=='2'){ynew=7;}
    if(game1.charAt(4*moves+3)=='1'){ynew=8;}
 // game1 defines next white move


 if((int)(moves/2)==(int)(moves+1)/2){
if(castle){
     if(kside){
           wset[12].xplace=7;
           wset[15].xplace=6;
         } //end kside
      else{
           wset[12].xplace=3;
           wset[8].xplace=4;
           } // end else qside
     castle=false;  } //end if castle
    else{for(i=0;i<16;i++){

         if((wset[i].xplace==xold)&(wset[i].yplace==yold))
               {cobj=i;} // end if wset defines cobj for white
           } //end for i

           wset[cobj].xplace=xnew; 
           wset[cobj].yplace=ynew; 

 for(i=0;i<16;i++){

   if((bset[i].xplace==wset[cobj].xplace)&
          (bset[i].yplace==wset[cobj].yplace)){ 
     bset[i].xplace=bset[i].xkill;
     bset[i].yplace=bset[i].ykill;
 
   kills[moves]=i+16;
  
        } //end if black piece there
        } // end for i
    } // end if not castle     
    }  // end if even
        
       else{
if(castle){
     if(kside){
           bset[12].xplace=7;
           bset[15].xplace=6;
         } //end kside
      else{
           bset[12].xplace=3;
           bset[8].xplace=4;
           } // end else qside
     castle=false;  } //end if castle
  else{for(i=0;i<16;i++){

           if((bset[i].xplace==xold)&(bset[i].yplace==yold))
           {cobj=i + 16;} // end if bset
            } //end for i

           bset[cobj-16].xplace=xnew; 
           bset[cobj-16].yplace=ynew; 

 for(i=0;i<16;i++){
   if((wset[i].xplace==bset[cobj-16].xplace)&
          (wset[i].yplace==bset[cobj-16].yplace)){ 
     wset[i].xplace=wset[i].xkill;
     wset[i].yplace=wset[i].ykill; 

     kills[moves]=i; 

        } //end if white piece there
        } // end for i
          }  // end if not castle
          } // else odd
 
           moves=moves+1;
         
                dBoard();
 
             } // end if moves < length/4
        


            } // end frw button

  if(event.target==bkw_button){
   if(moves>0){     
  moves=moves-1;
 
    if(game1.charAt(4*moves+0)=='a'){xnew=1;}
    if(game1.charAt(4*moves+0)=='b'){xnew=2;}
    if(game1.charAt(4*moves+0)=='c'){xnew=3;}
    if(game1.charAt(4*moves+0)=='d'){xnew=4;}
    if(game1.charAt(4*moves+0)=='e'){xnew=5;}
    if(game1.charAt(4*moves+0)=='f'){xnew=6;}
    if(game1.charAt(4*moves+0)=='g'){xnew=7;}
    if(game1.charAt(4*moves+0)=='h'){xnew=8;}
    if(game1.charAt(4*moves+0)=='o'){castle=true;}
    if(game1.charAt(4*moves+1)=='8'){ynew=1;}
    if(game1.charAt(4*moves+1)=='7'){ynew=2;}
    if(game1.charAt(4*moves+1)=='6'){ynew=3;}
    if(game1.charAt(4*moves+1)=='5'){ynew=4;}
    if(game1.charAt(4*moves+1)=='4'){ynew=5;}
    if(game1.charAt(4*moves+1)=='3'){ynew=6;}
    if(game1.charAt(4*moves+1)=='2'){ynew=7;}
    if(game1.charAt(4*moves+1)=='1'){ynew=8;}

    if(game1.charAt(4*moves+2)=='a'){xold=1;}
    if(game1.charAt(4*moves+2)=='b'){xold=2;}
    if(game1.charAt(4*moves+2)=='c'){xold=3;}
    if(game1.charAt(4*moves+2)=='d'){xold=4;}
    if(game1.charAt(4*moves+2)=='e'){xold=5;}
    if(game1.charAt(4*moves+2)=='f'){xold=6;}
    if(game1.charAt(4*moves+2)=='g'){xold=7;}
    if(game1.charAt(4*moves+2)=='h'){xold=8;}
    if(game1.charAt(4*moves+3)=='x'){kside=true;}
    if(game1.charAt(4*moves+3)=='o'){kside=false;}
    if(game1.charAt(4*moves+3)=='8'){yold=1;}
    if(game1.charAt(4*moves+3)=='7'){yold=2;}
    if(game1.charAt(4*moves+3)=='6'){yold=3;}
    if(game1.charAt(4*moves+3)=='5'){yold=4;}
    if(game1.charAt(4*moves+3)=='4'){yold=5;}
    if(game1.charAt(4*moves+3)=='3'){yold=6;}
    if(game1.charAt(4*moves+3)=='2'){yold=7;}
    if(game1.charAt(4*moves+3)=='1'){yold=8;}
 // game1 defines next white move

 if((int)(moves/2)==(int)(moves+1)/2){
if(castle){
     if(kside){
           wset[12].xplace=5;
           wset[15].xplace=8;
         } //end kside
      else{
           wset[12].xplace=5;
           wset[8].xplace=1;
           } // end else qside
     castle=false;  } //end if castle 
  else{for(i=0;i<16;i++){

         if((wset[i].xplace==xold)&(wset[i].yplace==yold))
               {cobj=i;} // end if wset defines cobj for white
           } //end for i

           wset[cobj].xplace=xnew; 
           wset[cobj].yplace=ynew; 

     if(kills[moves]<32){
                 bset[kills[moves]-16].xplace=xold;
                 bset[kills[moves]-16].yplace=yold;
                 } // end unkills

     } // end not castle     
    }  // end if even
        
       else{  // if odd
if(castle){
     if(kside){
           bset[12].xplace=5;
           bset[15].xplace=8;
         } //end kside
      else{
           bset[12].xplace=5;
           bset[8].xplace=1;
           } // end else qside
     castle=false;  } //end if castle
else{for(i=0;i<16;i++){

           if((bset[i].xplace==xold)&(bset[i].yplace==yold))
           {cobj=i + 16;} // end if bset
            } //end for i

           bset[cobj-16].xplace=xnew; 
           bset[cobj-16].yplace=ynew; 

    if(kills[moves]<32){
                 wset[kills[moves]].xplace=xold;
                 wset[kills[moves]].yplace=yold;
                 } // end unkills white

      }  // end if not castle
      } // else odd
 



          dBoard();

        }  // end if moves>0
          return true;
         }  // end bkw button 

           // Otherwise let the superclass handle it.
           else return super.action(event, arg);
     }
}

