xxxxxxxxxx
149
cellSize = 8;
savedCells = [];
cells = [];
simActive = false; // Tracks whether the simulation is active
lastPaintedCell = null; // Stores the last painted cell for mouse actions
eraseMode = false; // Flag to toggle between painting and erasing
// Color picker for the alive cells
let colorPicker;
function setup() {
createCanvas(400, 400);
// Create a label and color picker for choosing the alive color
createSpan('<b>Select Alive Color:</b> ');
colorPicker = createColorPicker('#000000');
colorPicker.style('margin', '10px');
// Initialize the grid of cells
for (let y = 0; y < height; y += cellSize) {
for (let x = 0; x < width; x += cellSize) {
append(cells, new Cell(x, y));
}
}
// Set the adjacent cells for each cell in the grid
for (let i = 0; i < cells.length; i++) {
cells[i].setAdjacentCells();
}
savedCells = cells; // Save the initial cell state
// Create UI buttons for controlling the simulation
toggleSimButton = createButton("Start");
advanceStepButton = createButton("Advance");
clearSimButton = createButton("Clear");
toggleSimButton.mousePressed(toggleSim);
clearSimButton.mousePressed(clearSim);
advanceStepButton.mousePressed(advanceStep);
// Create dropdowns for simulation rules (grow, underpopulate, overpopulate)
createSpan('<b><br>Grow</b>');
grow = createSelect();
for (let i = 0; i <= 8; i++) grow.option(i); // Options for cell growth rule
grow.value(2);
createSpan('<b><br>Underpopulate</b>');
underpop = createSelect();
for (let i = 1; i <= 7; i++) underpop.option(i); // Options for underpopulation rule
underpop.value(4);
createSpan('<b><br>Overpopulate</b>');
overpop = createSelect();
for (let i = 2; i <= 8; i++) overpop.option(i); // Options for overpopulation rule
overpop.value(5);
}
// Toggle simulation active state
function toggleSim() {
simActive = !simActive;
if (simActive) {
saveCells();
frameRate(10);
} else {
frameRate(30);
}
}
//save and reset
function saveCells() {
savedCells = [];
for (let i = 0; i < cells.length; i++) {
append(savedCells, cells[i]);
}
}
function loadCells() {
cells = [];
for (let i = 0; i < savedCells.length; i++) {
append(cells, savedCells[i]);
}
}
// Clear the grid, resetting all cells
function clearSim() {
for (let i = 0; i < cells.length; i++) {
cells[i].alive = false; // Set each cell to be dead
cells[i].color = null;
simActive = false;
}
frameRate(30);
}
// Mouse released, reset the last painted cell
function mouseReleased() {
lastPaintedCell = null;
}
// Mouse pressed, toggle erase mode based on cell state
function mousePressed() {
let w = (width / cellSize);
let x = floor(mouseX / cellSize);
let y = floor(mouseY / cellSize);
let n = x + y * w;
if (cells[n] != null) {
eraseMode = cells[n].alive;
print(eraseMode);
}
}
// Advance the simulation by one step
function advanceStep() {
for (let i = 0; i < cells.length; i++) {
cells[i].getNeighborState();
}
for (let i = 0; i < cells.length; i++) {
cells[i].updateAliveState();
}
}
// Draw function, called continuously
function draw() {
// When mouse is pressed, toggle cell states or erase cells
if (mouseIsPressed) {
let w = (width / cellSize);
let h = (height / cellSize);
let x = floor(mouseX / cellSize);
let y = floor(mouseY / cellSize);
let n = x + y * w;
if (cells[n] != null) {
if (!eraseMode && !cells[n].alive) {
cells[n].color = colorPicker.color(); // Assign the selected color
}
cells[n].alive = !eraseMode; // Toggle the cell's alive state
}
}
if (simActive) {
advanceStep();
}
// Draw each cell in the grid
for (let i = 0; i < cells.length; i++) {
cells[i].draw();
}
}