import java.awt.*;
import java.util.Random;

/*


 operations:
     turn cells on/off
    check to see if a cell should be born/die
    compute the next generation
    clear the graph

*/


public class GameOfLife {
  
  private boolean[][] board;
  private int width;
  private int height;
 
  public GameOfLife( int w, int h ) {
    board = new boolean[w][h];
    width = w;
    height = h;
  }
  
  
  public void setCell( int x, int y, boolean b ) {
    board[x][y] = b;
  }
  
  
  public void fillWithRandom( double density ) {
    Random rgen = new Random();
    
    for ( int x = 0; x < width; x++ ) {
      for ( int y = 0; y < height; y++ ) {
        double val = rgen.nextDouble();
        board[x][y] = ( val <= density );
      }
    }
    
  }
  
  
  public boolean contains( int x, int y ) {
    return (x >= 0 && x < width && y >= 0 && y < height);
  }
  
  
  public boolean checkNextState( int x, int y ) {
    boolean nextState = board[x][y];
    int numAlive = 0;
    
    // figure out number of live neighboring cells
    for ( int i = -1; i <= 1; i++ ) {
      for ( int j = -1; j <= 1; j++ ) {
        if ( contains(x+i, y+j) && board[ x + i ][ y + j ] && !( i==0 && j==0 ) )
                                               /*(i!=0 || j!=0)*/
          numAlive++;
      }
    }
    
    // check next state
    if ( numAlive == 3 )
      nextState = true;
    if ( numAlive == 0 || numAlive == 1 || numAlive >= 4 )
      nextState = false;
    
    return nextState;
  }
  
  public void nextGeneration( ) {
    int x = 0;
    int y = 0;
    
    boolean[][] nextBoard = new boolean[width][height];
    
    for ( x = 0; x < width; x++ ) {
      for ( y = 0; y < height; y++ ) {
        nextBoard[x][y] = checkNextState( x, y );
      }
    }
    
    board = nextBoard;
  }
  
  public void clearBoard() {
    for ( int x = 0; x < width; x++ ) {
      for ( int y = 0; y < height; y++ ) {
        setCell( x, y, false );
      }
    }
  }
  
  
  public void printBoard() {
    String output = "";
    for ( int y = 0; y < height; y++ ) {
      for ( int x = 0; x < width; x++ ) {
        output += ( board[x][y] ? '#' : ' ' );
      }
      output += "\n";
    }
    
    System.out.println( output );
  }
  
  
  public void draw( Graphics2D g2 ) {
    g2.setColor( Color.BLUE );
    g2.fill( new Rectangle( 0, 0, width * 10, height * 10 ) );
    g2.setColor( Color.BLACK );
    
    for ( int y = 0; y < height; y++ ) {
      for ( int x = 0; x < width; x++ ) {
        Rectangle r = new Rectangle( x * 10, y * 10, 10, 10 );
        if ( board[x][y] ) 
          g2.fill( r );
        else
          g2.draw( r );
      }
    }
  }
  
  
  
  
  
}