xxxxxxxxxx
// GOLly Dish, my cntribution to #WCCChallenge
// Inspired by "Petri Dish" by Kathy McGuiness – https://openprocessing.org/sketch/2606359/
// Instead of a random walker I determine the visits by the number of frames a cell
// has ben alive in my hexagonal GOL implementation.
var cfg = {
rowCols: 200,
len: 0,
dots: []
}
class Dot {
constructor(i, j) {
this.i = i;
this.j = j;
//Hex coordinates
this.x = cfg.len * (this.i + 0.5 * this.j % 2);
this.y = sqrt(0.5) * cfg.len * this.j;
this.rsqr = (this.x - width/2) ** 2 + (this.y - height / 2) ** 2;
//Set of relative coordinates for checking the neighbours
this.vec = [[-1,0], [-1,1], [0,1], [1,1], [1,0], [0,-1]];
// About 75% of the cells are alive at the start - and will instantly die from overpopulation
// before the second frame is drawn.
this.alive = random() > 0.15;
this.visits = 0;
this.action = 0;
// Only cells inside the circle are displayed
this.show_me = false;
if (this.rsqr < (width / 2.1) ** 2) {
this.show_me = true;
}
}
revive() {
//Development from the last step/ frame
if (this.action == 1) {
this.alive = true;
}
if (this.action == -1) {
this.alive = false;
}
}
check() {
//Reset action, should not be necessary
this.action = 0;
//Determine livin neighbours; only if two of them live, the cells becoes or stays alive
var livingNeighbours = 0;
for (var k = 0; k < 6; k++) {
var ti = (this.i + this.vec[k][0] + cfg.rowCols) % cfg.rowCols;
var tj = (this.j + this.vec[k][1] + cfg.rowCols * 1.4) % (cfg.rowCols * 1.4 );
var tAddr = ti + cfg.rowCols * tj;
if (cfg.dots[tAddr].show_me == cfg.dots[tAddr].alive) {
livingNeighbours++;
}
}
if (livingNeighbours == 2) {
this.action = 1;
} else {
this.action = -1;
}
if (this.alive) {
this.visits++;
}
}
show() {
// Display cell; living cells are isplayed slightly bigger and with a shade of blue;
// Independent from being actually alive, the times the cells has been alive in the ast, is coded by the green channel.
if (this.show_me) {
strokeWeight((0.1 * this.alive + 0.8 + 0.2 * noise(this.i, this.j)) * cfg.len);
stroke(50 + min(150, 5 * this.visits ** 0.333), min(250, sqrt(this.visits) * 10), 25 * this.alive);
point(this.x, this.y);
}
}
}
function setup() {
var a = min(windowWidth, windowHeight);
createCanvas(a,a);
cfg.len = a / cfg.rowCols;
for (var j = 0; j < cfg.rowCols * 1.4; j++) {
for (var i = 0; i < cfg.rowCols; i++) {
cfg.dots.push(new Dot(i,j));
}
}
}
function draw() {
frameRate(25);
background(0);
for (d of cfg.dots) {
d.check();
}
// Only frames > 1 are shown to hide the mass extinction at the beginning.
if (frameCount > 1) {
for (d of cfg.dots) {
d.show();
}
}
for (d of cfg.dots) {
d.revive();
}
stroke(0);
strokeWeight(cfg.len * 5);
noFill();
circle(width/2, height/2, width / 1.05);
//noLoop();
}