xxxxxxxxxx
122
// @description : Celullar Automata with infinite canvas, rule switching to randomly chosen one, stop if all cells are 0 or 1 to prevent "repetitive all 0 and 1"
// @author : Esprit Orgue
// -------------------------------------------------------------------------
// Cell Size
const cS = 10;
// Rule value (not necessary if ruleRandom is true)
const ruleValue = 90;
// -------------------------------------------------------------------------
// Randomly choose a rule value
const ruleRandom = true
// Allow Switching rule value. Needs ruleRandom to be true
const ruleSwitch = true
// Percentage of chance the value of the rule will change. Needs ruleSwitch to be true
const ruleSwitchPercent = 0.1
// -------------------------------------------------------------------------
// Randomly set initial cells, otherwise only set the middle one.
const randomCells = true;
// -------------------------------------------------------------------------
// Allow infinite scroll, otherwise, stop at step
const infinite = true
// Set the number of step before stopping the loop. Not needed if infinite is set
const step = 100
// -------------------------------------------------------------------------
// Cells array
let c = [];
// Cells height
let y;
// Step counter. Not needed if infinite is true
let stepCount = 0;
// Binary rule
let ruleSet
function setup() {
y = cS;
if(!ruleRandom){
ruleSet = ruleValue.toString(2).padStart(8, "0")
}else{
ruleSet = floor(random(256)).toString(2).padStart(8, "0")
//let p = createP(`Rule ${parseInt(ruleSet,2).toString()}`)
//p.elt.id = "ruleP"
}
createCanvas(windowWidth - (windowWidth % cS), y)
y = 0;
c[0] = [];
if (randomCells) {
for (let i = 0; i < floor(width / cS); i++) {
c[0].push(floor(random(2)));
}
} else {
for (let i = 0; i < floor(width / cS); i++) {
c[0].push(0);
}
c[0][floor(c[0].length / 2)] = 1;
}
}
function draw() {
// Behaviour if all 1 or 0 is strange, blocking it when first seen
if(c[c.length-1].every((a)=>a==0)||c[c.length-1].every((a)=>a==1)){
noLoop()
}
// Random + Switch rule
if(ruleRandom && ruleSwitch){
if(random()<ruleSwitchPercent){
ruleSet = floor(random(256)).toString(2).padStart(8, "0")
//select("#ruleP").elt.innerText += ` - ${parseInt(ruleSet,2).toString()}`
}
}
// if infinite is false, stop after step. Better for slow perf computer !
if(!infinite)if (stepCount > step) noLoop();
noStroke();
y += cS;
resizeCanvas(width, y);
window.scrollTo(0, document.body.scrollHeight);
for (let i = 0; i < c.length; i++) {
for (let j = 0; j < c[i].length; j++) {
fill(255 - c[i][j] * 255);
square(j * cS, i * cS, cS);
}
}
let index = c.length;
let len = c[index - 1].length;
c[index] = [];
for (let i = 0; i < c[index - 1].length; i++) {
// Calculate the states of neighboring cells
let left = c[index - 1][(i - 1 + len) % len];
let right = c[index - 1][(i + 1) % len];
let state = c[index - 1][i];
// Set the new state based on the current state and neighbors.
let newState = calculateState(left, state, right);
c[index][i] = newState;
}
if(stepCount>=0)stepCount++;
}
function calculateState(a, b, c) {
// Create a string representing the state of the cell and its neighbors.
let neighborhood = "" + a + b + c;
// Convert the string to a binary number
let value = 7 - parseInt(neighborhood, 2);
// Return the new state based on the ruleset.
return parseInt(ruleSet[value]);
}
// Try to stop canvas generating with "P" key
function keyPressed(){
if(keyCode == 80){
if(isLooping())noLoop()
else{
loop()
stepCount = 0
}
}
}