Conway's Game of Life · llama-3.1-8b-instruct
No runnable output Cost / run $0.0012 Runtime 13.1s
Prompt for this run
Build Conway's Game of Life on a canvas with a 60 by 40 grid and finite, non-wrapping boundaries. Use HTML, CSS, and JavaScript as needed. Write it to `index.html` in the current working directory using your file tools. Inline your own CSS and JavaScript. Do not use external assets, CDNs, or network requests. No third-party libraries are provided. Required behavior: - Apply the standard rules simultaneously: a live cell survives with two or three live neighbors, and a dead cell becomes live with exactly three. Treat cells outside the grid as dead. - Start paused with a visible blinker pattern. Provide Play/Pause, Step, Randomize, and Clear, plus a generation counter. - While paused, clicking toggles a cell. On a drag, choose painting alive or dead from the first cell and apply that same state to each visited cell, without repeatedly toggling it. - Step advances exactly one generation while paused. Randomize and Clear leave the simulation paused and reset the generation counter; Clear removes all live cells. - Fit the grid and controls within the viewport while keeping cells distinguishable. Verify: Step the initial blinker twice and compare its alternating arrangements. Paint a short stroke while paused and check consistent cell painting, then use Clear and confirm the grid and generation counter reset.
This one-shot run produced no runnable artifact.
Error: agent produced no index.html
The transcript below shows what the model did — read it to see why the one shot fell short.
TAKE IT TO CODE
This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.
RUN
METRICS
Transcript · 7 messages
Build Conway's Game of Life on a canvas with a 60 by 40 grid and finite, non-wrapping boundaries. Use HTML, CSS, and JavaScript as needed. Write it to `index.html` in the current working directory using your file tools. Inline your own CSS and JavaScript. Do not use external assets, CDNs, or network requests. No third-party libraries are provided. Required behavior: - Apply the standard rules simultaneously: a live cell survives with two or three live neighbors, and a dead cell becomes live with exactly three. Treat cells outside the grid as dead. - Start paused with a visible blinker pattern. Provide Play/Pause, Step, Randomize, and Clear, plus a generation counter. - While paused, clicking toggles a cell. On a drag, choose painting alive or dead from the first cell and apply that same state to each visited cell, without repeatedly toggling it. - Step advances exactly one generation while paused. Randomize and Clear leave the simulation paused and reset the generation counter; Clear removes all live cells. - Fit the grid and controls within the viewport while keeping cells distinguishable. Verify: Step the initial blinker twice and compare its alternating arrangements. Paint a short stroke while paused and check consistent cell painting, then use Clear and confirm the grid and generation counter reset.
<write>{<!DOCTYPE html><html><head><style> canvas { border: 1px solid black; } </style></head><body><canvas id="game" width="600" height="400"></canvas><button id="playpause">Play/Pause</button><button id="step">Step</button><button id="randomize">Randomize</button><button id="clear">Clear</button><p id="generations">Generations: 0</p></body><script>function generateGrid(rows, cols) { var grid = []; for (var r = 0; r < rows; r++) { grid.push([]); for (var c = 0; c < cols; c++) { grid[r].push(Math.random() > 0.8 ? 1 : 0); } } return grid; } function drawGrid(grid, canvas) { var ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, canvas.width, canvas.height); for (var r = 0; r < grid.length; r++) { for (var c = 0; c < grid[r].length; c++) { if (grid[r][c] == 1) { ctx.fillStyle = "black"; } else { ctx.fillStyle = "white"; } ctx.fillRect(c * 15, r * 15, 15, 15); } } } function getNeighbors(grid, r, c) { var n = 0; for (var i = -1; i <= 1; i++) { for (var j = -1; j <= 1; j++) { if (i != 0 || j != 0) { n += grid[r+i][c+j]; } } } return n; } function nextGeneration(grid) { var newGrid = []; for (var r = 0; r < grid.length; r++) { newGrid.push([]); for (var c = 0; c < grid[r].length; c++) { var n = getNeighbors(grid, r, c); if (grid[r][c] == 1 && (n == 2 || n == 3)) { newGrid[r].push(1); } else if (grid[r][c] == 0 && n == 3) { newGrid[r].push(1); } else { newGrid[r].push(0); } } } return newGrid; } function isPausing() { return document.getElementById("playpause").textContent == "Play"; } document.getElementById("game").addEventListener("click", function(e) { var rect = document.getElementById("game").getBoundingClientRect(); var x = Math.floor((e.clientX - rect.left) / 15); var y = Math.floor((e.clientY - rect.top) / 15); var grid = gridState; if (isPausing()) { if (selectedState) { grid[y][x] = selectedState; } else { grid[y][x] = 1 - grid[y][x]; } } }); document.getElementById("game").addEventListener("mousedown", function(e) { var rect = document.getElementById("game").getBoundingClientRect(); var x = Math.floor((e.clientX - rect.left) / 15); var y = Math.floor((e.clientY - rect.top) / 15); if (e.buttons == 1) { selectedState = 1; paintingAlive = true; } else if (e.buttons == 2) { selectedState = 0; paintingAlive = true; } selectedX = x; selectedY = y; }); document.getElementById("game").addEventListener("mousemove", function(e) { var rect = document.getElementById("game").getBoundingClientRect(); var x = Math.floor((e.clientX - rect.left) / 15); var y = Math.floor((e.clientY - rect.top) / 15); if (selectedState && paintingAlive) { for (var r = selectedY; r <= y; r++) { for (var c = (r == selectedY) ? selectedX : x; c <= x; c++) { if (r >= 0 && c >= 0 && r < gridState.length && c < gridState[r].length) { gridState[r][c] = selectedState; } } } } }); document.getElementById("playpause").addEventListener("click", function() { isPausing() ? document.getElementById("playpause").textContent = "Play" : document.getElementById("playpause").textContent = "Pause"; selectedState = null; paintingAlive = false; if (isPausing()) { gridInterval = setInterval(function() { gridState = nextGeneration(gridState); drawGrid(gridState, document.getElementById("game")); document.getElementById("generations").textContent = "Generations: " + gridGenerations; }, 100); } else { clearInterval(gridInterval); }); }); document.getElementById("step").addEventListener("click", function() { if (!isPausing()) { document.getElementById("playpause").textContent = "Play"; gridInterval = setInterval(function() { gridState = nextGeneration(gridState); drawGrid(gridState, document.getElementById("game")); document.getElementById("generations").textContent = "Generations: " + gridGenerations; }, 100); } gridState = nextGeneration(gridState); drawGrid(gridState, document.getElementById("game")); document.getElementById("generations").textContent = "Generations: " + gridGenerations; }); document.getElementById("randomize").addEventListener("click", function() { gridState = generateGrid(40, 60); drawGrid(gridState, document.getElementById("game")); gridGenerations = 0; document.getElementById("generations").textContent = "Generations: 0"; selectedState = null; paintingAlive = false; }); document.getElementById("clear").addEventListener("click", function() { gridState = generateGrid(40, 60); drawGrid(gridState, document.getElementById("game")); gridGenerations = 0; document.getElementById("generations").textContent = "Generations: 0"; selectedState = null; paintingAlive = false; }); var selectedState = null; var paintingAlive = false; var gridInterval = null; var gridState = generateGrid(40, 60); var gridGenerations = 0; drawGrid(gridState, document.getElementById("game"));</script><style>canvas { position: absolute; top: 20px; left: 20px; } button { position: absolute; top: 80px; left: 20px; } #play { top: 120px; } #pause { display: none; } #step { top: 160px; } #randomize { top: 200px; } #clear { top: 240px; } #generations { position: absolute; top: 20px; right: 20px; }</style><script>function drawGrid(grid, canvas) { var ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, canvas.width, canvas.height); for (var r = 0; r < grid.length; r++) { for (var c = 0; c < grid[r].length; c++) { if (grid[r][c] == 1) { ctx.fillStyle = "black"; } else { ctx.fillStyle = "white"; } ctx.fillRect(c * 15, r * 15, 15, 15); } } }</script><script>function generateGrid(rows, cols) { var grid = []; for (var r = 0; r < rows; r++) { grid.push([]); for (var c = 0; c < cols; c++) { grid[r].push(Math.random() > 0.8 ? 1 : 0); } } return grid; }</script><script>function getNeighbors(grid, r, c) { var n = 0; for (var i = -1; i <= 1; i++) { for (var j = -1; j <= 1; j++) { if (i != 0 || j != 0) { n += grid[r+i][c+j]; } } } return n; }</script><script>function nextGeneration(grid) { var newGrid = []; for (var r = 0; r < grid.length; r++) { newGrid.push([]); for (var c = 0; c < grid[r].length; c++) { var n = getNeighbors(grid, r, c); if (grid[r][c] == 1 && (n == 2 || n == 3)) { newGrid[r].push(1); } else if (grid[r][c] == 0 && n == 3) { newGrid[r].push(1); } else { newGrid[r].push(0); } } } return newGrid; }</script></script></script></script></script></script></script> </write>
The output file index.html has not been written, or is empty. Write the complete app to index.html in the current directory now. Use the remaining time to verify it, then finish. The original 15-minute deadline still applies.
<write>{ style=\"<style>\n\ canvas {\n border: 1px solid black;\n }\n\ button {\n position: absolute;\n top: 20;\n left: 20;\n }\n\ #play {\n top: 80;\n }\n\ #pause {\n display: none;\n }\n\ #step {\n top: 160;\n }\n\ #randomize {\n top: 200;\n }\n\ #clear {\n top: 240;\n }\n\ #generations {\n position: absolute;\n top: 20;\n right: 20;\n }\n\ </style>\", script=\"<script>\n\ function generateGrid(rows, cols) {\n\ var grid = [];\n\ for (var r = 0; r < rows; r++) {\n\ grid.push([]);\n\ for (var c = 0; c < cols; c++) {\n\ grid[r].push(Math.random() > 0.8 ? 1 : 0);\n}\n\ }\n\ return grid;\n\ }\n\ function drawGrid(grid, canvas) {\n\ var ctx = canvas.getContext(\"2d\");\n\ ctx.clearRect(0, 0, canvas.width, canvas.height);\n\ for (var r = 0; r < grid.length; r++) {\n\ for (var c = 0; c < grid[r].length; c++) {\n\ if (grid[r][c] == 1) {\n\ ctx.fillStyle = \"black\";\n\ } else {\n\ ctx.fillStyle = \"white\";\n\ }\n\ ctx.fillRect(c * 15, r * 15, 15, 15);\n\ }\n\ }\n\ }\n\ function getNeighbors(grid, r, c) {\n\ var n = 0;\n\ for (var i = -1; i <= 1; i++) {\n\ for (var j = -1; j <= 1; j++) {\n\ if (i != 0 || j != 0) {\n\ n += grid[r+i][c+j];\n\ }\n\ }\n\ }\n\ return n;\n\ }\n\ function nextGeneration(grid) {\n\ var newGrid = [];\n\ for (var r = 0; r < grid.length; r++) {\n\ newGrid.push([]);\n\ for (var c = 0; c < grid[r].length; c++) {\n\ var n = getNeighbors(grid, r, c);\n\ if (grid[r][c] == 1 && (n == 2 || n == 3)) {\n\ newGrid[r].push(1);\n\ } else if (grid[r][c] == 0 && n == 3) {\n\ newGrid[r].push(1);\n\ } else {\n\ newGrid[r].push(0);\n\ }\n\ }\n\ }\n\ return newGrid;\n\ }\n\ function isPausing() {\n\ return document.getElementById(\"playpause\").textContent == \"Play\";\n\ }\n\ document.getElementById(\"game\").addEventListener(\"click\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ var grid = gridState;\n\ if (isPausing()) {\n\ if (selectedState) {\n\ grid[y][x] = selectedState;\n\ } else {\n\ grid[y][x] = 1 - grid[y][x];\n\ }\n\ }\n\ });\n\ document.getElementById(\"game\").addEventListener(\"mousedown\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ if (e.buttons == 1) {\n\ selectedState = 1;\n\ paintingAlive = true;\n\ }\n\ else if (e.buttons == 2) {\n\ selectedState = 0;\n\ paintingAlive = true;\n\ }\n\ selectedX = x;\n\ selectedY = y;\n\ });\n\ document.getElementById(\"game\").addEventListener(\"mousemove\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ if (selectedState && paintingAlive) {\n\ for (var r = selectedY; r <= y; r++) {\n\ for (var c = (r == selectedY) ? selectedX : x; c <= x; c++) {\n\ if (r >= 0 && c >= 0 && r < gridState.length && c < gridState[r].length) {\n\ gridState[r][c] = selectedState;\n\ }\n\ }\n\ }\n\ }\n\ });\n\ document.getElementById(\"playpause\").addEventListener(\"click\", function() {\n\ isPausing() ? document.getElementById(\"playpause\").textContent = \"Play\" : document.getElementById(\"playpause\").textContent = \"Pause\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ if (isPausing()) {\n\ gridInterval = setInterval(function() {\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ }, 100);\n\ }\n\ else {\n\ clearInterval(gridInterval);\n\ }\n\ });\n\ document.getElementById(\"step\").addEventListener(\"click\", function() {\n\ if (!isPausing()) {\n\ document.getElementById(\"playpause\").textContent = \"Play\";\n\ gridInterval = setInterval(function() {\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ }, 100);\n\ }\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ });\n\ document.getElementById(\"randomize\").addEventListener(\"click\", function() {\n\ gridState = generateGrid(40, 60);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ gridGenerations = 0;\n\ document.getElementById(\"generations\").textContent = \"Generations: 0\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ });\n\ document.getElementById(\"clear\").addEventListener(\"click\", function() {\n\ gridState = generateGrid(40, 60);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ gridGenerations = 0;\n\ document.getElementById(\"generations\").textContent = \"Generations: 0\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ });\n\ var selectedState = null;\n\ var paintingAlive = false;\n\ var gridInterval = null;\n\ var gridState = generateGrid(40, 60);\n\ var gridGenerations = 0;\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ </script>\", html=\"<html><head><title>Conway's Game of Life</title></head><body><canvas id='game' width='600' height='400'></canvas><button id='playpause'>Play/Pause</button><button id='step'>Step</button><button id='randomize'>Randomize</button><button id='clear'>Clear</button><p id='generations'>Generations: 0</p></body></html>\", content=\"\", path='./' }<function=write>{'path': './', 'content': '', 'content': "<html><head><title>Conway's Game of Life</title></head><body><canvas id='game' width='600' height='400'></canvas><button id='playpause'>Play/Pause</button><button id='step'>Step</button><button id='randomize'>Randomize</button><button id='clear'>Clear</button><p id='generations'>Generations: 0</p><style>\n\ canvas {\n border: 1px solid black;\n }\n\ button {\n position: absolute;\n top: 20;\n left: 20;\n }\n\ #play {\n top: 80;\n }\n\ #pause {\n display: none;\n }\n\ #step {\n top: 160;\n }\n\ #randomize {\n top: 200;\n }\n\ #clear {\n top: 240;\n }\n\ #generations {\n position: absolute;\n top: 20;\n right: 20;\n }\n\ function generateGrid(rows, cols) {\n\ var grid = [];\n\ for (var r = 0; r < rows; r++) {\n\ grid.push([]);\n\ for (var c = 0; c < cols; c++) {\n\ grid[r].push(Math.random() > 0.8 ? 1 : 0);\n}\n\ }\n\ return grid;\n\ }\n\ function drawGrid(grid, canvas) {\n\ var ctx = canvas.getContext(\"2d\");\n\ ctx.clearRect(0, 0, canvas.width, canvas.height);\n\ for (var r = 0; r < grid.length; r++) {\n\ for (var c = 0; c < grid[r].length; c++) {\n\ if (grid[r][c] == 1) {\n\ ctx.fillStyle = \"black\";\n\ } else {\n\ ctx.fillStyle = \"white\";\n\ }\n\ ctx.fillRect(c * 15, r * 15, 15, 15);\n\ }\n\ }\n\ }\n\ function getNeighbors(grid, r, c) {\n\ var n = 0;\n\ for (var i = -1; i <= 1; i++) {\n\ for (var j = -1; j <= 1; j++) {\n\ if (i != 0 || j != 0) {\n\ n += grid[r+i][c+j];\n\ }\n\ }\n\ }\n\ return n;\n\ }\n\ function nextGeneration(grid) {\n\ var newGrid = [];\n\ for (var r = 0; r < grid.length; r++) {\n\ newGrid.push([]);\n\ for (var c = 0; c < grid[r].length; c++) {\n\ var n = getNeighbors(grid, r, c);\n\ if (grid[r][c] == 1 && (n == 2 || n == 3)) {\n\ newGrid[r].push(1);\n\ } else if (grid[r][c] == 0 && n == 3) {\n\ newGrid[r].push(1);\n\ } else {\n\ newGrid[r].push(0);\n\ }\n\ }\n\ }\n\ return newGrid;\n\ }\n\ function isPausing() {\n\ return document.getElementById(\"playpause\").textContent == \"Play\";\n\ }\n\ document.getElementById(\"game\").addEventListener(\"click\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ var grid = gridState;\n\ if (isPausing()) {\n\ if (selectedState) {\n\ grid[y][x] = selectedState;\n\ } else {\n\ grid[y][x] = 1 - grid[y][x];\n\ }\n\ }\n\ });\n\ document.getElementById(\"game\").addEventListener(\"mousedown\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ if (e.buttons == 1) {\n\ selectedState = 1;\n\ paintingAlive = true;\n\ }\n\ else if (e.buttons == 2) {\n\ selectedState = 0;\n\ paintingAlive = true;\n\ }\n\ selectedX = x;\n\ selectedY = y;\n\ });\n\ document.getElementById(\"game\").addEventListener(\"mousemove\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ if (selectedState && paintingAlive) {\n\ for (var r = selectedY; r <= y; r++) {\n\ for (var c = (r == selectedY) ? selectedX : x; c <= x; c++) {\n\ if (r >= 0 && c >= 0 && r < gridState.length && c < gridState[r].length) {\n\ gridState[r][c] = selectedState;\n\ }\n\ }\n\ }\n\ });\n\ document.getElementById(\"playpause\").addEventListener(\"click\", function() {\n\ isPausing() ? document.getElementById(\"playpause\").textContent = \"Play\" : document.getElementById(\"playpause\").textContent = \"Pause\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ if (isPausing()) {\n\ gridInterval = setInterval(function() {\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ }, 100);\n\ }\n\ else {\n\ clearInterval(gridInterval);\n\ }\n\ });\n\ document.getElementById(\"step\").addEventListener(\"click\", function() {\n\ if (!isPausing()) {\n\ document.getElementById(\"playpause\").textContent = \"Play\";\n\ gridInterval = setInterval(function() {\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ }, 100);\n\ }\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ });\n\ document.getElementById(\"randomize\").addEventListener(\"click\", function() {\n\ gridState = generateGrid(40, 60);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ gridGenerations = 0;\n\ document.getElementById(\"generations\").textContent = \"Generations: 0\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ });\n\ document.getElementById(\"clear\").addEventListener(\"click\", function() {\n\ gridState = generateGrid(40, 60);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ gridGenerations = 0;\n\ document.getElementById(\"generations\").textContent = \"Generations: 0\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ });\n\ var selectedState = null;\n\ var paintingAlive = false;\n\ var gridInterval = null;\n\ var gridState = generateGrid(40, 60);\n\ var gridGenerations = 0;\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ </style><script>document.write(\"</body></html>\")</script>\", script='<script>document.write("</body></html>")</script></html><style></style>' }</function>
The output file index.html has not been written, or is empty. Write the complete app to index.html in the current directory now. Use the remaining time to verify it, then finish. The original 15-minute deadline still applies.
<write>{'path': '.', 'content': "<style>\n\ canvas {\n border: 1px solid black;\n }\n\ button {\n position: absolute;\n top: 20;\n left: 20;\n }\n\ #play {\n top: 80;\n }\n\ #pause {\n display: none;\n }\n\ #step {\n top: 160;\n }\n\ #randomize {\n top: 200;\n }\n\ #clear {\n top: 240;\n }\n\ #generations {\n position: absolute;\n top: 20;\n right: 20;\n }\n\ </style><script>\n\ function generateGrid(rows, cols) {\n\ var grid = [];\n\ for (var r = 0; r < rows; r++) {\n\ grid.push([]);\n\ for (var c = 0; c < cols; c++) {\n\ grid[r].push(Math.random() > 0.8 ? 1 : 0);\n}\n\ }\n\ return grid;\n\ }\n\ function drawGrid(grid, canvas) {\n\ var ctx = canvas.getContext(\"2d\");\n\ ctx.clearRect(0, 0, canvas.width, canvas.height);\n\ for (var r = 0; r < grid.length; r++) {\n\ for (var c = 0; c < grid[r].length; c++) {\n\ if (grid[r][c] == 1) {\n\ ctx.fillStyle = \"black\";\n\ } else {\n\ ctx.fillStyle = \"white\";\n\ }\n\ ctx.fillRect(c * 15, r * 15, 15, 15);\n\ }\n\ }\n\ }\n\ function getNeighbors(grid, r, c) {\n\ var n = 0;\n\ for (var i = -1; i <= 1; i++) {\n\ for (var j = -1; j <= 1; j++) {\n\ if (i != 0 || j != 0) {\n\ n += grid[r+i][c+j];\n\ }\n\ }\n\ }\n\ return n;\n\ }\n\ function nextGeneration(grid) {\n\ var newGrid = [];\n\ for (var r = 0; r < grid.length; r++) {\n\ newGrid.push([]);\n\ for (var c = 0; c < grid[r].length; c++) {\n\ var n = getNeighbors(grid, r, c);\n\ if (grid[r][c] == 1 && (n == 2 || n == 3)) {\n\ newGrid[r].push(1);\n\ } else if (grid[r][c] == 0 && n == 3) {\n\ newGrid[r].push(1);\n\ } else {\n\ newGrid[r].push(0);\n\ }\n\ }\n\ }\n\ return newGrid;\n\ }\n\ function isPausing() {\n\ return document.getElementById(\"playpause\").textContent == \"Play\";\n\ }\n\ document.getElementById(\"game\").addEventListener(\"click\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ var grid = gridState;\n\ if (isPausing()) {\n\ if (selectedState) {\n\ grid[y][x] = selectedState;\n\ } else {\n\ grid[y][x] = 1 - grid[y][x];\n\ }\n\ }\n\ });\n\ document.getElementById(\"game\").addEventListener(\"mousedown\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ if (e.buttons == 1) {\n\ selectedState = 1;\n\ paintingAlive = true;\n\ }\n\ else if (e.buttons == 2) {\n\ selectedState = 0;\n\ paintingAlive = true;\n\ }\n\ selectedX = x;\n\ selectedY = y;\n\ });\n\ document.getElementById(\"game\").addEventListener(\"mousemove\", function(e) {\n\ var rect = document.getElementById(\"game\").getBoundingClientRect();\n\ var x = Math.floor((e.clientX - rect.left) / 15);\n\ var y = Math.floor((e.clientY - rect.top) / 15);\n\ if (selectedState && paintingAlive) {\n\ for (var r = selectedY; r <= y; r++) {\n\ for (var c = (r == selectedY) ? selectedX : x; c <= x; c++) {\n\ if (r >= 0 && c >= 0 && r < gridState.length && c < gridState[r].length) {\n\ gridState[r][c] = selectedState;\n\ }\n\ }\n\ }\n\ });\n\ document.getElementById(\"playpause\").addEventListener(\"click\", function() {\n\ isPausing() ? document.getElementById(\"playpause\").textContent = \"Play\" : document.getElementById(\"playpause\").textContent = \"Pause\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ if (isPausing()) {\n\ gridInterval = setInterval(function() {\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ }, 100);\n\ }\n\ else {\n\ clearInterval(gridInterval);\n\ }\n\ });\n\ document.getElementById(\"step\").addEventListener(\"click\", function() {\n\ if (!isPausing()) {\n\ document.getElementById(\"playpause\").textContent = \"Play\";\n\ gridInterval = setInterval(function() {\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ }, 100);\n\ }\n\ gridState = nextGeneration(gridState);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ document.getElementById(\"generations\").textContent = \"Generations: \" + gridGenerations;\n\ });\n\ document.getElementById(\"randomize\").addEventListener(\"click\", function() {\n\ gridState = generateGrid(40, 60);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ gridGenerations = 0;\n\ document.getElementById(\"generations\").textContent = \"Generations: 0\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ });\n\ document.getElementById(\"clear\").addEventListener(\"click\", function() {\n\ gridState = generateGrid(40, 60);\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ gridGenerations = 0;\n\ document.getElementById(\"generations\").textContent = \"Generations: 0\";\n\ selectedState = null;\n\ paintingAlive = false;\n\ });\n\ var selectedState = null;\n\ var paintingAlive = false;\n\ var gridInterval = null;\n\ var gridState = generateGrid(40, 60);\n\ var gridGenerations = 0;\n\ drawGrid(gridState, document.getElementById(\"game\"));\n\ </script><script>\n\ document.write(\"<html><head><title>Conway's Game of Life</title><style>\n\ canvas {\n border: 1px solid black;\n }\n\ button {\n position: absolute;\n top: 20;\n left: 20;\n }\n\ #play {\n top: 80;\n }\n\ #pause {\n display: none;\n }\n\ #step {\n top: 160;\n }\n\ #randomize {\n top: 200;\n }\n\ #clear {\n top: 240;\n }\n\ #generations {\n position: absolute;\n top: 20;\n right: 20;\n }\n\ </style></head><body><canvas id='game' width='600' height='400'></canvas><button id='playpause'>Play/Pause</button><button id='step'>Step</button><button id='randomize'>Randomize</button><button id='clear'>Clear</button><p id='generations'>Generations: 0</p></body></html>\")\n\ </script>\")</script></style></html>"}</function>