Maze generator & solver · gpt-4o-mini-2024-07-18
Generate a random maze with the recursive-backtracker algorithm on a canvas, then animate an A-star or BFS solver finding the path from start to finish.
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
Generate a random maze with the recursive-backtracker algorithm on a canvas, then animate an A-star or BFS solver finding the path from start to finish.
Here's a self-contained HTML file that generates a random maze using the recursive-backtracker algorithm and animates an A* algorithm to find the path from the start to finish. ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Maze Generator and Solver</title> <style> body { display: flex; align-items: center; justify-content: center; height: 100vh; background: #222; color: white; } canvas { border: 1px solid #fff; } </style> </head> <body> <canvas id="mazeCanvas"></canvas> <script> const canvas = document.getElementById('mazeCanvas'); const ctx = canvas.getContext('2d'); const rows = 20; const cols = 20; const cellSize = 30; canvas.width = cols * cellSize; canvas.height = rows * cellSize; let grid = []; let stack = []; let current; let path = []; // Maze Creation - Recursive Backtracker Algorithm function setup() { for (let i = 0; i < rows; i++) { grid[i] = []; for (let j = 0; j < cols; j++) { grid[i][j] = { visited: false, walls: { top: true, right: true, bottom: true, left: true } }; } } current = grid[0][0]; current.visited = true; draw(); generateMaze(); } function generateMaze() { const neighbors = getNeighbors(current); if (neighbors.length > 0) { const next = neighbors[Math.floor(Math.random() * neighbors.length)]; removeWall(current, next); stack.push(current); current = next; current.visited = true; generateMaze(); } else if (stack.length > 0) { current = stack.pop(); generateMaze(); } else { pathfinding(); } } function getNeighbors(cell) { const neighbors = []; const { row, col } = getCellPosition(cell); if (row > 0 && !grid[row - 1][col].visited) neighbors.push(grid[row - 1][col]); if (col < cols - 1 && !grid[row][col + 1].visited) neighbors.push(grid[row][col + 1]); if (row < rows - 1 && !grid[row + 1][col].visited) neighbors.push(grid[row + 1][col]); if (col > 0 && !grid[row][col - 1].visited) neighbors.push(grid[row][col - 1]); return neighbors; } function removeWall(current, next) { const { row: curRow, col: curCol } = getCellPosition(current); const { row: nextRow, col: nextCol } = getCellPosition(next); if (curRow === nextRow) { if (curCol < nextCol) { current.walls.right = false; next.walls.left = false; } else { current.walls.left = false; next.walls.right = false; } } else { if (curRow < nextRow) { current.walls.bottom = false; next.walls.top = false; } else { current.walls.top = false; next.walls.bottom = false; } } } function getCellPosition(cell) { for (let row = 0; row < rows; row++) { for (let col = 0; col < cols; col++) { if (grid[row][col] === cell) return { row, col }; } } } function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i < rows; i++) { for (let j = 0; j < cols; j++) { const cell = grid[i][j]; const x = j * cellSize; const y = i * cellSize; ctx.fillStyle = cell.visited ? "#fff" : "#000"; ctx.fillRect(x, y, cellSize, cellSize); ctx.strokeStyle = "#fff"; if (cell.walls.top) ctx.strokeRect(x, y, cellSize, 1); if (cell.walls.right) ctx.strokeRect(x + cellSize - 1, y, 1, cellSize); if (cell.walls.bottom) ctx.strokeRect(x, y + cellSize - 1, cellSize, 1); if (cell.walls.left) ctx.strokeRect(x, y, 1, cellSize); } } } // Pathfinding - A* Algorithm function pathfinding() { const start = grid[0][0]; const end = grid[rows - 1][cols - 1]; const openSet = [start]; const closedSet = []; const cameFrom = new Map(); const gScore = new Map(); const fScore = new Map(); for (let i = 0; i < rows; i++) { for (let j = 0; j < cols; j++) { gScore.set(grid[i][j], Infinity); fScore.set(grid[i][j], Infinity); } } gScore.set(start, 0); fScore.set(start, heuristic(start, end)); function heuristic(a, b) { const { row: ax, col: ay } = getCellPosition(a); const { row: bx, col: by } = getCellPosition(b); return Math.abs(ax - bx) + Math.abs(ay - by); } let pathFound = false; while (openSet.length > 0) { let current = openSet.reduce((a, b) => fScore.get(a) < fScore.get(b) ? a : b); if (current === end) { pathFound = true; reconstructPath(cameFrom, current); break; } openSet.splice(openSet.indexOf(current), 1); closedSet.push(current); const neighbors = getNeighbors(current); for (const neighbor of neighbors) { if (!closedSet.includes(neighbor)) { const tentativeGScore = gScore.get(current) + 1; if (!openSet.includes(neighbor)) { openSet.push(neighbor); } else if (tentativeGScore >= gScore.get(neighbor)) { continue; } cameFrom.set(neighbor, current); gScore.set(neighbor, tentativeGScore); fScore.set(neighbor, gScore.get(neighbor) + heuristic(neighbor, end)); } } } if (pathFound) animatePath(); } function reconstructPath(cameFrom, current) { while (cameFrom.has(current)) { path.push(current); current = cameFrom.get(current); } path.reverse(); } function animatePath() { let index = 0; function drawPath() { if (index < path.length) { const { row, col } = getCellPosition(path[index]); ctx.fillStyle = 'red'; ctx.fillRect(col * cellSize, row * cellSize, cellSize, cellSize); index++; requestAnimationFrame(drawPath); } } drawPath(); } setup(); </script> </body> </html> ``` This code creates a maze generator and solver using the canvas element. The maze is generated using the recursive-backtracker method, and the A* algorithm is used to find the shortest path from the top-left corner to the bottom-right corner, shown in red when animated. You can save this code to a file named `index.html` in your current directory.
TAKE IT TO CODE
This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.