import java.util.Random;

import java.awt.*;

/**

*   This class defines a Cellular Automaton (CA).

*   @author CS100J - Fall 2000

*   @version 2.0

*/

public class CA {

 

     /** Current state of the automaton */

     private int[] state;

     /** Number of cells in the automaton */

     private final int LENGTH;

 

    

     /** Constructor */

     public CA ( int length, boolean isRandom )

     {

          LENGTH = length;

          state = new int[ LENGTH ];

          if ( isRandom )

          {

               Random rand = new Random();

              for( int i = 0; i < LENGTH; i++ )

                   state[ i ] = Math.abs( rand.nextInt()%2 );

          }

          else

              state[ length/2 ] = 1;

     }

    
/**

     *   Operate on the current state to obtain the next state using a supplied

     *   set of rules.

     *   @param rules the rule set

     */

     public void updateState( int[] rules )

     {

          // indices of left, current, and right cell

          int left, middle, right;

          // instantiate new array to hold the updated state

          int[] tempState = new int[ LENGTH ];

          for(int i=0;i < LENGTH;i++)

          {

              left = state[ ( i + LENGTH - 1 )%LENGTH ];

               middle = state[ i ];

              right = state[ (i + 1+ LENGTH )%LENGTH ];

               tempState[ i ] = rules[ conv( left, middle, right) ];

          }

          // assign current state to new state

          state = tempState;  

     }

    

         

     /**

     *   Converts three 0/1 values to an integer value

     *   @param x,y,z the digits of the binary number

     */

     private int conv( int x, int y, int z )

     {

          return x*4+ y*2 + z;

     }

    

     /**

     *   Prints the current state on the console window

     */

     public void printState( )

     {

          for (int i = 0; i < state.length; i++ )

               System.out.print( state[ i ] + " " );

          System.out.println();

     }

    

     /**

     *   Draws current state on the gui

     *   @param k   k specifies the  y-coordinate of the state

     *   @param g graphics context passed from class CAProgram

     */

     public void drawState( int k, Graphics g )

     {

 

          int stretch = 10;

          for(int i=0;i < LENGTH;i++) {

               GraphicsUtil.fillRect( g, i*stretch, k*stretch, stretch, stretch,

                   ( state[ i ] == 0 ? Color.white : Color.blue ) );

               GraphicsUtil.drawRect( g, i*stretch, k*stretch, stretch, stretch,

                    Color.black );

          }

     }

 

    

}