Here we initialize the system with an unusual breeder: a configuration of cells that generate secondary and tertiary patterns in its wake. Click on the simulation to reset to a random state.
Next: Automaton Explorer
<html>
<head>
<title>Conway’s Game of Life</title>
<link type="text/css" rel="stylesheet" href="ex.css?3.2"/>
<script type="text/javascript" src="../protovis-r3.2.js"></script>
<script type="text/javascript" src="life.js"></script>
<script type="text/javascript" src="breeder.js"></script>
<style type="text/css">
body {
background: #222;
}
#fig {
width: 300px;
height: 300px;
}
</style>
</head>
<body><div id="center"><div id="fig">
<script type="text/javascript+protovis">
var vis = new pv.Panel()
.width(life.size * 2)
.height(life.size * 2);
vis.add(pv.Image)
.def("init", function() life.update())
.imageWidth(life.size)
.imageHeight(life.size)
.image(pv.colors(null, "#0f0").by(function(i, j) life[j * life.size + i]))
.event("click", function() life.reset());
vis.render();
setInterval(function() vis.render(), 42);
</script>
</div></div></body>
</html>
var life = [];
life.neighbors = [];
life.neighbors.add = function(x, y, v) {
for (var i = x - 1; i <= x + 1; i++) {
for (var j = y - 1; j <= y + 1; j++) {
this[i * life.size + j] += v;
}
}
this[x * life.size + y] -= v;
};
life.reset = function(source) {
if (!arguments.length) {
source = [];
source.size = 150;
for (var x = 0, p = 0; x < source.size; x++) {
for (var y = 0; y < source.size; y++, p++) {
source[p] = Math.random() > .5 ? 1 : 0;
}
}
}
life.size = source.size;
for (var x = 0, p = 0; x < life.size; x++) {
for (var y = 0; y < life.size; y++, p++) {
life[p] = source[p];
life.neighbors[p] = 0;
}
}
for (var x = 0, p = 0; x < life.size; x++) {
for (var y = 0; y < life.size; y++, p++) {
if (life[p]) {
life.neighbors.add(x, y, 1);
}
}
}
};
life.update = function() {
var neighbors = this.neighbors.concat();
for (var x = 0, p = 0; x < life.size; x++) {
for (var y = 0; y < life.size; y++, p++) {
if (this[p]) {
if ((neighbors[p] < 2) || (neighbors[p] > 3)) {
this.neighbors.add(x, y, -1);
this[p] = 0;
}
} else if (neighbors[p] == 3) {
this.neighbors.add(x, y, 1);
this[p] = 1;
}
}
}
};
See also breeder.js.