oneshotlm
Compare all models on this prompt →

Maze generator & solver · qwen3-coder-30b-a3b-instruct

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.

⚠ no runnable output

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
user

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.

assistant

```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 { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c); padding: 20px; color: white; overflow-x: hidden; } .container { max-width: 900px; width: 100%; text-align: center; } h1 { font-size: 2.5rem; margin-bottom: 10px; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); } .subtitle { font-size: 1.2rem; margin-bottom: 25px; opacity: 0.9; } .canvas-container { background-color: rgba(0, 0, 0, 0.3); border-radius: 10px; padding: 15px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); margin-bottom: 25px; display: inline-block; } canvas { background-color: #0d1b2a; border-radius: 5px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); } .controls { display: flex; flex-wrap: wrap; gap: 15px; justify-content: center; margin-bottom: 25px; } button { padding: 12px 25px; font-size: 1rem; font-weight: 600; border: none; border-radius: 50px; cursor: pointer; background: linear-gradient(to right, #4A00E0, #8E2DE2); color: white; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); transition: all 0.3s ease; } button:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3); } button:active { transform: translateY(1px); } .info-panel { background-color: rgba(255, 255, 255, 0.1); border-radius: 10px; padding: 20px; margin-top: 15px; text-align: left; } .info-panel h2 { margin-top: 0; border-bottom: 2px solid rgba(255, 255, 255, 0.2); padding-bottom: 10px; } .info-panel ul { padding-left: 20px; } .info-panel li { margin-bottom: 10px; line-height: 1.5; } .stats { display: flex; justify-content: center; gap: 30px; margin: 15px 0; flex-wrap: wrap; } .stat-box { background: rgba(0, 0, 0, 0.2); padding: 12px 25px; border-radius: 8px; min-width: 120px; } .stat-value { font-size: 1.8rem; font-weight: bold; color: #8E2DE2; } .stat-label { font-size: 0.9rem; opacity: 0.8; } @media (max-width: 600px) { h1 { font-size: 2rem; } .subtitle { font-size: 1rem; } .controls { flex-direction: column; align-items: center; } button { width: 80%; } .stats { gap: 10px; } .stat-box { padding: 10px 15px; min-width: 100px; } .stat-value { font-size: 1.4rem; } } </style> </head> <body> <div class="container"> <h1>Maze Generator & Solver</h1> <p class="subtitle">Recursive Backtracker + A* Pathfinding</p> <div class="stats"> <div class="stat-box"> <div class="stat-value" id="maze-size">0x0</div> <div class="stat-label">MAZE SIZE</div> </div> <div class="stat-box"> <div class="stat-value" id="nodes-expanded">0</div> <div class="stat-label">NODES EXPANDED</div> </div> <div class="stat-box"> <div class="stat-value" id="path-length">0</div> <div class="stat-label">PATH LENGTH</div> </div> </div> <div class="canvas-container"> <canvas id="mazeCanvas" width="500" height="500"></canvas> </div> <div class="controls"> <button id="generateBtn">Generate New Maze</button> <button id="solveBtn">Solve with A*</button> <button id="clearBtn">Clear Path</button> </div> <div class="info-panel"> <h2>About This Implementation</h2> <ul> <li><strong>Recursive Backtracker</strong> - Generates perfect mazes by carving passages with a depth-first approach</li> <li><strong>A* Algorithm</strong> - Finds shortest path using heuristic estimation of distance to goal</li> <li><strong>Visual Feedback</strong> - Color-coded cells show maze generation and pathfinding progress</li> <li><strong>Performance Stats</strong> - Real-time display of maze size, nodes expanded, and path length</li> </ul> </div> </div> <script> // Canvas setup const canvas = document.getElementById('mazeCanvas'); const ctx = canvas.getContext('2d'); const cellSize = 20; const cols = Math.floor(canvas.width / cellSize); const rows = Math.floor(canvas.height / cellSize); // UI Elements const generateBtn = document.getElementById('generateBtn'); const solveBtn = document.getElementById('solveBtn'); const clearBtn = document.getElementById('clearBtn'); const mazeSizeEl = document.getElementById('maze-size'); const nodesExpandedEl = document.getElementById('nodes-expanded'); const pathLengthEl = document.getElementById('path-length'); // Maze state let maze = []; let visited = []; let stack = []; let path = []; let start = {x: 0, y: 0}; let end = {x: cols - 1, y: rows - 1}; let isGenerating = false; let isSolving = false; let nodesExpanded = 0; let pathLength = 0; // Initialize maze function initializeMaze() { maze = []; visited = []; for (let y = 0; y < rows; y++) { maze[y] = []; visited[y] = []; for (let x = 0; x < cols; x++) { maze[y][x] = { top: true, right: true, bottom: true, left: true, visited: false }; visited[y][x] = false; } } // Reset stats nodesExpanded = 0; pathLength = 0; updateStats(); } // Update stats display function updateStats() { mazeSizeEl.textContent = `${cols}x${rows}`; nodesExpandedEl.textContent = nodesExpanded; pathLengthEl.textContent = pathLength; } // Draw maze function function drawMaze() { ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw walls ctx.strokeStyle = '#4A90E2'; ctx.lineWidth = 2; for (let y = 0; y < rows; y++) { for (let x = 0; x < cols; x++) { const cell = maze[y][x]; const px = x * cellSize; const py = y * cellSize; // Draw walls if they exist if (cell.top) { ctx.beginPath(); ctx.moveTo(px, py); ctx.lineTo(px + cellSize, py); ctx.stroke(); } if (cell.right) { ctx.beginPath(); ctx.moveTo(px + cellSize, py); ctx.lineTo(px + cellSize, py + cellSize); ctx.stroke(); } if (cell.bottom) { ctx.beginPath(); ctx.moveTo(px, py + cellSize); ctx.lineTo(px + cellSize, py + cellSize); ctx.stroke(); } if (cell.left) { ctx.beginPath(); ctx.moveTo(px, py); ctx.lineTo(px, py + cellSize); ctx.stroke(); } } } // Draw start and end ctx.fillStyle = '#2ECC71'; ctx.fillRect(start.x * cellSize + 2, start.y * cellSize + 2, cellSize - 4, cellSize - 4); ctx.fillStyle = '#E74C3C'; ctx.fillRect(end.x * cellSize + 2, end.y * cellSize + 2, cellSize - 4, cellSize - 4); } // Draw path function function drawPath() { ctx.strokeStyle = '#F1C40F'; ctx.lineWidth = 4; for (let i = 0; i < path.length - 1; i++) { const current = path[i]; const next = path[i + 1]; const x1 = current.x * cellSize + cellSize/2; const y1 = current.y * cellSize + cellSize/2; const x2 = next.x * cellSize + cellSize/2; const y2 = next.y * cellSize + cellSize/2; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); } } // Recursive Backtracker algorithm function generateMaze() { if (isGenerating || isSolving) return; initializeMaze(); isGenerating = true; // Set starting cell as visited const current = {x: 0, y: 0}; visited[current.y][current.x] = true; stack = [current]; // Add visual feedback for start cell drawMaze(); let animationId = requestAnimationFrame(animateGeneration); function animateGeneration() { if (stack.length === 0) { isGenerating = false; drawMaze(); updateStats(); return; } const neighbors = getUnvisitedNeighbors(current); if (neighbors.length > 0) { const next = neighbors[Math.floor(Math.random() * neighbors.length)]; // Remove walls between current and next removeWalls(current, next); visited[next.y][next.x] = true; stack.push(next); current.x = next.x; current.y = next.y; // Draw current cell with special color ctx.fillStyle = '#9B59B6'; ctx.fillRect(current.x * cellSize + 2, current.y * cellSize + 2, cellSize - 4, cellSize - 4); } else { const prev = stack.pop(); current.x = prev.x; current.y = prev.y; } // Draw step requestAnimationFrame(animateGeneration); } } // Get unvisited neighbors function getUnvisitedNeighbors(cell) { const neighbors = []; const directions = [ {dx: 0, dy: -2}, // Top {dx: 2, dy: 0}, // Right {dx: 0, dy: 2}, // Bottom {dx: -2, dy: 0} // Left ]; for (const dir of directions) { const nx = cell.x + dir.dx; const ny = cell.y + dir.dy; if (nx >= 0 && nx < cols && ny >= 0 && ny < rows && !visited[ny][nx]) { neighbors.push({x: nx, y: ny}); } } return neighbors; } // Remove walls between cells function removeWalls(cell1, cell2) { const dx = cell2.x - cell1.x; const dy = cell2.y - cell1.y; // Horizontal move if (dx !== 0) { const wallX = cell1.x + (dx > 0 ? 1 : -1); maze[cell1.y][wallX].right = false; maze[cell2.y][wallX].left = false; } // Vertical move else if (dy !== 0) { const wallY = cell1.y + (dy > 0 ? 1 : -1); maze[wallY][cell1.x].bottom = false; maze[wallY][cell2.x].top = false; } } // A* Algorithm implementation function solveMaze() { if (isSolving || isGenerating) return; isSolving = true; nodesExpanded = 0; const openSet = []; const cameFrom = {}; const gScore = {}; const fScore = {}; // Initialize scores for (let y = 0; y < rows; y++) { for (let x = 0; x < cols; x++) { gScore[`${x},${y}`] = Infinity; fScore[`${x},${y}`] = Infinity; } } gScore[`${start.x},${start.y}`] = 0; fScore[`${start.x},${start.y}`] = heuristic(start, end); openSet.push(start); // Draw initial state drawMaze(); ctx.fillStyle = '#3498DB'; ctx.fillRect(start.x * cellSize + 2, start.y * cellSize + 2, cellSize - 4, cellSize - 4); ctx.fillStyle = '#E74C3C'; ctx.fillRect(end.x * cellSize + 2, end.y * cellSize + 2, cellSize - 4, cellSize - 4); let animationId = requestAnimationFrame(animateSolving); function animateSolving() { if (openSet.length === 0) { isSolving = false; alert('No solution found!'); return; } // Find node with lowest fScore let current = openSet[0]; let lowestIndex = 0; for (let i = 1; i < openSet.length; i++) { if (fScore[`${openSet[i].x},${openSet[i].y}`] < fScore[`${current.x},${current.y}`]) { current = openSet[i]; lowestIndex = i; } } // Remove from open set openSet.splice(lowestIndex, 1); // Check if we reached the end if (current.x === end.x && current.y === end.y) { isSolving = false; reconstructPath(cameFrom, current); pathLength = path.length - 1; updateStats(); drawPath(); return; } // Mark as evaluated nodesExpanded++; updateStats(); // Draw evaluated cell if (current.x !== start.x || current.y !== start.y) { ctx.fillStyle = '#F1C40F'; ctx.fillRect(current.x * cellSize + 2, current.y * cellSize + 2, cellSize - 4, cellSize - 4); } const neighbors = getMazeNeighbors(current); for (const neighbor of neighbors) { if (gScore[`${neighbor.x},${neighbor.y}`] === Infinity) { // Calculate scores const tentativeGScore = gScore[`${current.x},${current.y}`] + 1; if (tentativeGScore < gScore[`${neighbor.x},${neighbor.y}`]) { cameFrom[`${neighbor.x},${neighbor.y}`] = current; gScore[`${neighbor.x},${neighbor.y}`] = tentativeGScore; fScore[`${neighbor.x},${neighbor.y}`] = gScore[`${neighbor.x},${neighbor.y}`] + heuristic(neighbor, end); if (!openSet.some(n => n.x === neighbor.x && n.y === neighbor.y)) { openSet.push(neighbor); } } } } // Continue animation animationId = requestAnimationFrame(animateSolving); } } // Get neighbors of a cell in the maze (excluding walls) function getMazeNeighbors(cell) { const neighbors = []; // Direction vectors: up, right, down, left const directions = [ {dx: 0, dy: -1}, // Up {dx: 1, dy: 0}, // Right {dx: 0, dy: 1}, // Down {dx: -1, dy: 0} // Left ]; for (const dir of directions) { const nx = cell.x + dir.dx; const ny = cell.y + dir.dy; // Check if neighbor is inside the maze if (nx >= 0 && nx < cols && ny >= 0 && ny < rows) { // Check if wall exists let hasWall = false; if (dir.dx === 0 && dir.dy === -1) { hasWall = maze[cell.y][cell.x].top; } else if (dir.dx === 1 && dir.dy === 0) { hasWall = maze[cell.y][cell.x].right; } else if (dir.dx === 0 && dir.dy === 1) { hasWall = maze[cell.y][cell.x].bottom; } else if (dir.dx === -1 && dir.dy === 0) { hasWall = maze[cell.y][cell.x].left; } if (!hasWall) { neighbors.push({x: nx, y: ny}); } } } return neighbors; } // Heuristic function (Manhattan distance) function heuristic(a, b) { return Math.abs(a.x - b.x) + Math.abs(a.y - b.y); } // Reconstruct path function reconstructPath(cameFrom, current) { path = [current]; while (current.x !== start.x || current.y !== start.y) { const prev = cameFrom[`${current.x},${current.y}`]; path.unshift(prev); current = prev; } } // Clear path function clearPath() { if (isGenerating || isSolving) return; initializeMaze(); drawMaze(); path = []; pathLength = 0; updateStats(); } // Event listeners generateBtn.addEventListener('click', generateMaze); solveBtn.addEventListener('click', solveMaze); clearBtn.addEventListener('click', clearPath); // Initialize initializeMaze(); drawMaze(); </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.

RUN

modelqwen3-coder-30b-a3b-instruct
vendorQwen
harnesspi-agent
generated2026-08-01

METRICS

runtime87.7s
tokens in1.7k
tokens out4.6k
cached0
cost / run$0.0013