mindjack/content/hypno/hex/hex.js

209 lines
4.5 KiB
JavaScript

var grid = document.getElementById("grid");
var cellsize = 60;
var width = Math.ceil(window.innerWidth / cellsize) + 1;
var height = Math.ceil(window.innerHeight / (cellsize*Math.sqrt(3)/2));
function xCoord(i, j) {
var x = i + j/2;
if (x > width - 1) {
x = x - width;
}
return x;
}
function yCoord(i, j) {
return Math.sqrt(3)*j/2;
}
var cells = new Array(width);
for (var i = 0; i < width; ++i) {
cells[i] = new Array(height);
for (var j = 0; j < height; ++j) {
cells[i][j] = document.createElement("div");
cells[i][j].classList.add("cell");
cells[i][j].classList.add("alive");
spiral = document.createElement("img");
spiral.classList.add("spiral");
spiral.src = "spiral.svg";
cells[i][j].appendChild(spiral);
hex = document.createElement("img");
hex.classList.add("hex");
hex.src = "hex.svg";
cells[i][j].appendChild(hex);
cells[i][j].style.position = "absolute";
cells[i][j].style.left = xCoord(i, j)*cellsize + "px";
cells[i][j].style.bottom = yCoord(i, j)*cellsize + "px";
grid.appendChild(cells[i][j]);
}
}
function prebirth(i, j) {
cells[i][j].classList.add("birthing");
}
function prekill(i, j) {
cells[i][j].classList.add("dying");
}
function birth(i, j) {
cells[i][j].classList.remove("dead");
cells[i][j].classList.add("alive");
}
function kill(i, j) {
cells[i][j].classList.remove("alive");
cells[i][j].classList.add("dead");
}
function update(i, j) {
var cl = cells[i][j].classList;
if (cl.contains("birthing")) {
cl.remove("birthing");
birth(i, j);
}
if (cl.contains("dying")) {
cl.remove("dying");
kill(i, j);
}
}
function isAlive(i, j) {
return !cells[i][j].classList.contains("dead");
}
function rotate(a) {
a.push(a.shift());
}
function arraysEq(a, b) {
if (a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function arraysRotatedEq(a, b) {
if (a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; ++i) {
if (arraysEq(a, b)) {
return true;
}
rotate(b);
}
return false;
}
function mod(m, n) {
return ((m % n) + n) % n;
}
function ip(i) {
return mod(i-1, width);
}
function is(i) {
return mod(i+1, width);
}
function jp(j) {
return mod(j-1, height);
}
function js(j) {
return mod(j+1, height);
}
function ll(i, j) {
return isAlive(ip(i), j);
}
function dl(i, j) {
return isAlive(i, jp(j));
}
function dr(i, j) {
return isAlive(is(i), jp(j));
}
function rr(i, j) {
return isAlive(is(i), j);
}
function ur(i, j) {
return isAlive(i, js(j));
}
function ul(i, j) {
return isAlive(ip(i), js(j));
}
function neighbors(i, j) {
return [ll(i, j), dl(i, j), dr(i, j), rr(i, j), ur(i, j), ul(i, j)];
}
function neighborsCount(i, j) {
return neighbors(i, j).filter(function (b) { return b; }).length;
}
function golay(i, j) {
var n = neighbors(i, j);
var g1 = [true, true, false, false, false, false];
var g2 = [true, false, true, false, false, false];
return (arraysRotatedEq(n, g1) || arraysRotatedEq(n, g2));
}
function preston(i, j) {
var n = neighbors(i, j);
var p1 = [true, true, false, false, false, false];
var p2 = [true, false, true, false, false, false];
return (isAlive(i, j) && (arraysRotatedEq(n, p1) || arraysRotatedEq(n, p2))) || (!isAlive(i, j) && neighborsCount(i, j) === 2);
}
function golayStep() {
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
if (golay(i, j)) {
prebirth(i, j);
} else {
prekill(i, j);
}
}
}
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
update(i, j);
}
}
}
function prestonStep() {
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
if (preston(i, j)) {
prebirth(i, j);
} else {
prekill(i, j);
}
}
}
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
update(i, j);
}
}
}
for (var i = 0; i < width; ++i) {
for (var j = 0; j < height; ++j) {
if (Math.floor(Math.random()*2) === 0) {
kill(i, j);
}
}
}
setInterval(prestonStep, 1000);