import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class GameOfLife1 extends JPanel {

	final int DEAD = 0;
	final int ALIVE = 1;
	final int GRID_SIZE = 100;
	final int PIXEL_SIZE = 5;

	int grid1[][] = new int[GRID_SIZE][GRID_SIZE];
	int grid2[][] = new int[GRID_SIZE][GRID_SIZE];

	public static void main(String[] args) {
		JFrame top = new JFrame("Game of Life");
		top.setBounds(100, 100, 800, 600);
		top.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		GameOfLife1 gol1 = new GameOfLife1();
		top.getContentPane().add(gol1);
		
		GameOfLifeTask task = gol1.new GameOfLifeTask(gol1);
		task.start();

		top.setVisible(true);
	}

	public void paint(Graphics g) {
		// clear drawing area
		Rectangle bounds = getBounds();
		g.clearRect(bounds.x, bounds.y, bounds.width, bounds.height);

		// draw the grid
		for (int i = 0; i < GRID_SIZE; i++) {
			for (int j = 0; j < GRID_SIZE; j++) {
				int cell = grid1[i][j];
				if (cell == ALIVE) {
					g.setColor(Color.GREEN);
				} else {
					g.setColor(Color.BLUE);
				}
				int x = PIXEL_SIZE * i;
				int y = PIXEL_SIZE * j;
				g.fillRect(x, y, PIXEL_SIZE, PIXEL_SIZE);
			}
		}
	}

	private class GameOfLifeTask extends Thread {

		JPanel panel;
		public GameOfLifeTask(JPanel panel) {
			this.panel = panel;
		}

		public int random_cell() {
			if (Math.random() < 0.1) {
				return ALIVE;
			} else {
				return DEAD;
			}
		}
		
		public void run() {
			for (int i = 0; i < GRID_SIZE; i++) {
				for (int j = 0; j < GRID_SIZE; j++) {
					if (i == 0 || j == 0 || i == GRID_SIZE-1 || j == GRID_SIZE-1) {
						grid1[i][j] = DEAD;
					} else {
						grid1[i][j] = random_cell();
					}
				}
			}
			
			while (true) {
				// apply rules
				for  (int i = 1; i < GRID_SIZE - 1; i++) {
					for  (int j = 1; j < GRID_SIZE - 1; j++) {
						int neighbors = grid1[i-1][j-1] + grid1[i][j-1] + grid1[i+1][j-1];
						neighbors += grid1[i-1][j] + grid1[i+1][j];
						neighbors += grid1[i-1][j+1] + grid1[i][j+1] + grid1[i+1][j+1];
						int cell = grid1[i][j];
						if (cell == DEAD && neighbors == 3) {
							grid2[i][j] = ALIVE;
						} else if (cell == ALIVE && (neighbors < 2 || neighbors > 3)) {
							grid2[i][j] = DEAD;
						} else {
							grid2[i][j] = grid1[i][j];
						}
					}
				}

				// swap the two grids
				int[][] grid_temp = grid1;
				grid1 = grid2;
				grid2 = grid_temp;
				
				panel.repaint();

				try {
					sleep(250);
				} catch (InterruptedException e) {}
			}
		}
	}

}

