Cellular Automaton experiment

Unusual cellular automata with unlimited light-speed. C(x, y, 2t) = f(C(x, y, 2t-1), C(x, y-1, 2t), C(x+1, y-1, 2t)) C(x, y, 2t+1) = g(C(x, y, 2t), C(x, y+1, 2t+1), C(x-1, y+1, 2t+1))

by prophet

HTML

<canvas id="canvas" width="510" height="255" onmousemove="step();"></canvas>

CSS

canvas {
    padding: 5px;
    background-color: gray;
}

JavaScript

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = 255;
var height = 255;
var id = ctx.createImageData(2 * width, height);
var data = id.data;

var colors = [
    255, 255, 255,
    0, 0, 0,
];

var rules = [
    1, 0, 0, 1,
    1, 0, 0, 0,

    0, 1, 1, 1,
    1, 1, 0, 0
];

var field = [];
//for (var i=0; i<width*height; i++) {
//    field[i] = Math.floor(Math.random() * 2);
//}
for (var y=0; y<height; y++) {
    for (var x=0; x<width; x++) {
        field[width * y + x] = (x + 2 * y) % 3 % 2;
    }
}
for (var i=0; i<width; i++) {
    field[i] = Math.floor(Math.random() * 2);
}

function draw() {
    for (var y=0; y<height; y++) {
        for (var x=0; x<width; x++) {
            var a = y + 2 * x;
            var b = 2 * width * y;
            var idx1 = 4 * (b + a % (2 * width));
            var idx2 = 4 * (b + (a + 1) % (2 * width));
            var c = 3 * field[width * y + x];

            data[idx1    ] = data[idx2    ] = colors[c    ];
            data[idx1 + 1] = data[idx2 + 1] = colors[c + 1];
            data[idx1 + 2] = data[idx2 + 2] = colors[c + 2];
            data[idx1 + 3] = data[idx2 + 3] = 255;
        }
    }
    ctx.putImageData(id, 0, 0);
}

function step1() {
    for (var y=1; y<height; y++) {
        for (var x=0; x<width; x++) {
            field[width * y + x] = rules[
                4 * field[width * y + x] +
                2 * field[width * (y - 1) + x] +
                field[width * (y - 1) + (x + 1) % width]];
        }
    }
}

function step2() {
    for (var y=height-2; y>=0; y--) {
        for (var x=0; x<width; x++) {
            field[width * y + x] = rules[
                8 +
                4 * field[width * y + x] +
                2 * field[width * (y + 1) + x] +
                field[width * (y + 1) + (x + width - 1) % width]];
        }
    }
}

var dir = false;

window.step = function() {
    if (dir) { step1(); }
    else { step2(); }
    draw();
    dir = !dir;
}

draw();