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

public class ConwayGR
             extends Applet implements Runnable{

   boolean Population [ ] [ ] = new boolean [ 20 ] [ 20 ];

   int generations = 0;

   Button Step, Restart, Run;
  
   Label LGenerations;

   Thread life;

   Image img;

   Graphics gImg;

   void initialize ( ) {
      int i, j, rand;

      generations = 0;
      for ( i = 0 ; i < 20 ; i ++ )
         for ( j = 0 ; j < 20 ; j ++ ) {
             rand = (int)(Math.random()*1000);
             if ( rand %2 == 1 )
                Population[i][j] = true;
             else
                Population[i][j] = false;
         }
   }

   boolean[][] next_generation( ) {
      boolean new_generation[][] = new boolean[20][20];
      int i, j;
      int k, l;
      int neighbours;

      for(i=0;i<20;i++)
         for(j=0;j<20;j++){
            neighbours = 0;
            for(k=-1;k<=1;k++)
               for(l=-1;l<=1;l++)
                  if ( ( ( i + k ) >=0 ) && ( ( j + l ) >= 0 ) 
                     && ( ( i + k ) <= 19 ) && ( ( j + l ) <= 19 ) 
                     && ( k != 0 || l != 0 ) )
                     if (Population[i+k][j+l])
                        neighbours = neighbours + 1;
            if ( Population[i][j] )
               if ( ( neighbours == 2 ) || ( neighbours == 3 ) )
                  new_generation[i][j] = true;
               else
                  new_generation[i][j] = false;
            else
               if ( neighbours == 3 )
                  new_generation[i][j] = true;
               else
                  new_generation[i][j] = false;
       }
       return(new_generation);
    }

   public void regenerate ( ) {
      generations = generations + 1;
      Population = next_generation();
      LGenerations.setText ( "Generation: " + generations + "     " );
   }

   public void init ( ) {
      int i, j;
      int rand;

      initialize ( );

      Step = new Button ( " Step " );
      Restart = new Button ( " Restart " );
      Run = new Button ( " Run 100" );
      LGenerations = new Label ( "Generation: " + generations + "     "); 

      add ( Step );
      add ( Restart );
      add ( Run );
      add ( LGenerations );
      img = createImage(500,600);
      gImg = img.getGraphics();
   }

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

   public void update ( Graphics g ) {

       int i, j;
 
       gImg.setColor ( Color.black );

       gImg.fillRect ( 0, 0, 500, 600 );

       gImg.setColor ( Color.red );

       for ( i = 100; i <= 600; i = i + 25 )
           gImg.drawLine ( 1, i, 500, i );

       for ( i = 1; i <= 500 ; i = i + 25 )
           gImg.drawLine ( i, 100, i, 600 );
           
       for ( i = 0; i < 20 ; i ++ )
           for ( j = 0; j < 20 ; j ++ ) {
               if ( Population [ i ] [ j ] )
                   gImg.setColor ( Color.green );
               else 
                   gImg.setColor ( Color.black );

               gImg.fillOval ( 8 + 25 * i, 108 + 25 * j, 10, 10 );
           }
        g.drawImage(img,0,0,this);
   }
   
   public boolean action ( Event e, Object o ) {
      if ( e.target == Step ){
          regenerate();
          repaint ( );
      }
      if ( e.target == Restart ) {
          initialize();
          LGenerations.setText ( "Generation: " + generations + "     ");
          repaint();
      }

      if ( e.target == Run ) {
         life = new Thread ( this );
         life.start();
      }
      return false;
   }

   public void run (){
      int i;
      for ( i = 0; i < 100; i ++ ){
          regenerate();
          repaint();
          try {
             life.sleep ( 100 );
          }catch (InterruptedException e) { }
     }
   }
}
