Conway's Game of Life · qwen3-coder-flash
Run Conway's Game of Life on a full-screen canvas grid with click-and-drag to toggle cells, plus play/pause, step, randomize, and clear controls.
This one-shot run produced no runnable artifact.
agent produced no index.html
The transcript below shows what the model did — read it to see why the one shot fell short.
transcript · 2 messages
Run Conway's Game of Life on a full-screen canvas grid with click-and-drag to toggle cells, plus play/pause, step, randomize, and clear controls.
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Conway's Game of Life</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #1a1a1a; color: #e0e0e0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; overflow: hidden; height: 100vh; display: flex; flex-direction: column; } .header { padding: 15px; text-align: center; background-color: #2d2d2d; border-bottom: 2px solid #444; } h1 { font-size: 2.2rem; margin-bottom: 5px; color: #4fc3f7; } .subtitle { font-size: 1rem; opacity: 0.8; } .controls { display: flex; justify-content: center; gap: 15px; padding: 15px; flex-wrap: wrap; background-color: #252525; border-bottom: 1px solid #333; } button { padding: 10px 20px; font-size: 1rem; background-color: #3a3a3a; color: #e0e0e0; border: 1px solid #555; border-radius: 4px; cursor: pointer; transition: all 0.2s ease; min-width: 100px; } button:hover { background-color: #4a4a4a; transform: translateY(-2px); } button:active { transform: translateY(0); } button.play-pause { background-color: #2e7d32; min-width: 120px; } button.play-pause:hover { background-color: #388e3c; } .canvas-container { flex: 1; display: flex; justify-content: center; align-items: center; padding: 20px; } canvas { background-color: #111; box-shadow: 0 0 20px rgba(0, 0, 0, 0.7); border: 1px solid #333; } .stats { display: flex; justify-content: center; gap: 30px; padding: 10px; background-color: #252525; font-size: 0.9rem; border-top: 1px solid #333; } .stat-item { display: flex; flex-direction: column; align-items: center; } .stat-value { font-weight: bold; color: #4fc3f7; font-size: 1.1rem; } .instructions { position: absolute; bottom: 20px; left: 0; right: 0; text-align: center; font-size: 0.9rem; opacity: 0.7; padding: 10px; } @media (max-width: 768px) { .controls { flex-direction: column; align-items: center; } button { width: 80%; } .stats { flex-direction: column; gap: 5px; } } </style> </head> <body> <div class="header"> <h1>Conway's Game of Life</h1> <div class="subtitle">Click and drag to toggle cells | Play/Pause to start/stop simulation</div> </div> <div class="controls"> <button id="playPauseBtn" class="play-pause">Play</button> <button id="stepBtn">Step</button> <button id="randomBtn">Randomize</button> <button id="clearBtn">Clear</button> </div> <div class="canvas-container"> <canvas id="gameCanvas"></canvas> </div> <div class="stats"> <div class="stat-item"> <span>Generation</span> <span id="generationCount" class="stat-value">0</span> </div> <div class="stat-item"> <span>Live Cells</span> <span id="liveCellsCount" class="stat-value">0</span> </div> <div class="stat-item"> <span>Speed</span> <span id="speedValue" class="stat-value">5</span> </div> </div> <div class="instructions"> Click and drag to toggle cells | Use controls below to manage simulation </div> <script> // Canvas setup const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // Set canvas to full window size function resizeCanvas() { canvas.width = window.innerWidth - 40; canvas.height = window.innerHeight - 200; } window.addEventListener('resize', resizeCanvas); resizeCanvas(); // Game constants const CELL_SIZE = 10; const GRID_WIDTH = Math.floor(canvas.width / CELL_SIZE); const GRID_HEIGHT = Math.floor(canvas.height / CELL_SIZE); // Game state let grid = createEmptyGrid(); let nextGrid = createEmptyGrid(); let isRunning = false; let animationId = null; let generation = 0; let speed = 5; // frames per second // DOM elements const playPauseBtn = document.getElementById('playPauseBtn'); const stepBtn = document.getElementById('stepBtn'); const randomBtn = document.getElementById('randomBtn'); const clearBtn = document.getElementById('clearBtn'); const generationCount = document.getElementById('generationCount'); const liveCellsCount = document.getElementById('liveCellsCount'); const speedValue = document.getElementById('speedValue'); // Create empty grid function createEmptyGrid() { return Array(GRID_HEIGHT).fill().map(() => Array(GRID_WIDTH).fill(false)); } // Initialize grid with random values function randomizeGrid() { for (let y = 0; y < GRID_HEIGHT; y++) { for (let x = 0; x < GRID_WIDTH; x++) { grid[y][x] = Math.random() > 0.7; } } updateStats(); } // Clear grid function clearGrid() { grid = createEmptyGrid(); generation = 0; updateStats(); } // Count live neighbors for a cell function countNeighbors(x, y) { let count = 0; for (let dy = -1; dy <= 1; dy++) { for (let dx = -1; dx <= 1; dx++) { if (dx === 0 && dy === 0) continue; const nx = (x + dx + GRID_WIDTH) % GRID_WIDTH; const ny = (y + dy + GRID_HEIGHT) % GRID_HEIGHT; if (grid[ny][nx]) { count++; } } } return count; } // Compute next generation function computeNextGeneration() { let liveCells = 0; for (let y = 0; y < GRID_HEIGHT; y++) { for (let x = 0; x < GRID_WIDTH; x++) { const neighbors = countNeighbors(x, y); const isAlive = grid[y][x]; // Apply Conway's Game of Life rules if (isAlive && (neighbors < 2 || neighbors > 3)) { nextGrid[y][x] = false; // Dies } else if (!isAlive && neighbors === 3) { nextGrid[y][x] = true; // Born liveCells++; } else { nextGrid[y][x] = isAlive; // Stays the same if (isAlive) liveCells++; } } } // Swap grids [grid, nextGrid] = [nextGrid, grid]; generation++; updateStats(); } // Draw the grid function drawGrid() { ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw cells for (let y = 0; y < GRID_HEIGHT; y++) { for (let x = 0; x < GRID_WIDTH; x++) { if (grid[y][x]) { ctx.fillStyle = '#4fc3f7'; ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE); // Add a subtle highlight ctx.fillStyle = 'rgba(255, 255, 255, 0.2)'; ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, 1); ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, 1, CELL_SIZE); } } } // Draw grid lines ctx.strokeStyle = '#333'; ctx.lineWidth = 0.5; // Vertical lines for (let x = 0; x <= canvas.width; x += CELL_SIZE) { ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, canvas.height); ctx.stroke(); } // Horizontal lines for (let y = 0; y <= canvas.height; y += CELL_SIZE) { ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(canvas.width, y); ctx.stroke(); } } // Update statistics display function updateStats() { let liveCells = 0; for (let y = 0; y < GRID_HEIGHT; y++) { for (let x = 0; x < GRID_WIDTH; x++) { if (grid[y][x]) liveCells++; } } generationCount.textContent = generation; liveCellsCount.textContent = liveCells; speedValue.textContent = speed; } // Game loop function gameLoop() { if (isRunning) { computeNextGeneration(); drawGrid(); animationId = setTimeout(() => { gameLoop(); }, 1000 / speed); } } // Toggle cell state at position function toggleCell(x, y) { const gridX = Math.floor(x / CELL_SIZE); const gridY = Math.floor(y / CELL_SIZE); if (gridX >= 0 && gridX < GRID_WIDTH && gridY >= 0 && gridY < GRID_HEIGHT) { grid[gridY][gridX] = !grid[gridY][gridX]; drawGrid(); updateStats(); } } // Event listeners for buttons playPauseBtn.addEventListener('click', () => { isRunning = !isRunning; playPauseBtn.textContent = isRunning ? 'Pause' : 'Play'; if (isRunning) { gameLoop(); } else if (animationId) { clearTimeout(animationId); } }); stepBtn.addEventListener('click', () => { if (!isRunning) { computeNextGeneration(); drawGrid(); } }); randomBtn.addEventListener('click', () => { if (!isRunning) { randomizeGrid(); drawGrid(); } }); clearBtn.addEventListener('click', () => { if (!isRunning) { clearGrid(); drawGrid(); } }); // Mouse event handlers for drawing let isDrawing = false; canvas.addEventListener('mousedown', (e) => { isDrawing = true; const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; toggleCell(x, y); }); canvas.addEventListener('mousemove', (e) => { if (isDrawing) { const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; toggleCell(x, y); } }); canvas.addEventListener('mouseup', () => { isDrawing = false; }); canvas.addEventListener('mouseleave', () => { isDrawing = false; }); // Touch events for mobile devices canvas.addEventListener('touchstart', (e) => { e.preventDefault(); isDrawing = true; const rect = canvas.getBoundingClientRect(); const touch = e.touches[0]; const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; toggleCell(x, y); }); canvas.addEventListener('touchmove', (e) => { e.preventDefault(); if (isDrawing) { const rect = canvas.getBoundingClientRect(); const touch = e.touches[0]; const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; toggleCell(x, y); } }); canvas.addEventListener('touchend', () => { isDrawing = false; }); // Initialize randomizeGrid(); drawGrid(); // Add keyboard shortcuts document.addEventListener('keydown', (e) => { switch(e.key) { case ' ': e.preventDefault(); playPauseBtn.click(); break; case 'r': randomBtn.click(); break; case 'c': clearBtn.click(); break; case 'ArrowRight': if (!isRunning) stepBtn.click(); break; case '+': case '=': speed = Math.min(speed + 1, 20); speedValue.textContent = speed; break; case '-': case '_': speed = Math.max(speed - 1, 1); speedValue.textContent = speed; break; } }); </script> </body> </html> ```
TAKE IT TO CODE
This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.