xxxxxxxxxx
143
let cols, rows;
let grid = [];
let nextGrid = [];
let previousGrid = [];
const hexSize = 10; // Hexagon size
let frameRateSlider; // Slider for adjusting frame rate
let totalIterations = 0;
let maxIterationsBeforeChange = 40; // Maximum iterations before forcing a ruleset change
let rulesetChanged = false;
let reversedBack = false;
function setup() {
createCanvas(1100, 1000);
cols = int(width / (hexSize * 1.5));
rows = int(height / (sqrt(3) * hexSize));
for (let i = 0; i < cols; i++) {
let gridRow = [];
for (let j = 0; j < rows; j++) {
gridRow.push(random() < 0.7); // Initial live cells
}
grid.push(gridRow);
nextGrid.push([gridRow]);
previousGrid.push([gridRow]);
}
// Slider for frame rate control
frameRateSlider = createSlider(1, 60, 15);
frameRateSlider.position(10, height + 10);
}
function draw() {
frameRate(frameRateSlider.value());
background(255);
noStroke();
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let x = i * hexSize * 1.5 + hexSize;
let y = j * sqrt(3) * hexSize + hexSize;
if (i % 2 == 0) {
y += sqrt(3) * hexSize / 2;
}
if (grid[i][j]) {
fill(50, 225, 50); // Green for live cells
} else if (previousGrid[i][j]) {
fill(255, 0, 0); // Red for recently dead cells
} else {
fill(255); // White for dead cells
}
drawHexagon(x, y, hexSize);
}
}
updateGrid();
}
function drawHexagon(x, y, size) {
beginShape();
for (let i = 0; i < 6; i++) {
let angle = TWO_PI / 6 * i;
let vx = x + cos(angle) * size;
let vy = y + sin(angle) * size;
vertex(vx, vy);
}
endShape(CLOSE);
}
function mouseDragged() {
let col = int(mouseX / (hexSize * 1.5));
let row = int(mouseY / (sqrt(3) * hexSize));
if (col >= 0 && col < cols && row >= 0 && row < rows) {
grid[col][row] = true; // Set cell to alive
}
}
function calculateNeighbors(col, gridRow) {
let count = 0;
let neighborPositions = col % 2 === 0 ?
[[-1, 0], [0, -1], [1, -1], [-1, 1], [0, 1], [1, 0]] :
[[-1, -1], [0, -1], [1, 0], [-1, 1], [0, 1], [1, -1]];
neighborPositions.forEach(pos => {
let newCol = col + pos[0];
let newRow = gridRow + pos[1];
if (newCol >= 0 && newCol < cols && newRow >= 0 && newRow < rows) {
count += grid[newCol][newRow];
}
});
return count;
}
function updateGrid() {
for (let col = 0; col < cols; col++) {
for (let gridRow = 0; gridRow < rows; gridRow++) {
let neighbors = calculateNeighbors(col, gridRow);
let newCellState = calculateNewCellState(grid[col][gridRow], neighbors);
nextGrid[col][gridRow] = newCellState;
}
}
totalIterations++;
if (!rulesetChanged && totalIterations > maxIterationsBeforeChange) {
rulesetChanged = true;
totalIterations = 0; // Reset total iterations
}
if (rulesetChanged && !reversedBack) {
if (totalIterations > maxIterationsBeforeChange) {
reversedBack = true;
totalIterations = 0; // Reset total iterations
}
}
if (reversedBack && totalIterations > maxIterationsBeforeChange) {
reversedBack = false;
rulesetChanged = false;
totalIterations = 0; // Reset total iterations
}
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
previousGrid[i][j] = grid[i][j];
}
}
let temp = grid;
grid = nextGrid;
nextGrid = temp.map(gridRow => [gridRow]);
}
function calculateNewCellState(currentState, neighbors) {
if (!reversedBack) {
if (!rulesetChanged) {
return (!currentState && neighbors === 3) || (currentState && (neighbors === 2 || neighbors === 3));
} else {
return (!currentState && (neighbors === 2 || neighbors === 3)) || (currentState && (neighbors >= 1 && neighbors <= 4));
}
} else {
return (!currentState && neighbors === 3) || (currentState && (neighbors === 2 || neighbors === 3));
}
}