import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

public class OneDimensionalAutomaton extends JFrame
{
	private int rule = 110;
	private int width = 1600;
	private int height = 800;

	private boolean rules[] = new boolean[8];
	private int pixels[] = new int[width*height];
	private Image image;

	public OneDimensionalAutomaton() {
		// create rules index array
		for (int i = 0, m = 1; i < 8; i++, m *= 2) rules[i] = (rule & m) > 0;

		// print rules index array
		for (int i = 0; i < 8; i++) {
			for (int j = 4; j > 0; j /= 2) {
				System.out.print((i & j) > 0 ? "1" : "0");
			}
			System.out.println();
			System.out.println(" " + (rules[i] ? "1" : "0"));
		}
		
		// fill pixels
		boolean b[] = new boolean[width];
		int j = 0;
		String s = "11111000100110";
//		String s = "1110";
//		String s = "11111000111111010";
		for (int i = 0; i < width; i++) {
			if (s.charAt(j) == '1') b[i] = true;
			if (++j == s.length()) j = 0;
			if (Math.random() < 0.09) {
				if (Math.random() < 0.5) {
					b[i] = true;
				} else {
					b[i] = false;
				}
			}
		}
		boolean b2[] = new boolean[width];
		int bitFalse = (new Color(255, 255, 255)).getRGB();
		int bitTrue = (new Color(0, 0, 0)).getRGB();
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				int i = 0;
				if (x == width - 1) {
					if (b[0]) i += 1;
				} else {
					if (b[x + 1]) i += 1;
				}
				if (b[x]) i += 2;
				if (x == 0) {
					if (b[width - 1]) i += 4;
				} else {
					if (b[x - 1]) i += 4;
				}
				pixels[x + y * width] = b[x] ? bitTrue : bitFalse;
				b2[x] = rules[i];
			}
			boolean tmp[] = b2; b2 = b; b = tmp;
		}
		
		// create image
		image = Toolkit.getDefaultToolkit().createImage(
			new MemoryImageSource(width, height, ColorModel.getRGBdefault(), pixels, 0, width)
		);

		// show frame with image		
		setSize(width + 20, height + 120);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public void paint(Graphics g) {
		g.drawImage(image, 8, 100, this);
	}

	public static void main(String args[]) {
		new OneDimensionalAutomaton();
	}
}
