Home
|
Course Outline
|
Lectures
|
Homework
|
Files
The following applet is based on the program CA1.java, which is a translation of PROGRAM ca1 on pages 503-504 of the textbook.
Here is the code which generates this applet:
// CA1.java
import comphys.graphics.*;
import java.awt.event.*;
public class CA1 extends Animation {
int[] update = new int[8];
int maxL = 500;
int[] site = new int[maxL + 2];
int[] initialSite = new int[maxL + 2];
int[] previousSite = new int[maxL + 2];
int rule = 90;
void setrule () {
int r = rule;
int powerOf2 = 128;
for (int i = 0; i < 8; i++) {
update[i] = r / powerOf2;
r -= powerOf2 * update[i];
powerOf2 /= 2;
}
}
int L = 20;
int t = 0;
static final int DEAD = 0;
static final int ALIVE = DEAD + 1;
static final int RANDOM = ALIVE + 1;
int initialConfig = RANDOM;
boolean singleSite;
void initial () {
t = 0;
for (int i = 1; i <= L; i++) {
initialSite[i] = DEAD;
if (singleSite) {
if (i == L / 2)
initialSite[i] = ALIVE;
} else {
if (initialConfig == ALIVE)
initialSite[i] = ALIVE;
else if (initialConfig == RANDOM && Math.random() < 0.5)
initialSite[i] = ALIVE;
}
previousSite[i] = site[i] = initialSite[i];
}
// boundary conditions
initialSite[0] = previousSite[0] = site[0] = site[L];
initialSite[L+1] = previousSite[L+1] = site[L+1] = site[1];
needToClear = true;
}
void stepInTime () {
++t;
for (int i = 1; i <= L; i++) {
int index = 4 * previousSite[i - 1]
+ 2 * previousSite[i] + previousSite[i + 1];
site[i] = update[index];
}
for (int i = 1; i <= L; i++) {
previousSite[i] = site[i];
}
site[0] = previousSite[0] = site[L];
site[L + 1] = previousSite[L + 1] = site[1];
}
boolean sameAsPrevious () {
for (int i = 1; i <= L; i++)
if (site[i] != previousSite[i])
return false;
return true;
}
boolean sameAsInitial () {
for (int i = 1; i <= L; i++)
if (site[i] != initialSite[i])
return false;
return true;
}
boolean needToClear;
class Evolution extends Plot {
double xSize = 400;
double ySize = 400;
public void paint () {
if (needToClear) {
clear();
needToClear = false;
}
setWindow(0, xSize, 0, ySize);
double dx = xSize / L;
int d = (int) dx - 1;
if (d < 2)
d = 2;
int timeSteps = L;
double x0 = 0;
double y = 0;
// draw initial configuration at bottom of picture
if (t == 0) {
setColor("red");
for (int i = 0; i < L; i++) {
if (initialSite[i+1] == ALIVE) {
double x = x0 + i * dx;
boxArea(x, x + d, y, y + d);
}
}
}
int row = t % timeSteps;
y = row * dx;
setColor("white");
boxArea(0, xSize, y, y + d);
if (sameAsInitial())
setColor("red");
else
setColor("black");
for (int i = 0; i < L; i++) {
if (site[i + 1] == ALIVE) {
double x = x0 + i * dx;
boxArea(x, x + d, y, y + d);
}
}
}
}
class RuleWindow extends Plot implements MouseListener {
int xPixels = 400;
int yPixels = 70;
RuleWindow () {
setSize(xPixels, yPixels);
addMouseListener(this);
}
String[] states = { "111", "110", "101", "100",
"011", "010", "001", "000" };
public void paint () {
setWindow(0, xPixels, 0, yPixels);
clear();
setColor("blue");
boxArea(0, xPixels, 0, yPixels);
setColor("white");
int dx = xPixels / 9;
int x0 = dx / 2;
int dy = 20;
int y = yPixels - dy;
plotString("Binary local rule (click to change bit)" +
" Time step = " + t, x0, y);
y -= dy;
for (int i = 0; i < 8; i++) {
plotString(states[i], x0 + i * dx, y);
plotString("" + update[i], x0 + 8 + i * dx, y - dy);
}
}
public void mouseClicked (MouseEvent me) { }
public void mouseEntered (MouseEvent me) { }
public void mouseExited (MouseEvent me) { }
public void mousePressed (MouseEvent me) {
int dx = xPixels / 9;
int x0 = dx / 2;
int i = (me.getX() - x0) / dx;
int j = me.getY();
if (j > 20 && j < 70 && i >= 0 && i < 8) {
if (update[i] == 0)
update[i] = 1;
else
update[i] = 0;
repaint();
getrule();
}
}
public void mouseReleased (MouseEvent me) { }
}
Evolution evolution;
RuleWindow ruleWindow;
Reader LReader, ruleReader, singleSiteReader;
public void init () {
initial();
setrule();
add(evolution = new Evolution());
add(ruleWindow = new RuleWindow());
add(LReader = new Reader("L = ", L));
add(ruleReader = new Reader("Decimal rule", rule));
add(singleSiteReader = new Reader("Single site", singleSite));
addControlPanel();
}
public void step () {
stepInTime();
evolution.repaint();
ruleWindow.repaint();
}
public void reset () {
L = LReader.readInt();
rule = ruleReader.readInt();
singleSite = singleSiteReader.readBoolean();
setrule();
initial();
needToClear = true;
evolution.repaint();
ruleWindow.repaint();
}
void getrule () {
rule = 0;
int powerOf2 = 128;
for (int i = 0; i < 8; i++) {
rule += powerOf2 * update[i];
powerOf2 /= 2;
}
ruleReader.setInt(rule);
ruleWindow.repaint();
}
public static void main (String[] args) {
CA1 ca1 = new CA1();
ca1.frame("One-dimensional Boolean cellular automaton", 430, 650);
}
}