OverviewCode › R165
Code · blind round

R165 · Recursive backtracker carving a maze, then solving it

blind round 9/11 local models answered

Every answer below carries the name of the model that wrote it. Blind refers to the scoring: the review was done without knowing which model produced which answer — the published result names them.

1 of the 11 local models delivered nothing through our test harness in this round — for reasons that lie with our setup, not with the models. Those cards are marked DNF like any other, but they are not evidence about those models — the reason is noted on the card itself.

Show task
Create ONE self-contained HTML file (STRICT LIMIT: max 7000 characters in total — this is a budget on characters, not on lines, so removing line breaks does not help) that first carves a maze on a <canvas> using randomized recursive backtracking on a grid of about 25 columns by 18 rows: starting from a random cell with all walls intact, repeatedly carve a passage to a random unvisited neighbor and push the new cell onto a stack, highlighting the current cell and drawing the active backtracking stack path in a distinct color, backtracking along the stack when a cell has no unvisited neighbors, until every cell has been visited. Show a counter of cells carved so far. Once the maze is fully carved, switch to a solving phase: place a wanderer at one corner and animate it solving the maze toward the opposite corner using a visible algorithm such as the wall-follower rule or a depth-first search that marks dead ends and backtracks, highlighting the wanderer's current cell and marking cells it has already explored so backtracked dead ends stay visible in a muted color while the eventual solution path stands out. Show a separate counter of steps taken during solving. Once the wanderer reaches the exit, pause briefly, then discard the maze and start over with a freshly carved one. Smooth requestAnimationFrame animation, NO user input, starts immediately and keeps running (restart with a fresh random instance when finished). No external libraries, no comments needed. Output ONLY the HTML file content, nothing else.

The answers

Local models (Brain cluster) — identical prompt, shuffled order (the sequence is not a ranking)
deepseek-r1:14bBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><body style="background:#000;margin:0;display:flex;flex-direction:column;align-items:center">
<canvas id=c></canvas>
<div id=counters style="color:white;font-family:sans-serif;font-size:12px">Carved: <span id=carve>0</span> | Solved: <span id=solve>0</span></div>

<script>
const c=document.getElementById('c'),ctx=c.getContext('2d');
const w=25,h=18,cellSize=24;
c.width=w*cellSize;c.height=h*cellSize;

let grid=[],carveCount=0,solveCount=0,currentPath=[],solveStarted=false,solution=null;

function createGrid() {
  for(let y=0;y<h;y++)grid[y]=new Array(w).fill().map(()=>'1111');
}

function getNeighbors(x,y,visited) {
  let neighbors=[];
  const dirs=[[1,0],[0,1],[-1,0],[0,-1]];
  for(let [dx,dy] of dirs) {
    let nx=x+dx,ny=y+dy;
    if(nx>=0&&nx<w&&ny>=0&&ny<h&&!visited[ny][nx]) 
      neighbors.push({x:ny,y:nx});
  }
  return neighbors;
}

function carveMaze() {
  const stack=[],path=[],current={x:Math.floor(Math.random()*h),y:Math.floor(Math.random()*w)};
  grid[current.y]=grid[current.y].fill('1111');
  stack.push(current);
  
  while(stack.length) {
    let cell=stack[stack.length-1];
    ctx.fillStyle='#333';ctx.fillRect(cell.y*cellSize,cell.x*cellSize,cellSize-1,cellSize-1);
    
    if(!path.includes(cell)) path.push(cell);
    let visited=new Array(h).fill().map(()=>new Array(w).fill(false));
    
    while(path.length) {
      let next=path[path.length-1];
      visited[next.y][next.x]=true;
      
      for(let n of getNeighbors(next.x+1,next.y+1,visited)) {
        if(!grid[n.y][n.x]) continue;
        grid[n.y][n.x]='0000';
        ctx.fillStyle='#666';ctx.fillRect(n.y*cellSize,n.x*cellSize,cellSize-1,cellSize-1);
        if(carveCount++<w*h) ctx.fillStyle='#f00';else break;
      }
      
      let back=false;
      for(let n of getNeighbors(next.x+1,next.y)) {
        if(grid[n.y][n.x]&&visited[n.y][n.x]) {back=true;break;}
      }
      if(back) path.pop();
    }
    
    let dir=dirs[Math.floor(Math.random()*4)];
    let nx=current.y+dir[0],ny=current.x+dir[1];
    if(nx>=0&&nx<h&&ny>=0&&ny<w&&!grid[nx][ny]) {
      grid[nx][ny]='0000';
      ctx.fillStyle='#666';ctx.fillRect(ny*cellSize,nx*cellSize,cellSize-1,cellSize-1);
      current.y=nx;current.x=ny;
    }
  }
}

function solveMaze() {
  if(solveStarted) return;
  solveStarted=true;solution=null;solveCount=0;
  
  let start={x:0,y:h-1},end={x:w-1,y:0};
  let current=start,stack=[current];
  ctx.fillStyle='#f0f';ctx.fillRect(current.y*cellSize,current.x*cellSize,cellSize-1,cellSize-1);
  
  function solve() {
    if(current.x===end.x&&current.y===end.y) {
      solution=stack.slice();
      return;
    }
    
    let visited=new Array(h).fill().map(()=>new Array(w).fill(false));
    let next=null;
    
    for(let d of [[0,1],[1,0],[-1,0],[0,-1]]) {
      let ny=current.y+d[0],nx=current.x+d[1];
      if(ny>=0&&ny<h&&nx>=0&&nx<w&&!visited[ny][nx]&&!grid[ny][nx]) {next={x:nx,y:ny};break;}
    }
    
    if(next) {
      stack.push(next);
      ctx.fillStyle='#fff';ctx.fillRect(next.y*cellSize,next.x*cellSize,cellSize-1,cellSize-1);
      current=next;solveCount++;requestAnimationFrame(solve);
    } else {
      stack.pop();
      if(stack.length) {current=stack[stack.length-1];ctx.fillStyle='#ff0';ctx.fillRect(current.y*cellSize,current.x*cellSize,cellSize-1,cellSize-1);}
      solveCount++;
      requestAnimationFrame(solve);
    }
  }
  
  solve();
}

function animate() {
  if(!solveStarted) {
    createGrid();carveCount=0;solveCount=0;
    ctx.fillStyle='#666';ctx.fillRect(0,0,c.width,c.height);
    if(Math.random()<.1)ctx.fillStyle='#f00',ctx.fillRect(
      (Math.floor(Math.random()*w))*cellSize,
      (Math.floor(Math.random()*h))*cellSize,
      cellSize-2,cellSize-2
    );
  } else {
    ctx.fillStyle='#666';ctx.fillRect(0,0,c.width,c.height);
    if(solution) {
      for(let c of solution)solution[0].x==c.x? 
        ctx.fillStyle='#0ff' : ctx.fillStyle='#888';
      ctx.fillRect(c.y*cellSize,c.x*cellSize,cellSize-1,cellSize-1);
    }
  }
  
  document.getElementById('carve').textContent=carveCount;
  document.getElementById('solve').textContent=solveCount;
  
  if(solveStarted&&current.x==end.x&&current.y==end.y) {
    setTimeout(()=>animate(),500);
  } else {
    requestAnimationFrame(animate);
  }
}

animate();
</script>
</body></html>
```
llama3.1:8bERRSTATLIMFORMAT
Show code
```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>
.canvas {
  border: 1px solid black;
}
.step-count {
  font-size: 12px;
  color: gray;
}
.solving .step-count {
  color: blue;
}
.path {
  stroke-width: 2;
  fill: none;
}
.wanderer {
  fill: red;
}
.visited {
  fill-opacity: 0.5;
}
</style>
</head>
<body>
<canvas id="maze" width="25*20" height="18*20"></canvas>
<div class="step-count">Steps: <span id="solve-steps">0</span></div>
<script>
const canvas = document.getElementById('maze');
const ctx = canvas.getContext('2d');
const gridWidth = 25;
const gridHeight = 18;

function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function Cell(x, y) {
  this.x = x;
  this.y = y;
  this.visited = false;
  this.walls = [true, true, true, true];
  this.path = false;
  this.backtracking = false;
  this.solved = false;
}

let cells = [];
for (let i = 0; i < gridHeight; i++) {
  for (let j = 0; j < gridWidth; j++) {
    cells.push(new Cell(j, i));
  }
}

function carveMaze() {
  const stack = [];
  let currentCell = cells[randomInt(0, gridWidth * gridHeight - 1)];
  while (currentCell) {
    ctx.fillStyle = 'white';
    ctx.fillRect(currentCell.x * 20, currentCell.y * 20, 20, 20);
    if (!currentCell.visited) {
      currentCell.visited = true;
      stack.push(currentCell);
    }
    let nextCells = getUnvisitedNeighbors(currentCell);
    if (nextCells.length > 0) {
      const nextCell = nextCells[randomInt(0, nextCells.length - 1)];
      removeWall(currentCell, nextCell);
      currentCell = nextCell;
    } else {
      currentCell.backtracking = true;
      currentCell = stack.pop();
    }
  }
}

function getUnvisitedNeighbors(cell) {
  const unvisitedNeighbors = [];
  if (cell.x > 0 && !cells[cell.y * gridWidth + cell.x - 1].visited) unvisitedNeighbors.push(cells[cell.y * gridWidth + cell.x - 1]);
  if (cell.x < gridWidth - 1 && !cells[cell.y * gridWidth + cell.x + 1].visited) unvisitedNeighbors.push(cells[cell.y * gridWidth + cell.x + 1]);
  if (cell.y > 0 && !cells[(cell.y - 1) * gridWidth + cell.x].visited) unvisitedNeighbors.push(cells[(cell.y - 1) * gridWidth + cell.x]);
  if (cell.y < gridHeight - 1 && !cells[(cell.y + 1) * gridWidth + cell.x].visited) unvisitedNeighbors.push(cells[(cell.y + 1) * gridWidth + cell.x]);
  return unvisitedNeighbors;
}

function removeWall(cellA, cellB) {
  if (cellA.x === cellB.x) {
    if (cellA.y < cellB.y) {
      cellA.walls[3] = false;
      cellB.walls[1] = false;
    } else {
      cellA.walls[1] = false;
      cellB.walls[3] = false;
    }
  } else {
    if (cellA.x < cellB.x) {
      cellA.walls[2] = false;
      cellB.walls[0] = false;
    } else {
      cellA.walls[0] = false;
      cellB.walls[2] = false;
    }
  }
}

function drawMaze() {
  ctx.fillStyle = 'black';
  for (let i = 0; i < gridHeight; i++) {
    for (let j = 0; j < gridWidth; j++) {
      if (cells[i * gridWidth + j].walls[0]) ctx.beginPath(); ctx.moveTo(j * 20, i * 20); ctx.lineTo((j + 1) * 20, i * 20); ctx.stroke();
      if (cells[i * gridWidth + j].walls[1]) ctx.beginPath(); ctx.moveTo((j + 1) * 20, i * 20); ctx.lineTo((j + 1) * 20, (i + 1) * 20); ctx.stroke();
      if (cells[i * gridWidth + j].walls[2]) ctx.beginPath(); ctx.moveTo(j * 20, (i + 1) * 20); ctx.lineTo((j + 1) * 20, (i + 1) * 20); ctx.stroke();
      if (cells[i * gridWidth + j].walls[3]) ctx.beginPath(); ctx.moveTo(j * 20, i * 20); ctx.lineTo(j * 20, (i + 1) * 20); ctx.stroke();
    }
  }
}

function solveMaze() {
  let wanderer = cells[randomInt(0, gridWidth * gridHeight - 1)];
  wanderer.solved = true;
  const stack = [];
  let currentCell = wanderer;
  while (currentCell !== null) {
    ctx.fillStyle = 'green';
    ctx.fillRect(wanderer.x * 20, wanderer.y * 20, 20, 20);
    if (wanderer.walls[0] && !cells[(wanderer.y - 1) * gridWidth + wanderer.x].solved) {
      wanderer.walls[0] = false;
      cells[(wanderer.y - 1) * gridWidth + wanderer.x].walls[3] = false;
      currentCell = cells[(wanderer.y - 1) * gridWidth + wanderer.x];
    } else if (wanderer.walls[1] && !cells[wanderer.y * gridWidth + wanderer.x + 1].solved) {
      wanderer.walls[1] = false;
      cells[wanderer.y * gridWidth + wanderer.x + 1].walls[0] = false;
      currentCell = cells[wanderer.y * gridWidth + wanderer.x + 1];
    } else if (wanderer.walls[2] && !cells[(wanderer.y + 1) * gridWidth + wanderer.x].solved) {
      wanderer.walls[2] = false;
      cells[(wanderer.y + 1) * gridWidth + wanderer.x].walls[1] = false;
      currentCell = cells[(wanderer.y + 1) * gridWidth + wanderer.x];
    } else if (wanderer.walls[3] && !cells[wanderer.y * gridWidth + wanderer.x - 1].solved) {
      wanderer.walls[3] = false;
      cells[wanderer.y * gridWidth + wanderer.x - 1].walls[2] = false;
      currentCell = cells[wanderer.y * gridWidth + wanderer.x - 1];
    } else {
      stack.push(wanderer);
      if (currentCell) {
        ctx.fillStyle = 'blue';
        ctx.fillRect(currentCell.x * 20, currentCell.y * 20, 20, 20);
        wanderer.solved = true;
        wanderer.path = true;
        wanderer.backtracking = false;
        wanderer = stack.pop();
      } else {
        wanderer.solved = true;
        wanderer.path = true;
        wanderer.backtracking = false;
      }
    }
    ctx.fillStyle = 'black';
    wanderer = currentCell;
  }
}

function animate() {
  ctx.fillStyle = 'white';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  carveMaze();
  drawMaze();
  ctx.beginPath();
  ctx.strokeStyle = 'blue';
  for (let i = 0; i < gridHeight; i++) {
    for (let j = 0; j < gridWidth; j++) {
      if (cells[i * gridWidth + j].path) ctx.moveTo(j * 20, i * 20); 
      else if (cells[i * gridWidth + j].backtracking) ctx.lineTo(j * 20, i * 20);
    }
  }
  ctx.stroke();
  ctx.fillStyle = 'black';
  let carvedCount = 0;
  for (let i = 0; i < gridHeight; i++) {
    for (let j = 0; j < gridWidth; j++) {
      if (cells[i * gridWidth + j].visited) carvedCount++;
    }
  }
  document.getElementById('carved-steps').textContent = `Carved: ${carvedCount}`;
  setTimeout(() => {
    solveMaze();
    ctx.beginPath();
    ctx.strokeStyle = 'green';
    for (let i = 0; i < gridHeight; i++) {
      for (let j = 0; j < gridWidth; j++) {
        if (cells[i * gridWidth + j].solved) ctx.moveTo(j * 20, i * 20); 
        else if (cells[i * gridWidth + j].path) ctx.lineTo(j * 20, i * 20);
      }
    }
    ctx.stroke();
    let solveSteps = 0;
    for (let i = 0; i < gridHeight; i++) {
      for (let j = 0; j < gridWidth; j++) {
        if (cells[i * gridWidth + j].path) solveSteps++;
      }
    }
    document.getElementById('solve-steps').textContent = `Steps: ${solveSteps}`;
    setTimeout(() => {
      carveMaze();
      drawMaze();
      ctx.fillStyle = 'white';
      for (let i = 0; i < gridHeight; i++) {
        for (let j = 0; j < gridWidth; j++) {
          ctx.fillRect(j * 20, i * 20, 20, 20);
        }
      }
      setTimeout(() => animate(), 1000);
    }, 2000);
  }, 500);
}

animate();
</script>
</body>
</html>
```
qwen3-coder:30bERRBLANKLIM
Show code
<!DOCTYPE html>
<html><head><title>Maze Runner</title></head><body style="background:#111;margin:0;display:flex;justify-content:center;padding-top:20px;"><canvas id="mazeCanvas" width="640" height="480" style="border:1px solid #333;"></canvas><div id="stats" style="color:#eee;text-align:center;margin-top:10px;"></div><script>
const CANVAS = document.getElementById('mazeCanvas');
const CTX = CANVAS.getContext('2d');
const STATS_DIV = document.getElementById('stats');

// Grid constants (Approx 25x18)
const COLS = 25;
const ROWS = 18;
const CELL_SIZE = Math.min(CANVAS.width, CANVAS.height) / Math.max(COLS, ROWS); // Scale uniformly
const WALL_COLOR = '#333';
const PATH_COLOR = '#000';
const ACTIVE_COLOR = '#FFD700'; // Gold for current cell
const STACK_PATH_COLOR = '#4CAF50'; // Green for stack path
const EXPLORED_COLOR = '#222'; // Muted grey/dark color for backtracked paths
const SOLUTION_COLOR = '#FF6347'; // Tomato red for solution path

// State variables
let mazeGrid; 
let visited;
let carvedCellsCount = 0;
let stepsTaken = 0;
let animationRunning = false;

// --- Utility Functions ---

function getCoords(r, c) { return { r: Math.floor(c / (CELL_SIZE * 2)), c: Math.floor(r / (CELL_SIZE * 2)) }; }
function drawCell(r, c, color) {
    const x = c * CELL_SIZE * 2;
    const y = r * CELL_SIZE * 2;
    CTX.fillStyle = color || PATH_COLOR;
    CTX.fillRect(x, y, CELL_SIZE, CELL_SIZE);
}

// --- Maze Carving Phase (Recursive Backtracking) ---

function initializeMaze() {
    mazeGrid = Array(ROWS).fill(0).map(() => Array(COLS).fill(1)); // 1=Wall, 0=Path
    visited = Array(ROWS).fill(0).map(() => Array(COLS).fill(false));
    carvedCellsCount = 0;

    // Start at a random cell (must be odd coordinates for proper wall carving)
    let startR = Math.floor(Math.random() * ((ROWS / 2) - 1)) * 2 + 1;
    let startC = Math.floor(Math.random() * ((COLS / 2) - 1)) * 2 + 1;

    // Ensure starting point is within bounds and odd
    if (startR < 1 || startC < 1) { startR = 1; startC = 1; }

    const stack = [{ r: startR, c: startC }];
    visited[startR][startC] = true;
    drawInitialMaze(); 
    
    animateCarve(stack);
}

function drawInitialMaze() {
    CTX.clearRect(0, 0, CANVAS.width, CANVAS.height);
    for (let r = 0; r < ROWS; r++) {
        for (let c = 0; c < COLS; c++) {
            if (mazeGrid[r][c] === 1) { // If it's a wall initially
                const x = c * CELL_SIZE * 2;
                const y = r * CELL_SIZE * 2;
                CTX.fillStyle = WALL_COLOR;
                CTX.fillRect(x, y, CELL_SIZE, CELL_SIZE);
            } else { // If it's a path (shouldn't happen initially)
                 CTX.fillStyle = PATH_COLOR;
                 CTX.fillRect(x, y, CELL_SIZE, CELL_SIZE);
            }
        }
    }
}

function carvePassage(r1, c1, r2, c2) {
    const dr = Math.abs(r1 - r2);
    const dc = Math.abs(c1 - c2);
    // Carve the two cells (the wall between them)
    let midR = r1 + (r2 > r1 ? 0 : 1); // Simple heuristic for finding middle point
    let midC = c1 + (c2 > c1 ? 0 : 1);

    // We are carving a passage, so we mark the wall cell as path (0)
    const wallR = Math.min(r1, r2), wallC = Math.min(c1, c2);
    if (Math.abs(r1 - r2) === 2 && Math.abs(c1 - c2) === 0) { // Vertical move
        mazeGrid[wallR + (r1 < r2 ? 1 : 0)][Math.min(c1, c2)] = 0;
    } else if (Math.abs(r1 - r2) === 0 && Math.abs(c1 - c2) === 2) { // Horizontal move
        mazeGrid[Math.min(r1, r2)][wallC + (c1 < c2 ? 1 : 0)] = 0;
    } else if (Math.abs(r1 - r2) === 2 && Math.abs(c1 - c2) === 2) { // Diagonal move (shouldn't happen in standard grid carving, but for safety)
        // This simplified implementation assumes movement is along axes and carves the cell at the center of the passage gap.
    }

    // The core path cells are already set to 0 by initialization or previous carvings. We just need to mark the connecting wall cleared.
    mazeGrid[r2][c2] = 0; // Ensure destination is marked as open path
}

function getNeighbors(r, c) {
    const neighbors = [];
    const potentialMoves = [[-2, 0], [2, 0], [0, -2], [0, 2]]; // Only jump over walls (2 units)
    for (const [dr, dc] of potentialMoves) {
        let nr = r + dr;
        let nc = c + dc;
        if (nr >= 1 && nr < ROWS - 1 && nc >= 1 && nc < COLS - 1 && !visited[nr][nc]) {
            neighbors.push({r: nr, c: nc});
        }
    }
    return neighbors;
}

function solveMaze(currentR, currentC, path = []) {
    const startR = 1; // Corner starting point for solving visualization
    const startC = 1;
    const endR = ROWS - 2;
    const endC = COLS - 2;

    // DFS/Wall Follower implementation: Find a path to the target corner (endR, endC)
    let stack = [{ r: currentR, c: currentC }];
    let visitedSolve = Array(ROWS).fill(0).map(() => Array(COLS).fill(false));

    while (stack.length > 0) {
        const { r, c } = stack[stack.length - 1];
        if (r < 0 || r >= ROWS || c < 0 || c >= COLS || visitedSolve[r][c]) {
            stack.pop(); continue;
        }

        visitedSolve[r][c] = true;
        path.push({r, c});
        stepsTaken++;

        if (r === endR && c === endC) {
            return path; // Solution found!
        }

        // Potential moves: Check neighbors that are paths and not yet visited in this solve attempt
        const potentialMoves = [[-1, 0], [1, 0], [0, -1], [0, 1]];
        let nextMoveFound = false;
        for (const [dr, dc] of potentialMoves) {
            const nr = r + dr;
            const nc = c + dc;
            if (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS && mazeGrid[nr][nc] === 0 && !visitedSolve[nr][nc]) {
                stack.push({r: nr, c: nc});
                nextMoveFound = true;
                break; // Move immediately to the first valid neighbor (simple path following)
            }
        }

        if (!nextMoveFound) {
            // Dead end or reached target. Backtrack if not at the start.
            stack.pop(); 
        }
    }
    return []; // Should ideally not happen if maze is solvable
}


function animateCarve(stack) {
    if (stack.length === 0) return;

    const current = stack[stack.length - 1];
    let nextNeighbors = getNeighbors(current.r, current.c);
    let pathHistory = []; // Simulate the active path for rendering purposes

    // 1. Draw background and clear highlights
    CTX.clearRect(0, 0, CANVAS.width, CANVAS.height);
    for (let r = 0; r < ROWS; r++) {
        for (let c = 0; c < COLS; c++) {
            if (mazeGrid[r][c] === 1) {
                const x = c * CELL_SIZE * 2;
                const y = r * CELL_SIZE * 2;
                CTX.fillStyle = WALL_COLOR;
                CTX.fillRect(x, y, CELL_SIZE, CELL_SIZE);
            } else {
                 const x = c * CELL_SIZE * 2;
                 const y = r * CELL_SIZE * 2;
                 CTX.fillStyle = PATH_COLOR;
                 CTX.fillRect(x, y, CELL_SIZE, CELL_SIZE);
            }
        }
    }

    // 2. Highlight the stack path (all visited cells)
    // In a real scenario, we would track all carved coordinates, but here we highlight the current stack's visible path structure.
    for(let i = 0; i < stack.length - 1; i++) {
        const {r: r1, c: c1} = stack[i];
        const {r: r2, c: c2} = stack[i+1];
        // Draw the passage connecting them (already path color)
    }

    // 3. Highlight current cell
    CTX.fillStyle = ACTIVE_COLOR;
    const xCur = current.c * CELL_SIZE * 2;
    const yCur = current.r * CELL_SIZE * 2;
    CTX.fillRect(xCur, yCur, CELL_SIZE, CELL_SIZE);

    // 4. Check for next move (randomly pick one)
    let possibleMoves = nextNeighbors.filter(n => !visited[n.r][n.c]);
    if (possibleMoves.length > 0) {
        let nextCell = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];

        // Carve passage
        carvedCellsCount++;
        mazeGrid[nextCell.r][nextCell.c] = 0; // Mark as path
        visited[nextCell.r][nextCell.c] = true;

        // Push and recurse/animate
        stack.push(nextCell);
    } else {
        // Backtrack: Pop the stack
        stack.pop();
    }

    drawStats("Carving:", carvedCellsCount, null);
    animationRunning = true;
    requestAnimationFrame(() => animateCarve(stack));
}


// --- Solution Phase ---

function solveAnimation(path) {
    if (stepsTaken >= path.length || !path[0]) return;

    const currentPathLength = Math.min(stepsTaken, path.length);
    const targetPos = path[currentPathLength]; 

    // Draw the complete background first
     CTX.clearRect(0, 0, CANVAS.width, CANVAS.height);
    for (let r = 0; r < ROWS; r++) {
        for (let c = 0; c < COLS; c++) {
            const x = c * CELL_SIZE * 2;
            const y = r * CELL_SIZE * 2;
            CTX.fillStyle = mazeGrid[r][c] === 1 ? WALL_COLOR : PATH_COLOR;
            CTX.fillRect(x, y, CELL_SIZE, CELL_SIZE);
        }
    }

    // Draw the solution path (all points up to current)
    for(let i=0; i < Math.min(path.length, currentPathLength + 1); i++) {
         const {r: pr, c: pc} = path[i];
         const x = pc * CELL_SIZE * 2;
         const y = pr * CELL_SIZE * 2;
         CTX.fillStyle = (i === path.length - 1) ? SOLUTION_COLOR : '#8B0000'; // Darker red for previous steps
         CTX.fillRect(x, y, CELL_SIZE, CELL_SIZE);
    }

    // Highlight current position (Wanderer)
    const {r: cr, c: cc} = path[Math.min(path.length - 1, Math.max(0, currentPathLength))];
    CTX.fillStyle = ACTIVE_COLOR;
    const xCurr = cc * CELL_SIZE * 2;
    const yCurr = cr * CELL_SIZE * 2;
    CTX.fillRect(xCurr, yCurr, CELL_SIZE, CELL_SIZE);

    drawStats("Solving:", stepsTaken, null);

    if (currentPathLength < path.length) {
        setTimeout(() => requestAnimationFrame(() => solveAnimation(path)), 50); // Slow down animation slightly
    } else {
        // Solution complete! Wait and reset
        setTimeout(() => {
            alert("Maze Solved!");
            resetGame();
        }, 1500);
    }
}


// --- Main Loop Control ---

function solveAndReset() {
    const startR = 1; 
    const startC = 1;
    const endR = ROWS - 2;
    const endC = COLS - 2;
    
    // 1. Solve the generated maze
    const solutionPath = solveMaze(startR, startC, []);

    if (solutionPath.length > 0) {
        // 2. Animate solving
        solveAnimation(solutionPath);
    } else {
        // Fallback: If solving fails, just reset
        resetGame();
    }
}


function startGame() {
    mazeGrid = null;
    visited = null;
    carvedCellsCount = 0;
    stepsTaken = 0;
    animateCarve(null); // Start the carving process
}

function drawStats(phase, count1, count2) {
    let html = ``;
    if (phase === "Carving:") {
        html += `<span style="color: #4CAF50;">Maze Generation Progress:</span> ${count1} cells carved.`;
    } else if (phase === "Solving:") {
        html += `<span style="color: #FF6347;">Current Phase: Solving.</span> Steps taken: ${count2}.`;
    } else if (!phase) {
         html += `Ready to start maze generation...`;
    }
    STATS_DIV.innerHTML = html;
}

function resetGame() {
    // Reset all state variables and restart the loop
    startGame();
}


// Initial setup call
window.onload = () => {
    drawStats("Awaiting Start:", 0, 0);
    setTimeout(startGame, 500); // Delay slightly for visual effect
};

</script></body></html>
qwen3.5:9bSTATLIMFORMAT
Show code
```html
<!DOCTYPE html>
<head><title>Animated Maze Solver</title></head>
<body><canvas id="mazeCanvas" width="600" height="480"></canvas><script>
const canvas = document.getElementById('mazeCanvas');
const ctx = canvas.getContext('2d');
const COLS = 25;
const ROWS = 18;
const CELL_SIZE = Math.min(Math.floor(canvas.width / (COLS + 1)), Math.floor(canvas.height / (ROWS + 1)));

let grid = [];
let visited = Array(ROWS).fill(0).map(() => Array(COLS).fill(false));
let stack = [];
let isGenerating = false;
let isSolving = false;

let carvedCount = 0;
let solveSteps = 0;

function initGrid() {
    grid = Array(ROWS).fill(0).map(() => Array(COLS).fill(false)); // 0: Wall, 1: Path
    visited = Array(ROWS).fill(0).map(() => Array(COLS).fill(false));
    stack = [];
    carvedCount = 0;
    solveSteps = 0;

    for (let r = 0; r < ROWS; r++) {
        for (let c = 0; c < COLS; c++) {
            grid[r][c] = 1; // Start with all paths intact
        }
    }
}

function drawGrid() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    for (let r = 0; r < ROWS; r++) {
        for (let c = 0; c < COLS; c++) {
            const x1 = (c + 0.5) * CELL_SIZE;
            const y1 = (r + 0.5) * CELL_SIZE;
            const x2 = (c + 1) * CELL_SIZE;
            const y2 = (r + 1) * CELL_SIZE;

            // Draw Walls (Default: Black/Grey lines between cells)
            ctx.strokeStyle = '#333';
            ctx.lineWidth = 2;
            ctx.strokeRect(c * CELL_SIZE, r * CELL_SIZE, CELL_SIZE, CELL_SIZE);
        }
    }

    // Redraw the current state of passages (1=Path) and walls (0=Wall)
    for (let r = 0; r < ROWS; r++) {
        for (let c = 0; c < COLS; c++) {
            const x = c * CELL_SIZE;
            const y = r * CELL_SIZE;

            // Draw wall segments based on grid state
            ctx.fillStyle = '#111'; // Wall color
            ctx.fillRect(x, y, CELL_SIZE, CELL_SIZE); 
        }
    }
    
    // Erase paths (where grid[r][c] == 1)
    for (let r = 0; r < ROWS; r++) {
        for (let c = 0; c < COLS; c++) {
            if (grid[r][c]) {
                ctx.fillStyle = '#fff'; // Path color
                ctx.fillRect(c * CELL_SIZE, r * CELL_SIZE, CELL_SIZE, CELL_SIZE);
            }
        }
    }

    // Draw active state layers on top
    if (isGenerating) {
        const currentCell = stack[stack.length - 1];
        ctx.fillStyle = 'rgba(255, 0, 0, 0.3)'; // Highlight Current Cell
        ctx.fillRect(currentCell.c * CELL_SIZE, currentCell.r * CELL_SIZE, CELL_SIZE, CELL_SIZE);

        // Draw Stack Path (Muted blue)
        for(let i = 1; i < stack.length; i++) {
            const cell = stack[i];
             ctx.fillStyle = 'rgba(0, 0, 255, 0.2)';
             ctx.fillRect(cell.c * CELL_SIZE, cell.r * CELL_SIZE, CELL_SIZE, CELL_SIZE);
        }
    } else if (isSolving) {
        // Draw explored paths (Muted green/grey - dead ends)
        for(let r = 0; r < ROWS; r++) {
            for(let c = 0; c < COLS; c++) {
                if (grid[r][c] && !visited[r][c]) { // If path, but not yet solved/explored
                    const x = c * CELL_SIZE;
                    const y = r * CELL_SIZE;
                    ctx.fillStyle = 'rgba(100, 100, 100, 0.3)';
                    ctx.fillRect(x, y, CELL_SIZE, CELL_SIZE);
                }
            }
        }

        // Highlight Wanderer (Current position)
        const wanderer = {r: Math.floor((solveSteps * 2) % ROWS), c: Math.floor((solveSteps * 3) % COLS)}; // Placeholder visualization
        ctx.fillStyle = 'rgba(0, 150, 0, 0.7)';
        ctx.fillRect(wanderer.c * CELL_SIZE, wanderer.r * CELL_SIZE, CELL_SIZE, CELL_SIZE);

        // Highlight solution path (Yellow)
        for (let r = 0; r < ROWS; r++) {
            for (let c = 0; c < COLS; c++) {
                if (grid[r][c] && visited[r][c]) {
                    const x = c * CELL_SIZE;
                    const y = r * CELL_SIZE;
                    ctx.fillStyle = 'rgba(255, 200, 0, 0.3)';
                    ctx.fillRect(x, y, CELL_SIZE, CELL_SIZE);
                }
            }
        }
    }

    // Draw Counters (Simplified visualization)
    document.getElementById('mazeCanvas').style.borderBottom = '1px solid #aaa';
    if (!isGenerating && !isSolving) {
        ctx.fillText("Ready to Run", 20, CELL_SIZE - 10);
    } else if (isGenerating) {
        ctx.fillStyle = '#333';
        ctx.font = '16px Arial';
        ctx.fillText(`Carved: ${carvedCount}/${ROWS * COLS}`, 20, 30);
    } else if (isSolving) {
         ctx.fillStyle = '#333';
        ctx.font = '16px Arial';
        ctx.fillText(`Steps: ${solveSteps}`, 20, 30);
    }

}

// --- Phase 1: Maze Generation (Recursive Backtracking) ---
function carve(r, c) {
    if (!isGenerating) return;

    visited[r][c] = true;
    stack.push({r, c});
    carvedCount++;
    drawGrid();

    const neighbors = [[0, 1], [0, -1], [1, 0], [-1, 0]];
    // Shuffle directions for randomness
    neighbors.sort(() => Math.random() - 0.5);

    for (const [dr, dc] of neighbors) {
        let nr = r + dr;
        let nc = c + dc;

        if (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS && !visited[nr][nc]) {
            // Move two steps to ensure wall separation
            let nextR = r + 2 * dr;
            let nextC = c + 2 * dc;

            if (nextR >= 0 && nextR < ROWS && nextC >= 0 && nextC < COLS && !visited[nextR][nextC]) {
                // Carve path between current and neighbor, and to the neighbor
                grid[r][c] = true; // Current cell is always part of the path
                grid[Math.floor((r + nr) / 2)][Math.floor((c + nc) / 2)] = true; // Wall removed

                carve(nr, nc);
                return;
            }
        }
    }

    if (stack.length > 1) {
        // Backtrack: Pop the last cell and remove its visit status for visual path tracking
        const popped = stack.pop();
        // We don't un-visit it entirely, just that we backtracked from it.
    }

    if (!isGenerating && carvedCount >= ROWS * COLS) {
        console.log("Maze generation finished.");
        startSolving();
    }
}

function startGenerating() {
    initGrid();
    // Start at a random cell (must be odd/even based on grid structure, but for simplicity we just pick one corner and adjust the logic above)
    carve(1, 1); 
    isGenerating = true;
    drawGrid();
}

// --- Phase 2: Solving (Simple DFS/Wall Follower approximation) ---
let solvePath = []; // Stores the solved path coordinates
function startSolving() {
    if (!grid[0][0] || !carvedCount) return;

    isGenerating = false;
    isSolving = true;
    solveSteps = 0;
    visited.forEach(row => row.fill(false)); // Reset visited for solving visualization

    // Set start and end points (Top-Left to Bottom-Right conceptual goal)
    let currentR = 1;
    let currentC = 1;

    solvePath = [{r: currentR, c: currentC}];
    visited[currentR][currentC] = true;

    // Simple iterative DFS approach for solving (since actual wall following is complex for this constraint)
    function solveStep() {
        if (!isSolving) return;
        solveSteps++;

        let r = solvePath[solvePath.length - 1].r;
        let c = solvePath[solvePath.length - 1].c;

        // Check neighbors (Up, Down, Left, Right) for unvisited path cells
        const potentialMoves = [[-1, 0], [1, 0], [0, -1], [0, 1]];
        potentialMoves.sort(() => Math.random() - 0.5); // Random exploration order

        let nextR = -1, nextC = -1;

        for (const [dr, dc] of potentialMoves) {
            let nr = r + dr;
            let nc = c + dc;

             if (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS && grid[nr][nc] && !visited[nr][nc]) {
                nextR = nr;
                nextC = nc;
                break;
            }
        }

        if (nextR !== -1) {
            // Move forward
            solvePath.push({r: nextR, c: nextC});
            visited[nextR][nextC] = true;
        } else if (solveSteps > 50 && solvePath.length > 10) {
             // Stalled or finished solving due to complexity/time limit
             isSolving = false;
             console.log("Solving complete.");
        } else {
            // Dead end or need complex backtracking logic which is omitted for brevity, relying on the general DFS nature
            // In a real solver, we would backtrack here if no moves are found.
        }

        drawGrid();
    }

    solveStep(); // Kick off the first step
}


// --- Main Animation Loop ---
function animate() {
    if (isGenerating) {
        carve(stack[stack.length - 1].r, stack[stack.length - 1].c);
    } else if (isSolving && solvePath.length < ROWS * COLS / 2) { // Solve until a certain threshold or failure
        solveStep();
    } else if (isSolving && solvePath.length >= ROWS * COLS / 2) {
        // Solving finished, pause, then restart
        setTimeout(() => {
            startGenerating();
        }, 1000); // Pause for 1 second
    }

    requestAnimationFrame(animate);
}

// Initial setup call
window.onload = function() {
    initGrid();
    drawGrid();
    animate();
};
</script></body></html>
```
mistral-small:24bHANGFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Maze Generation and Solving</title>
<style>
body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f0f0f0; }
canvas { border: 1px solid black; }
</style>
</head>
<body>
<canvas id="mazeCanvas" width="625" height="378"></canvas>
<script>

function create2DArray(cols, rows) {
    let arr = new Array(rows);
    for (let i = 0; i < rows; i++) {
        arr[i] = new Array(cols).fill(1)
    }
    return arr
}

function shuffle(a) {
    for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
}

const canvas = document.getElementById('mazeCanvas');
const ctx = canvas.getContext('2d');
let mazeGrid;
let stack = [];
let carveCounter = 0;
let solveCounter = 0;

function drawMaze() {
    let cellSize = 25;
    for (let row = 0; row < mazeGrid.length; row++) {
        for (let col = 0; col < mazeGrid[0].length; col++) {
            let x = col * cellSize;
            let y = row * cellSize;
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 3;
            if (mazeGrid[row][col] === 1) {
                ctx.fillStyle = '#ffffff';
                ctx.fillRect(x, y, cellSize, cellSize);
                ctx.strokeRect(x, y, cellSize, cellSize);
            }
        }
    }
}

function carvePassage(currentCell) {
    let colList = [-1, 1];
    let rowList = [-1, 1];
    shuffle(colList);
    shuffle(rowList);

    for (let i = 0; i < colList.length; i++) {
        let newCol = currentCell[0] + colList[i]
        if (newCol >= 0 && newCol < mazeGrid[0].length) {
            let newRow = currentCell[1];
            if (mazeGrid[newRow][newCol] === 1) {
                stack.push([currentCell[0], currentCell[1]]);
                mazeGrid[currentCell[1]][currentCell[0]] = 0;
                mazeGrid[newRow][newCol] = 0;
                carveCounter++;
                return [newCol, newRow];
            }
        }

    }

    for (let i = 0; i < rowList.length; i++) {
        let newRow = currentCell[1] + rowList[i]
        if (newRow >= 0 && newRow < mazeGrid.length) {
            let newCol = currentCell[0];
            if (mazeGrid[newRow][newCol] === 1) {
                stack.push([currentCell[0], currentCell[1]]);
                mazeGrid[currentCell[1]][currentCell[0]] = 0;
                mazeGrid[newRow][newCol] = 0;
                carveCounter++;
                return [newCol, newRow];
            }
        }

    }
    stack.pop();
    if(stack.length > 0) {
        return stack[stack.length -1]
    } else {
        return null
    }

}

function drawStackPath() {
    let cellSize = 25;
    ctx.fillStyle = 'blue';
    for (let i = 0; i < stack.length; i++) {
        ctx.beginPath();
        ctx.rect(stack[i][0] * cellSize, stack[i][1] * cellSize, cellSize, cellSize);
        ctx.closePath();
        ctx.fill();
    }
}

function drawCarvedCell(currentCell) {
    let cellSize = 25;
    ctx.fillStyle = 'red';
    ctx.beginPath();
    ctx.rect(currentCell[0] * cellSize, currentCell[1] * cellSize, cellSize, cellSize);
    ctx.closePath();
    ctx.fill();
}

function drawCounter() {
    ctx.fillStyle = 'black';
    ctx.font = '24px Arial';
    ctx.fillText(`Carved Cells: ${carveCounter}`, 50, 360);
}

const mazeGeneration = () => {
    let startX = Math.floor(Math.random()*mazeGrid[0].length)
    let startY=Math.floor(Math.random()*mazeGrid.length);

    let currentCell=[startX,startY];
    while (carveCounter < mazeGrid.length * mazeGrid[0].length) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawMaze();
        drawStackPath();
        drawCarvedCell(currentCell);
        drawCounter();
        let nextCell = carvePassage(currentCell);
        currentCell = nextCell || [startX, startY];
    }
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    drawMaze()
    solveMaze([startX,startY],[mazeGrid[0].length -1,mazeGrid.length-1])
}

function drawWandersPath(wanderPath) {
    let cellSize = 25;
    ctx.fillStyle = 'green';
    for(let i=0; i<wanderPath.length;i++) {
        ctx.beginPath();
        ctx.rect(wanderPath[i][0] * cellSize, wanderPath[i][1]*cellSize, cellSize, cellSize);
        ctx.closePath();
        ctx.fill();
    }
}

function drawExploredCells(exploreCell) {
    let cellSize = 25;
    ctx.fillStyle = 'gray';
    for(let i=0; i<exploreCell.length;i++) {
        ctx.beginPath();
        ctx.rect(exploreCell[i][0] *cellSize, exploreCell[i][1]*cellSize, cellSize, cellSize);
        ctx.closePath();
        ctx.fill();
    }
}

function drawSolversCounter() {
    ctx.fillStyle = 'black';
    ctx.font = '24px Arial';
    ctx.fillText(`Solve Steps: ${solveCounter}`, 350, 360);
}

const solveMaze=(currentCell, endCell)=>{
    let directions=[[-1,0],[1,0],[0,-1],[0,1]];
    shuffle(directions)
    let wanderPath=[]
    let exploreCells= []
    solveCounter++
    while(currentCell[0] !==  endCell[0] || currentCell[1]!==endCell[1]){

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawMaze();

        for(let i=0; i< directions.length;i++) {
            let newCol=currentCell[0]+directions[i][0]
            let newRow= currentCell[1] + directions[i][1]

            if(newCol >= 0 && newCol < mazeGrid[0].length && newRow>=0 &&newRow <mazeGrid.length) {

                ctx.clearRect(0, 0, canvas.width, canvas.height);
                drawMaze();
                drawWandersPath(wanderPath)
                drawExploredCells(exploreCells)
                if (mazeGrid[newRow][newCol] === 1 || [newCol,newRow].toString()===exploreCells[exploreCells.length-1])
                    break
                else {
                    currentCell = [newCol, newRow]
                    solveCounter++
                    wanderPath.push([currentCell[0],currentCell[1]])
                    exploreCells.push(currentCell)
                    drawWandersPath(wanderPath)

                }
            }

        }

    }

}

const startMazeGeneration=(colCount=25, rowCount= 18)=> {
    mazeGrid = create2DArray(colCount,rowCount);
    requestAnimationFrame(mazeGeneration);
}
startMazeGeneration()
</script>
</body>
</html>
```
qwen3:8bERRBLANKMINIFIED
Show code
<!DOCTYPE html>
<html><head><title>Maze</title></head><body><canvas id=c></canvas><div id=s>0</div><div id=e>0</div><script>
const c=document.getElementById('c'),ctx=c.getContext('2d'),w=25,h=18,size=20,grid=Array(w).fill().map(_=>Array(h).fill().map(_=>({visited:false,walls:[1,1,1,1]})));
let stack=[],current,carved=0,solved=0;
function draw(){ctx.clearRect(0,0,c.width,c.height);for(let y=0;y<h;y++)for(let x=0;x<w;x++){let g=grid[x][y];if(g.visited){ctx.fillStyle=g===stack[stack.length-1]?'green':'lightgray';ctx.fillRect(x*size,y*size,size,size);for(let i=0;i<4;i++)if(g.walls[i]){ctx.strokeStyle='black';ctx.beginPath();ctx.moveTo(x*size,y*size+i===0?0:i===2?size:0);ctx.lineTo(x*size+(i===1?size:0),y*size+(i===2?size:0));ctx.stroke()}}}
}
function generate(){stack=[],current={x:Math.floor(Math.random()*w),y:Math.floor(Math.random()*h)},stack.push(current),current.visited=true,carved=1;while(stack.length){let cell=stack[stack.length-1];let neighbors=[];for(let dy=-1;dy<=1;dy+=2)for(let dx=-1;dx<=1;dx+=2){let nx=cell.x+dx,ny=cell.y+dy;if(nx>=0&&nx<w&&ny>=0&&ny<h&&!grid[nx][ny].visited)neighbors.push({x:nx,y:ny})};if(neighbors.length){let next=neighbors[Math.floor(Math.random()*neighbors.length)];let dir=[next.x-cell.x, next.y-cell.y];grid[cell.x][cell.y].walls[dir[0]+2*dir[1]]=0;grid[next.x][next.y].visited=true;stack.push(next);carved++;}else stack.pop();draw();document.getElementById('s').textContent=carved}
function solve(){let pos=[0,0],dir=0,steps=0,explored=Array(w).fill().map(_=>Array(h).fill(false)),solution=[];while(pos[0]!==24||pos[1]!==17){let nx=pos[0],ny=pos[1],d=dir;for(let i=0;i<4;i++){let newd=(d+i)%4;let dx=[-1,0,1,0][newd],dy=[0,1,0,-1][newd];let nx2=pos[0]+dx,ny2=pos[1]+dy;if(nx2>=0&&nx2<w&&ny2>=0&&ny2<h&&(!grid[nx2][ny2].walls[newd]||explored[nx2][ny2])){if(!explored[nx2][ny2]){explored[nx2][ny2]=true;pos=[nx2,ny2];dir=newd;break}if(i===3)break}if(pos[0]===24&&pos[1]===17)break}steps++;document.getElementById('e').textContent=steps;draw();requestAnimationFrame(()=>{if(pos[0]===24&&pos[1]===17){generate()}})}
}
generate();requestAnimationFrame(solve)
</script></body></html>
gemma4:26bharness
No answer reached us (ERR) — and the reason lies with our setup, not with the model: reasoning consumed the entire token budget (3 min 28 s, zero characters of answer); larger budgets are refused by the gateway Counted as a did-not-finish, but it is not evidence about this model.
qwen3:14bERRBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Autonomous Maze Solver</title>
    <style>
        body { background: #111; display: flex; justify-content: center; align-items: center; margin: 0; height: 100vh; font-family: sans-serif; color: white; }
        canvas { border: 2px solid #444; background: #000; }
    </style>
</head>
<body>

<canvas id="mazeCanvas"></canvas>
<div style="position: absolute; top: 10px; left: 30px; color: white;">Carved Cells: <span id="carveCount">0</span></div>
<div style="position: absolute; top: 10px; right: 30px; color: white;">Steps: <span id="stepCount">0</span></div>

<script>
    const canvas = document.getElementById('mazeCanvas');
    const ctx = canvas.getContext('2d');

    // Grid dimensions (odd numbers for proper wall separation)
    const COLS = 25;
    const ROWS = 18;
    const CELL_SIZE = 20; // Size used for drawing units
    canvas.width = COLS * CELL_SIZE + 2 * CELL_SIZE / 2; // Adjust width slightly for border visualization if needed, keeping it grid-aligned is simpler.
    canvas.height = ROWS * CELL_SIZE + 2 * CELL_SIZE / 2;

    // Adjusted dimensions to fit whole cells nicely
    const GRID_COLS = Math.floor(COLS / 2) - 1; // Number of inner nodes (excluding walls)
    const GRID_ROWS = Math.floor(ROWS / 2) - 1;
    const DRAW_SIZE = CELL_SIZE * 2;

    canvas.width = (GRID_COLS + 1) * DRAW_SIZE;
    canvas.height = (GRID_ROWS + 1) * DRAW_SIZE;


    // Maze structure: grid[y][x] stores the cell object/state.
    // We will use a simplified representation where walls are drawn implicitly by checking neighbors.
    // This array represents the actual state of passages (true=passage, false=wall).
    let maze = [];
    let visited = [];

    // --- Utility Functions ---

    function initGrid() {
        maze[ROWS] = Array(COLS).fill(0); // Placeholder structure initialization
        for (let r = 0; r < ROWS; r++) {
            maze[r] = Array(COLS).fill(false);
        }
        visited.forEach(() => visited.splice(0, visited.length, false));
    }

    function getCell(x, y) {
        if (x < 0 || x >= COLS || y < 0 || y >= ROWS) return null;
        return { x: x, y: y };
    }

    // --- Maze Generation (Recursive Backtracking) ---

    function carveMaze(cx, cy, cx_passed, cy_passed, pathStack) {
        if (!maze[cy][cx]) maze[cy][cx] = true; // Mark cell as part of the passage network
        visited[cy][cx] = true;

        const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];
        directions.sort(() => Math.random() - 0.5);

        for (const [dx, dy] of directions) {
            let nx = cx + dx * 2; // Jump two cells to avoid carving through walls immediately
            let ny = cy + dy * 2;

            // Check bounds and if the cell hasn't been visited yet
            if (nx >= 0 && nx < COLS && ny >= 0 && ny < ROWS && !visited[ny][nx]) {
                // Carve passage into the neighbor (and the wall between them)
                let wall_x = cx + dx;
                let wall_y = cy + dy;

                if (!maze[wall_y][wall_x]) maze[wall_y][wall_x] = true; // Carve wall
                
                carveMaze(nx, ny, cx, cy, [...pathStack, { x: cx, y: cy }]);
            }
        }
    }

    function generateNewMaze() {
        initGrid();
        // Reset all passages to false initially (clean slate)
        for(let r=0; r<ROWS; r++) for(let c=0; c<COLS; c++) maze[r][c] = false;
        
        visited.forEach(() => visited.splice(0, visited.length, false));

        // Start at a random odd cell (to ensure wall/passage structure)
        let startX = Math.floor(Math.random() * ((COLS - 1) / 2)) * 2 + 1;
        let startY = Math.floor(Math.random() * ((ROWS - 1) / 2)) * 2 + 1;

        carveMaze(startX, startY, 0, 0, []);
    }


    // --- Drawing Functions ---

    function drawGrid() {
        ctx.clearRect(-1, 0, canvas.width, canvas.height);

        for (let y = 0; y < ROWS; y++) {
            for (let x = 0; x < COLS; x++) {
                const isPassage = maze[y][x];
                
                // Calculate drawing coordinates based on the cell state
                let drawX = x * CELL_SIZE;
                let drawY = y * CELL_SIZE;

                ctx.fillStyle = isPassage ? '#222' : '#444'; // Passage vs Wall color
                ctx.fillRect(drawX, drawY, CELL_SIZE, CELL_SIZE);
            }
        }
    }

    function drawCellState(x, y, color) {
        const drawX = x * CELL_SIZE;
        const drawY = y * CELL_SIZE;
        ctx.fillStyle = color || '#000';
        ctx.fillRect(drawX, drawY, CELL_SIZE, CELL_SIZE);
    }

    function drawPassageVisualization() {
        // Redraw the base maze structure first
        drawGrid(); 

        let carveCount = 0;
        for (let y = 1; y < ROWS - 1; y += 2) {
            for (let x = 1; x < COLS - 1; x += 2) {
                if (maze[y][x]) {
                    carveCount++;
                }
            }
        }
        document.getElementById('carveCount').textContent = carveCount;
    }

    // --- Solving Phase Logic (Wall Follower / DFS Hybrid) ---

    let wandererX, wandererY;
    let solvingSteps = 0;
    const EXPLORED_COLOR = '#333'; // Muted color for explored/dead ends
    const SOLUTION_COLOR = '#FFCC00'; // Highlighted solution path
    const WANDERER_COLOR = '#00FFFF';

    function solveMaze(currentX, currentY, pathHistory) {
        // Wall Follower Logic (simplified DFS approach used here for reliable backtracking)
        let stack = [{ x: currentX, y: currentY }];
        let explored = new Set();

        while (stack.length > 0) {
            const current = stack[stack.length - 1];
            if (explored.has(`${current.x},${current.y}`)) {
                stack.pop(); // Backtrack
                continue;
            }
            
            // Mark as explored and push to path history only if it's a valid passage
            if (!maze[current.y][current.x]) {
                 stack.pop(); 
                 continue;
            }

            explored.add(`${current.x},${current.y}`);
            
            // Find unvisited neighbors (using simple directional checking)
            let foundNeighbor = false;
            const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];
            directions.sort(() => Math.random() - 0.5); // Randomize search order

            for (const [dx, dy] of directions) {
                let nx = current.x + dx;
                let ny = current.y + dy;

                // Check bounds and if it's a passage AND not yet visited in the exploration set
                if (nx >= 0 && nx < COLS && ny >= 0 && ny < ROWS && maze[ny][nx] && !explored.has(`${nx},${ny}`)) {
                    stack.push({ x: nx, y: ny });
                    foundNeighbor = true;
                    break; // Move to the neighbor immediately (DFS)
                }
            }

            if (!foundNeighbor) {
                // Dead end or all neighbors explored -> Backtrack pop happens above
                stack.pop();
            }
        }
        return Array.from(explored).map(s => s.split(',').map(Number));
    }


    // --- Animation Loop ---

    let isSolving = false;
    let solvePath = []; // Stores the path found by the solver

    function animateSolve() {
        if (!isSolving) return;

        const startX = COLS - 1;
        const startY = ROWS - 1;
        const endX = 0;
        const endY = 0;

        // If this is the first solve attempt, run the solver algorithm to get the path
        if (solvePath.length === 0) {
            // For simplicity and constrained code size, we simulate a basic DFS/BFS search path approximation
            // instead of running a full robust maze solver multiple times in the animation loop.
            let current = {x: startX, y: startY};
            solvePath = [{x: startX, y: startY}]; // Start point
            let queue = [current]; 

            while (queue.length > 0) {
                let next = queue.shift();
                if (next.y === endY && next.x === endX) break;

                const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];
                for(const [dx, dy] of directions) {
                    let nx = next.x + dx;
                    let ny = next.y + dy;

                    if (nx >= 0 && nx < COLS && ny >= 0 && ny < ROWS && maze[ny][nx] && !solvePath.some(p => p.x === nx && p.y === ny)) {
                        // Simple path tracing: just add the valid passage cell
                        solvePath.push({x: nx, y: ny});
                        queue.push({x: nx, y: ny});
                    }
                }
            }

        }


        if (solvePath.length === 0) { // Should only happen if maze generation failed
             console.error("Solver failed to find path.");
             reset();
             return;
        }
        
        // Get the current position for drawing
        const currentIndex = solvePath.findIndex(p => p.x === wandererX && p.y === wandererY);

        if (currentIndex < solvePath.length - 1) {
            // Move to the next step in the pre-calculated path
            const nextPoint = solvePath[currentIndex + 1];
            wandererX = nextPoint.x;
            wandererY = nextPoint.y;
            solvePath.unshift(nextPoint); // Keep the path history clean and active

        } else {
            // Reached the exit (0, 0) - End of current solving phase
            isSolving = false;
            document.getElementById('stepCount').textContent += solvePath.length - 1;
            setTimeout(reset, 2000); // Pause and restart after 2 seconds
        }

        // --- Drawing Phase ---
        ctx.clearRect(-1, 0, canvas.width, canvas.height);
        drawGrid();
        
        let stepCount = 0;
        for (let i = 0; i < solvePath.length; i++) {
            const p = solvePath[i];
            if (p.x === wandererX && p.y === wandererY) {
                drawCellState(p.x, p.y, WANDERER_COLOR); // Wanderer current
            } else if (maze[p.y][p.x]) {
                // Only color cells that are valid passages
                if (i < solvePath.length - 1 && i > 0) {
                    drawCellState(p.x, p.y, EXPLORED_COLOR); // Previously explored/visited path
                } else if (i == solvePath.length - 1 && i > 0) {
                     // Overwrite the last cell to show the final solution color
                    drawCellState(p.x, p.y, SOLUTION_COLOR); 
                }
            }
             stepCount++;
        }


        document.getElementById('stepCount').textContent = Math.max(0, solvePath.length - 1);

        requestAnimationFrame(animateSolve);
    }

    function reset() {
        solvePath = [];
        wandererX = COLS - 1;
        wandererY = ROWS - 1;
        isSolving = false;
        document.getElementById('stepCount').textContent = '0';
        // Start the loop immediately after a delay to allow visual pause
        setTimeout(() => {
            generateNewMaze();
            drawPassageVisualization();
            solvePath = []; // Clear old path data
             isSolving = true;
             animateSolve();
        }, 50);
    }

    // Initial run
    reset();

</script>
</body>
</html>
```
qwq:32bSTATLIM
Show code
<think>

Okay, let's tackle this problem. The user wants an HTML file that generates a maze using recursive backtracking and then solves it with a wanderer. First, I need to make sure the maze is created properly. The grid should be 25 columns by 18 rows. The recursive backtracking algorithm starts at a random cell, carves paths to unvisited neighbors, and keeps a stack for backtracking. I'll have to represent the grid with walls, maybe using a 2D array where each cell has wall information.

Next, the solving phase: choose a wall-follower or depth-first search. Wall-follower is simpler to animate. The wanderer should move step by step, highlighting its path and marking visited cells. The counters for carved cells and steps taken need to be updated. 

I need to use the canvas element for drawing. The animation should be smooth with requestAnimationFrame. The maze should restart automatically after solving. Also, ensure no external libraries are used. 

First, set up the HTML structure with a canvas and two divs for counters. Then the JavaScript part. 

For the maze generation: Initialize grid with all walls. Start at a random cell. Keep track of visited cells and the stack. When moving to a new cell, remove the common wall between current and next cell. Push next cell onto stack. When stuck, backtrack using the stack. Draw the maze step by step, highlighting the current cell and stack path. Show the counter for carved cells.

Solving phase: When all cells are visited, start the wanderer at one corner (like top-left), and move towards the exit (bottom-right). The wanderer should follow the right-hand rule, for example. Mark each step, track visited cells, and backtrack when hitting a dead end. The solution path needs to be distinguished from dead ends. Show steps taken, and when the exit is reached, reset the maze.

I need to handle the animation loop with requestAnimationFrame. During generation, each step (carving a path) is drawn, then the solving phase steps through the wanderer's moves. Need flags to know when to switch phases.

Potential challenges: Implementing the recursive backtracking correctly without getting stuck, especially the stack management. Also, ensuring the solving algorithm (wall follower) works correctly on the generated maze. Drawing the maze with walls and highlighting paths.

Let me outline the steps in code:

1. Setup canvas and context.
2. Create grid structure (maybe a 2D array where each cell has walls and visited status).
3. Initialize grid with walls.
4. Maze generation loop:
   a. Start at random cell, mark as visited.
   b. While stack not empty:
       i. Look for unvisited neighbors.
       ii. If any, pick random, remove walls between current and neighbor.
       iii. Push current to stack, move to neighbor, increment counter.
       iv. Else, backtrack to previous cell from stack.
5. Draw the maze step by step, highlighting current path and stack.
6. Once maze is done, start solving:
   a. Initialize wanderer at start cell.
   b. Use wall follower algorithm (like right-hand on walls).
   c. Track path, mark visited cells, highlight steps.
   d. When exit is reached, reset.

Wait, the solving needs to be animated as well. So after the maze is done generating, the solving steps are handled in the animation loop. The animation loop will switch between phases.

Variables needed: grid, current cell, stack, isGenerating, solvingPhase, wanderer position, etc.

In code structure:

The canvas is 25 cols and 18 rows. Let's set cell size to 20px (so canvas width 500, height 360). But maybe smaller for better visibility. Let me calculate: 25x20 = 500, 18x20=360. That might be okay, but the user might prefer a smaller size? But the problem says 'about' so maybe that's okay.

Now, the grid array. Each cell can have walls (top, right, bottom, left) and visited status.

For the recursive backtracking:

Initialize stack with first cell. The first cell is random. Then, while stack not empty:

currentCell = stack.top

Check all neighbors (up, down, left, right), those not visited.

If there are unvisited neighbors:

Pick one randomly.

Remove the walls between current and neighbor.

Mark neighbor as visited.

Push current to stack, set current to neighbor.

Else:

Pop from stack (backtrack).

So the stack is used for backtracking.

Drawing:

During generation, each step (when a new cell is added to stack) should draw the current cell and the path in the stack. Maybe draw the current cell in red, and stack path in another color. The walls are drawn by checking each cell's walls.

The counters: cellsCarved is the number of visited cells. Since total cells are 25*18=450, once that's reached, switch to solving.

For solving, the wanderer moves step by step. The algorithm could be the right-hand wall follower: always turn right (if possible), else go straight, else turn left, else backtrack. Wait, but how to track direction? Or, use the standard algorithm where the wanderer follows the right wall.

Alternatively, use the depth-first search for solving, but that's similar to how the maze was generated. But the user mentioned wall-follower, so better to pick that.

The solving steps:

Start at (0,0), target (24,17). Wanderer has a direction and current position. Each step:

Check adjacent cells based on the current direction. For example, using the right-hand rule: the wanderer tries to turn right, then straight, then left, then backtrack.

But to implement this, perhaps track the current direction and check the walls in that direction.

Alternatively, here's a step-by-step approach for right-hand wall follower:

At each step, the wanderer looks to turn right (ahead, then right, then left, then back). The exact direction steps need to be defined.

Alternatively, the algorithm could be:

While not at exit:

1. Check if the cell to the right (relative to direction) is open (no wall there) and unvisited.
   - If yes, turn right and move forward.
2. Else check forward direction.
   - If open and unvisited, move forward.
3. Else check left direction.
   - If open and unvisited, turn left and move forward.
4. Else, backtrack (reverse direction and move back, but need a stack for that).

Hmm, this becomes similar to the generating algorithm. Alternatively, using a stack to track path and backtrack when stuck.

Wait, perhaps for simplicity, the solving can use a stack-based approach, keeping track of the path taken. When a dead end is reached, backtrack.

Alternatively, since the maze is perfect (no cycles), the wall follower should find the path.

Implementation steps for solving:

Initialize wanderer at (0,0), direction (e.g., right). Each step:

Check directions in order (based on the rule, like right-hand). Let's say, the wanderer tries to turn right first. So, for each step, the wanderer looks in the direction of the right wall. For example, if facing east, check north wall (right side). Wait, maybe better to use a direction vector and check walls.

Alternatively, let's represent the current direction as a vector (dx, dy). The order of checking directions for turning right would be:

current direction is (dx, dy). The right turn direction would be ( -dy, dx ). For example:

If moving east (dx=1, dy=0), right turn is north (dx=0, dy=-1)?

Wait, directions:

Moving east: direction (1,0). Right turn (clockwise) would be north? Wait, no:

If facing east (right), turning right would face south (down). Hmm, perhaps better to precompute the directions.

Alternatively, represent direction as 0: East, 1: South, 2: West, 3: North. Then turning right would be (current +1) mod 4.

But maybe this is getting too complicated. Alternatively, track the current direction as:

north, east, south, west, each direction has a direction vector and a corresponding wall to check.

The right-hand rule says that the wanderer keeps their right hand on the wall. So, they turn right as much as possible.

The algorithm is:

1. Move forward if possible (in current direction), that is, if there's no wall in front and the next cell is unvisited.

Wait, but in a maze, the walls are between cells. So to move in direction (dx, dy), check if the current cell's adjacent wall allows movement.

Alternatively, when facing direction 'dir', the next cell is current.x + dx[dir], current.y + dy[dir].

The wall for that direction would be:

- If direction is east (dx=1), then the current cell's east wall must be missing, and the next cell's west wall must also be missing (since walls are shared). Wait, but in the grid structure, each cell has its own walls. So perhaps, to move east, we can check if the current cell's east wall is down (i.e., the neighbor to the east has their west wall also down).

Hmm, this might complicate things. Alternatively, when moving to a neighbor cell, we can check if the current cell's wall in that direction is removed.

Wait, in the grid structure, each cell's walls are stored. So to move east, check if the current cell's east wall is not present.

Thus, for the wanderer's direction:

They choose to move in an order (prefer right turn) and check if that direction's wall is open and the cell hasn't been visited yet.

Alternatively, here's a standard right-hand algorithm implementation steps:

The wanderer moves step by step, always moving in a direction that turns right when possible.

The exact steps can be found in pseudocode, but need to map it to code.

Perhaps the following approach:

At each step, the wanderer checks the cell to the right (relative to current direction). If there's a path there (no wall) and it hasn't been visited, move there and change direction to that right direction.

Else check forward direction: if path and unvisited, move forward, direction stays same.

Else check left direction (turn left): path and unvisited? Then move and change direction.

Else, backtrack (reverse direction, but need to have a stack of moves to know where to backtrack).

Hmm, this is getting too involved. Maybe implement the wall follower as follows:

The wanderer always tries to turn right, then go straight, then left, then reverse.

But to do this, need to determine the directions in order.

Let me think of the directions as an array. For each current direction, the order of preference is right, straight, left, back.

Wait, perhaps a better approach:

The wanderer's current direction is, say, east (right). The right-hand rule says that they keep their right hand on the wall. So, when moving, they first check the direction to the right (north?), then straight, then left (south?), then back.

Alternatively, using the standard "right-hand rule" algorithm from Wikipedia:

1. If there is no wall to the right, turn right (clockwise) and proceed straight.
2. Else if there is a wall to the right and in front, turn left (counter-clockwise).
3. Else proceed straight.

But to implement this, need to check the walls in the current direction's right direction.

Alternatively, let's use code for the right hand wall follower:

function move() {
  // Determine the directions in order: right, forward, left, back
  // For the current direction, the order of directions to try is right turn, then forward, etc.

  // Directions represented as indices:
  // 0: East, 1: South, 2: West, 3: North
  var dirs = [[1, 0], [0, 1], [-1, 0], [0, -1]];
  var dirNames = ['East', 'South', 'West', 'North'];
  
  var currentDir = wanderer.direction;
  var nextDir = currentDir;
  // Check right direction first
  var rightDir = (currentDir + 1) % 4;
  // Check if can turn right
  var dx = dirs[rightDir][0], dy = dirs[rightDir][1];
  var nx = wanderer.x + dx;
  var ny = wanderer.y + dy;
  // Check if this cell is within grid and path is available (no wall in that direction)
  if (nx >=0 && ny >=0 && nx < cols && ny < rows) {
    var currentCell = grid[ny][nx]; // assuming rows are y, columns x
    // Wait, need to check the wall between current cell and the direction.
    // Maybe the current cell's wall in the direction's direction.
    var wall = getWallForDirection(rightDir);
    // Not sure. Maybe better to check the cell's walls.
    // Alternatively, check if the current cell's wall in that direction is open.
    // Suppose the direction's wall is stored in the cell's walls array.
    // For example, if moving to the right direction (east), then check east wall.
    // Maybe the current cell's walls are stored as [top, right, bottom, left] or similar.
    // Let's assume each cell has walls as an array [top, right, bottom, left].

    // For direction rightDir (e.g., East direction index 0):
    // The wall to check is the current cell's right wall (if moving east), or the neighbor's left wall?
    // This is getting complicated. Maybe better to precompute for each possible direction.
    // Alternatively, when moving in the direction dx, dy, check that the current cell's wall in that direction is removed.

    // Let's say that to move in direction dx, dy, the current cell must have that direction's wall down.
    // For example, direction East (dx=1, dy=0), the current cell's east wall must be false (down).
    
    var cell = grid[ny][nx]; // Wait, actually the current cell is (wanderer.x, wanderer.y), and the next cell is (nx, ny).
    // The current cell's east wall is cell.east (or whatever representation).
    // The direction from current cell to (nx, ny) is dx, dy. So, the current cell's wall in that direction must be down.

    // This requires that the current cell's wall in that direction is false (removed).
    // For example, moving east: cell.east == false?
    // Also, the next cell's west wall must be down as well, but since walls are shared, maybe we don't need to check.

    // Anyway, assuming that the walls are represented such that if current cell's east wall is down, then the next cell to the east is accessible.

    // So if current cell has wall in the desired direction (dx, dy) as removed (false), then can move.
    
    // So in this case, to move in direction rightDir (east in example), if cell's east wall is down:
    // but since cell is the next cell? Wait, no. The current cell's east wall is between current and next cell.

    // This is getting too tangled. Maybe a better approach is to represent each cell as having walls for top, right, bottom, left, and when moving to an adjacent cell, check if the current cell's wall in that direction is down (false).

    // So, for the current position, to move east (dx=1, dy=0), check if current cell's east wall is down (no wall).
    // Then, the next cell is (x+1, y). That cell's west wall would also be down, but since we have a grid, when we carved the maze, the walls are removed symmetrically.

    // So, to ensure, whenever you move east, the current cell's east wall is already removed.

    // So, for the right-hand rule, the wanderer can check the current cell's right wall (the direction they want to turn right) to see if it's open.

    // Maybe this is too time-consuming, but perhaps I can proceed with code.

    // Suppose for the current direction, we can iterate through possible directions in the order of right, forward, left, back.

    // Let's try to code this step by step.

    // First, current direction is dir (index 0-3). The directions array is as before.

    // The current position is (x,y). We need to try moving in the right direction first.

    // The right direction is (currentDir +1) %4. Let's get dx and dy for that direction.
    var rightDir = (currentDir +1) %4;
    var dx = dirs[rightDir][0], dy = dirs[rightDir][1];
    var nx = wanderer.x + dx;
    var ny = wanderer.y + dy;
    
    // Check if cell is within bounds.
    if (nx >=0 && ny >=0 && nx < cols && ny < rows) {
        // Check if the current cell's wall in that direction is down (i.e., can move there)
        var wall = getWallInDirection(dirs[rightDir]);
        if (!wall && !grid[ny][nx].visited) {
            // Can move there.
            // Update direction to rightDir, move to nx, ny.
            wanderer.direction = rightDir;
            wanderer.x = nx;
            wanderer.y = ny;
            return; // done moving this step.
        }
    }
    // If not, try forward direction.
    // Same with forward direction, which is the current direction.
    dx = dirs[currentDir][0], dy = dirs[currentDir][1];
    nx = wanderer.x + dx;
    ny = wanderer.y + dy;
    // check if can move forward.
    if (nx >=0 && ny < rows) {
        // Check current cell's wall in current direction is down.
        // and next cell not visited.
        // etc.
    }
    // etc. for other directions.

    // This is quite involved. Perhaps I should look for a different approach or use a different algorithm.

    // Alternatively, let's assume that the maze is generated with passages between cells, and when moving, the wanderer can move to any adjacent cell where the wall is down and the cell hasn't been visited yet, choosing the right direction first.

    // To implement the right-hand rule, the order of preference is to turn right (clockwise), then go straight, then left, then back.

    // Thus, for each step:

    // Create an array of direction indices in the order of right, forward, left, back.

    var directionsToTry = [];
    var currentDir = wanderer.direction;
    directionsToTry.push( (currentDir +1)%4 ); // right
    directionsToTry.push( currentDir ); // forward
    directionsToTry.push( (currentDir -1 +4)%4 ); // left
    directionsToTry.push( (currentDir +2)%4 ); // back (opposite direction)
    
    // Iterate through each direction in order:
    for (var i=0; i <4; i++) {
        var dir = directionsToTry[i];
        var dx = dirs[dir][0], dy = dirs[dir][1];
        var nx = wanderer.x + dx;
        var ny = wanderer.y + dy;
        if (nx >=0 && ny >=0 && nx < cols && ny < rows) {
            var wall = getWallInDirection(dir);
            if (!wall) { // path is clear
                if (grid[ny][nx].visited) continue; // already been here
                // can move here
                wanderer.direction = dir;
                wanderer.x = nx;
                wanderer.y = ny;
                // mark as visited?
                grid[ny][nx].visited = true;
                return;
            }
        }
    }

    // If no direction found, need to backtrack. But how?

    // For backtracking, have a stack of previous positions.

    // This suggests that we need to track the path taken and possibly have an undo option, but it complicates things.

    // This is getting too complicated for this exercise. Maybe I can proceed by simplifying the algorithm.

    // For the purposes of this problem, since the user asked to create a maze and animate a solution (using a simple walk), perhaps using a simple depth-first search or backtracking approach would be better, but the user asked for the right-hand rule.

    // Alternatively, I'll proceed with the code structure, even if some parts are placeholders.

Now, stepping back, the overall structure of the code will be:

- Set up the grid with walls (all walls initially present except the start and end? Or randomly?)

Wait, actually the maze creation is part of the problem? The user just said "Create a maze and solve it with a right-hand rule solution using JavaScript." So I need to generate a maze and then solve it using right-hand rule.

Therefore, first, I need to implement a maze generation algorithm (like recursive backtracking, Prim's algorithm, etc.), then implement the right-hand rule solver.

But to keep it manageable, perhaps use a simple maze generation, like recursive backtracking, which also allows the solver to find a path easily.

Then, the animation would show the maze and the solver's path.

However, since the user asked to present the code here, perhaps in a compact form.

But given the complexity, maybe provide a code outline with comments.

Alternatively, here's an outline of the steps:

1. Initialize the grid with walls (all cells have all walls).
2. Generate the maze using a recursive backtracking algorithm, leaving a path from start to end.
3. Implement the right-hand rule solver starting at the start point and moving towards the end.
4. Animate the solver's movement step by step.

However, considering the space and time constraints, I'll outline the code with comments, focusing on the key parts.

First, the maze grid:

Each cell can be represented as an object with walls (top, right, bottom, left) and visited status.

But for simplicity, let's use a 2D array of cells:

var maze = new Array(rows);
for (var y=0; y<rows; y++) {
    maze[y] = new Array(cols);
    for (var x=0; x<cols; x++) {
        maze[y][x] = { 
            walls: { top: true, right: true, bottom: true, left: true },
            visited: false
        };
    }
}

Then, generate maze using recursive backtracking:

function generateMaze(x, y) {
    maze[y][x].visited = true;
    // Shuffle the directions
    var directions = [[1,0,'right'], [-1,0,'left'], [0,1,'bottom'], [0,-1,'top']];
    directions.sort(() => 0.5 - Math.random());
    for (var i=0; i<directions.length; i++) {
        var dx = directions[i][0];
        var dy = directions[i][1];
        var dir = directions[i][2];
        var nx = x + dx;
        var ny = y + dy;
        if (nx >=0 && ny >=0 && nx < cols && ny < rows) {
            if (!maze[ny][nx].visited) {
                // Remove the wall between current and next cell
                maze[y][x].walls[dir] = false;
                if (dir === 'right') {
                    maze[ny][nx].walls.left = false;
                } else if (dir === 'left') {
                    maze[ny][nx].walls.right = false;
                }
                // else similar for top and bottom.
                generateMaze(nx, ny);
            }
        }
    }
}

But this is a rough sketch. The exact wall removals depend on direction.

Once the maze is generated, the solver can start at the entrance (e.g., top-left cell) and traverse using right-hand rule.

The solver will need to keep track of its current position and direction, and move accordingly.

The animation would involve drawing the maze and updating the solver's position each step.

Given that this is a text-based answer, I'll provide a code skeleton with comments explaining each part.

But to actually provide a complete JavaScript code with animation, it would be quite lengthy, so here's a concise version with some simplifications:

```javascript
var canvas = document.getElementById('mazeCanvas');
var ctx = canvas.getContext('2d');
var cols = 20, rows = 20;
var cellSize = 20;
var maze = []; // 2D array representing the maze.

// Initialize maze with walls.
function initMaze() {
    maze = Array(rows);
    for (var y=0; y<rows; y++) {
        maze[y] = Array(cols);
        for (var x=0; x<cols; x++) {
            maze[y][x] = {
                walls: { top: true, right: true, bottom: true, left: true },
                visited: false
            };
        }
    }
}

// Maze generation using recursive backtracking.
function generateMaze(x, y) {
    maze[y][x].visited = true;
    var directions = [[1,0,'right'], [-1,0,'left'], [0,1,'bottom'], [0,-1,'top']];
    directions.sort(() => 0.5 - Math.random());
    for (var i=0; i<directions.length; i++) {
        var dx = directions[i][0], dy = directions[i][1];
        var dir = directions[i][2];
        var nx = x + dx;
        var ny = y + dy;
        if (nx >=0 && ny >=0 && nx < cols && ny < rows) {
            if (!maze[ny][nx].visited) {
                // Remove wall between current and next cell
                maze[y][x].walls[dir] = false;
                if (dir === 'right') {
                    maze[ny][nx].walls.left = false;
                } else if (dir === 'left') {
                    maze[ny][nx].walls.right = false;
                } else if (dir === 'top') {
                    maze[ny][nx].walls.bottom = false;
                } else if (dir === 'bottom') {
                    maze[ny][nx].walls.top = false;
                }
                generateMaze(nx, ny);
            }
        }
    }
}

// Start solver at (0,0), end at (cols-1, rows-1).
var solver = { x:0, y:0, direction: 'right' };
var directions = ['right', 'down', 'left', 'up']; // order of directions for right-hand rule.

function drawMaze() {
    ctx.clearRect(0,0,canvas.width, canvas.height);
    for (var y=0; y<rows; y++) {
        for (var x=0; x<cols; x++) {
            var cell = maze[y][x];
            ctx.strokeStyle = '#000';
            ctx.lineWidth = 2;
            // draw walls
            if (cell.walls.top) {
                ctx.strokeRect(x*cellSize, y*cellSize, cellSize, 1);
            }
            if (cell.walls.right) {
                ctx.strokeRect((x+1)*cellSize -1, y*cellSize, 1, cellSize);
            }
            if (cell.walls.bottom) {
                ctx.strokeRect(x*cellSize, (y+1)*cellSize -1, cellSize, 1);
            }
            if (cell.walls.left) {
                ctx.strokeRect(x*cellSize, y*cellSize, 1, cellSize);
            }
        }
    }
    // draw solver
    ctx.fillStyle = 'red';
    ctx.fillRect(solver.x*cellSize+4, solver.y*cellSize+4, cellSize-8, cellSize-8);
}

function solveMaze() {
    // Implement right-hand rule here.
    // Check the wall on the right, move forward if possible.
    // If not, turn right, etc.
    // This is a simplified placeholder.
    // For example:
    var currentCell = maze[solver.y][solver.x];
    var dir = solver.direction;
    var checkWall = function(dx, dy) {
        // Determine if the wall in direction (dx, dy) exists
    };
    // Determine next direction based on right-hand rule.
    // This needs to be more robust.
    // For now, just move in the current direction if possible.
    // Need to implement actual logic here.
}

initMaze();
generateMaze(0,0);
setInterval(drawMaze, 100);
```

However, this code is incomplete and lacks the actual solver logic. The solver function needs to track the current position and direction, check the walls on the right, and move accordingly.

To properly implement the right-hand rule:

1. The solver always extends the right hand and moves forward if the wall is absent.
2. If the wall is present, turn clockwise until a path is found.

This requires checking the adjacent cell's walls in the direction of the right hand.

Given time constraints, a simplified version might be:

At each step:

- Check if there's a wall to the right (relative to current direction).
- If no wall, turn right and move forward.
- If wall exists, move forward if possible.
- If neither, turn left (or back).

But this requires precise handling of directions and cell coordinates.

Given the complexity, here's a more detailed step-by-step plan for the solver function:

First, define directions as an array with their coordinates and order for rotation.

var directions = [
    {x:1, y:0, name:'right'},  // East
    {x:0, y:1, name:'down'},  // South
    {x:-1, y:0, name:'left'}, // West
    {x:0, y:-1, name:'up'}    // North
];

The solver has a current direction index (0 for right, etc.).

function solveStep() {
    var currentDirIndex = solver.directionIndex;
    var currentDir = directions[currentDirIndex];
    // Check right wall (next direction)
    var rightDirIndex = (currentDirIndex +1) %4;
    var rightDir = directions[rightDirIndex];
    var rightX = solver.x + rightDir.x;
    var rightY = solver.y + rightDir.y;
    // Check if the wall to the right is present.
    // The wall in the cell's direction.
    var currentCell = maze[solver.y][solver.x];
    var wallPresent = true;
    if (rightDir.name === 'right') {
        wallPresent = currentCell.walls.right;
    } else if (rightDir.name === 'down') {
        wallPresent = currentCell.walls.bottom;
    } else if (rightDir.name === 'left') {
        wallPresent = currentCell.walls.left;
    } else if (rightDir.name === 'up') {
        wallPresent = currentCell.walls.top;
    }
    if (!wallPresent) {
        // Turn right and move
        solver.directionIndex = rightDirIndex;
        solver.x += rightDir.x;
        solver.y += rightDir.y;
    } else {
        // Check current direction
        var currentX = solver.x + currentDir.x;
        var currentY = solver.y + currentDir.y;
        var currentWall = ...; // check wall in current direction
        if (!currentWall) {
            solver.x += currentDir.x;
            solver.y += currentDir.y;
        } else {
            // Turn left (or back)
            // Continue until path found
            // For simplicity, turn left
            solver.directionIndex = (currentDirIndex -1 +4)%4;
        }
    }
    // Check if at exit (cols-1, rows-1)
    if (solver.x === cols-1 && solver.y === rows-1) {
        clearInterval(interval);
    }
}

This is a rough sketch. The actual wall checking needs to reference the maze cell's walls correctly.

Given the time, perhaps the final code should be as follows, combining all parts with proper details:

Wait, but due to the complexity and length, I'll provide a full code example here, though it may be lengthy.
deepseek-r1:32bERRSTATFORMAT
Show code
```html
<!DOCTYPE html><html><body style="display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:#333"><canvas id=c></canvas><script>
const c=document.getElementById('c'),ctx=c.getContext('2d');
let cw=750,ch=480,cols=25,rows=18,cellS=cw/cols,grid=[],stack=[],current=null,totalCells=cols*rows,count=0,solving=false,wanderer=null,target=null,solvePath=[],steps=0;
c.width=cw;c.height=ch;

function Cell(i,j){
this.i=i;this.j=j;
this.walls=[1,1,1,1]; // top,right,bottom,left
this.visited=false;
return this;
}

Cell.prototype.getIndex=(i,j)=>i + j*cols;

Cell.prototype.show=(x,y)=>{
if(this.visited)ctx.fillStyle='#202020';
else ctx.fillStyle='#333';
ctx.fillRect(x+1,y+1,cellS-2,cellS-2);
if(this.walls[0])ctx.fillRect(x,y,cellS,1);
if(this.walls[1])ctx.fillRect(x+cellS-1,y,1,cellS);
if(this.walls[2])ctx.fillRect(x+1,y+cellS-1,cellS-2,1);
if(this.walls[3])ctx.fillRect(x,y,1,cellS);
};

Cell.prototype.getNeighbors=()=>{
let neighbors=[];
let i=this.i,j=this.j;
if(i>0 && !grid[j*cols + (i-1)].visited)neighbors.push(grid[j*cols + (i-1)]);
if(i<cols-1 && !grid[j*cols + (i+1)].visited)neighbors.push(grid[j*cols + (i+1)]);
if(j>0 && !grid[(j-1)*cols + i].visited)neighbors.push(grid[(j-1)*cols + i]);
if(j<rows-1 && !grid[(j+1)*cols + i].visited)neighbors.push(grid[(j+1)*cols + i]);
return neighbors;
};

function initGrid(){
grid=[];let idx=0;
for(let j=0;j<rows;j++){
for(let i=0;i<cols;i++){
grid[idx]=new Cell(i,j);
idx++;
}
}
current=grid[Math.floor(Math.random()*totalCells)];
stack=[];
count=0;solving=false;steps=0;solvePath=[];wanderer=null;
}

function drawMaze(){
ctx.fillStyle='#20';ctx.fillRect(0,0,cw,ch);
let x,y;
for(let j=0;j<rows;j++){
for(let i=0;i<cols;i++){
x=i*cellS;y=j*cellS;
grid[j*cols + i].show(x,y);
}
}
if(!solving){
current.show(current.i*cellS,current.j*cellS);
ctx.strokeStyle='#FF0';
let s=[];s.push(current);
while(s.length>0&&s[0]!=null){s.shift().drawPath();}
}
else{
wanderer.show(wanderer.i*cellS,wanderer.j*cellS,'#FFF');
target.show(target.i*cellS,target.j*cellS,'#F0F');
for(let cell of solvePath)ctx.fillRect(cell.i*cellS+cellS/4,cell.j*cellS+cellS/4,cellS/2,cellS/2);
}
ctx.fillStyle='#FFF';ctx.font='30px Arial';
if(!solving)ctx.fillText('Carving: '+count+'/'+totalCells,10,40);
else ctx.fillText('Steps: '+steps,10,40);
}

Cell.prototype.drawPath=()=>{
let x=this.i*cellS,y=this.j*cellS;
ctx.beginPath();
ctx.moveTo(x+cellS/2,y+cellS/2);
if(this.cameFrom!=null){
let dx=x - this.cameFrom.i*cellS,dj=y - this.cameFrom.j*cellS;
ctx.lineTo(this.cameFrom.i*cellS + cellS/2,this.cameFrom.j*cellS + cellS/2);
}
ctx.strokeStyle='#FF0';ctx.stroke();
};

function removeWalls(a,b){
let x=a.i - b.i; let y=a.j - b.j;
if(x===1){a.walls[3]=0;b.walls[1]=0;}
else if(x===-1){a.walls[1]=0;b.walls[3]=0;}
if(y===1){a.walls[0]=0;b.walls[2]=0;}
else if(y===-1){a.walls[2]=0;b.walls[0]=0;}
}

function carveMaze(){
if(count<totalCells){
grid.forEach(cell=>cell.visited=false);
current=randomWalk();
count++;
}
else{
solving=true;steps=0;
wanderer=grid[Math.floor(Math.random()*cols)+Math.floor(Math.random()*rows)*cols];
target=grid[(Math.floor(Math.random()*cols)) + (Math.floor(Math.random()*rows))*cols];
solveMaze();
}
}

function randomWalk(){
let next=null;
current.visited=true;
let neighbors=current.getNeighbors();
if(neighbors.length>0){
next=neighbors[Math.floor(Math.random()*neighbors.length)];
stack.push(current);
removeWalls(current,next);
current=next;
return current;
}
else{
while(stack.length>0){
let prev=stack.pop();
let next=null;
next=prev.getNeighbors().find(n=>n.visited===false);
if(next!=null)break;
}
if(prev==null&&next==null)return null;
removeWalls(prev,next);
current=next||prev;
return current;
}
}

function solveMaze(){
if(wanderer.i===target.i && wanderer.j===target.j){
solving=false;initGrid();carveMaze();
return;
}
let neighbors=wanderer.getNeighbors().filter(n=>!n.visited);
steps++;
let next=null;
if(neighbors.length>0){
next=neighbors[0];
next.cameFrom=wanderer;
solvePath.push(wanderer);
wanderer=next;
wanderer.visited=true;
}
else{
solvePath.pop();
if(solvePath.length>0)wanderer=solvePath[solvePath.length-1];
}
}

function animate(){
drawMaze();
if(!solving && current!=null){
carveMaze();
}
requestAnimationFrame(animate);
}

initGrid();animate();
</script></body></html>
```
No usable answer reached the harness (ERR). Counted as a did-not-finish.
Outside the Brain cluster — same task, same character budget, collected through their own tooling (response times not comparable)
Claude Opus 5frontier referenceOK
Show code
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Maze Carver &amp; Wanderer</title>
<style>
html,body{margin:0;height:100%;background:#080b12;color:#c8d8ef;font:13px/1.4 system-ui,Segoe UI,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px}
#hud{display:flex;gap:26px;text-transform:uppercase;letter-spacing:.12em;font-size:11px;color:#7288a8}
b{color:#7df9ff;font-variant-numeric:tabular-nums;font-weight:600}
canvas{border-radius:10px;box-shadow:0 0 50px #08a6ff26,0 0 0 1px #1c2942}
</style></head><body>
<div id="hud"><span>phase <b id="ph">carve</b></span><span>cells carved <b id="cc">0</b></span><span>solve steps <b id="ss">0</b></span></div>
<canvas id="cv" width="704" height="508"></canvas>
<script>
const C=25,R=18,S=28,x=document.getElementById('cv').getContext('2d');
const ph=document.getElementById('ph'),ec=document.getElementById('cc'),es=document.getElementById('ss');
const D=[[0,-1,0,2],[1,0,1,3],[0,1,2,0],[-1,0,3,1]];
let g,stack,cur,carved,mode,vis,path,steps,goal,timer;
function reset(){g=[];for(let i=0;i<C*R;i++)g.push({w:[1,1,1,1],v:0});
cur=(Math.random()*C*R)|0;g[cur].v=1;carved=1;stack=[cur];mode=0;steps=0;timer=0;vis=null;path=[];}
function nbrs(i,t){const c=i%C,r=(i/C)|0,o=[];
for(const[dx,dy,w,ow]of D){const nc=c+dx,nr=r+dy;if(nc<0||nr<0||nc>=C||nr>=R)continue;const j=nr*C+nc;if(t(j,w))o.push([j,w,ow]);}return o;}
function carveStep(){if(!stack.length){mode=1;vis=new Uint8Array(C*R);vis[0]=1;path=[0];cur=0;goal=C*R-1;return;}
cur=stack[stack.length-1];const o=nbrs(cur,j=>!g[j].v);
if(o.length){const[j,w,ow]=o[(Math.random()*o.length)|0];g[cur].w[w]=0;g[j].w[ow]=0;g[j].v=1;carved++;stack.push(j);}else stack.pop();}
function solveStep(){if(!path.length)return;cur=path[path.length-1];
if(cur===goal){mode=2;timer=80;return;}
const o=nbrs(cur,(j,w)=>!g[cur].w[w]&&!vis[j]);steps++;
if(o.length){const j=o[(Math.random()*o.length)|0][0];vis[j]=1;path.push(j);}else{vis[cur]=2;path.pop();}}
function line(a,col){if(a.length<2)return;x.strokeStyle=col;x.lineWidth=5;x.lineCap='round';x.lineJoin='round';x.beginPath();
a.forEach((i,k)=>{const px=(i%C)*S+S/2,py=((i/C)|0)*S+S/2;k?x.lineTo(px,py):x.moveTo(px,py)});x.stroke();}
function cell(i,col,p){x.fillStyle=col;x.fillRect((i%C)*S+p,((i/C)|0)*S+p,S-2*p,S-2*p);}
function draw(){x.setTransform(1,0,0,1,2,2);x.fillStyle='#0c1120';x.fillRect(-2,-2,704,508);
for(let i=0;i<C*R;i++){let f=null;
if(mode===0){if(g[i].v)f='#17253f';}else f=vis[i]===2?'#2b2138':vis[i]===1?'#0f5f70':'#131c2f';
if(f)cell(i,f,0);}
if(mode===0)line(stack,'#ff5fa2');else line(path,'#00e0ff');
x.strokeStyle='#42618f';x.lineWidth=2;x.beginPath();
for(let i=0;i<C*R;i++){const c=i%C,r=(i/C)|0,px=c*S,py=r*S,w=g[i].w;
if(w[0]){x.moveTo(px,py);x.lineTo(px+S,py);}
if(w[3]){x.moveTo(px,py);x.lineTo(px,py+S);}
if(c===C-1&&w[1]){x.moveTo(px+S,py);x.lineTo(px+S,py+S);}
if(r===R-1&&w[2]){x.moveTo(px,py+S);x.lineTo(px+S,py+S);}}
x.stroke();
if(mode){cell(0,'#39d98a',9);cell(goal,'#ff7b54',9);}
cell(cur,mode?'#ffe66d':'#fff2a8',6);}
function frame(){
if(mode===0){for(let k=0;k<5&&mode===0;k++)carveStep();}
else if(mode===1){for(let k=0;k<3&&mode===1;k++)solveStep();}
else if(--timer<=0)reset();
draw();ph.textContent=mode===0?'carving':mode===1?'solving':'complete';
ec.textContent=carved;es.textContent=steps;requestAnimationFrame(frame);}
reset();frame();
</script></body></html>
GPT-5.5 (Codex)frontier referenceOKMINIFIED
Show code
<!doctype html><html><head><meta charset=utf-8><title>Maze</title><style>html,body{margin:0;height:100%;background:#10151b;color:#e8eef2;font:16px system-ui;overflow:hidden}body{display:grid;place-items:center}#p{position:fixed;top:14px;left:14px;background:#121a22cc;border:1px solid #334150;padding:10px 12px;border-radius:8px;line-height:1.5}canvas{width:min(96vw,1100px);height:min(82vh,760px);image-rendering:auto}</style></head><body><div id=p><b id=m>Carving</b><br>cells <span id=c>0</span>/<span id=t></span><br>steps <span id=s>0</span></div><canvas id=a></canvas><script>
const W=25,H=18,N=W*H,cv=a,x=cv.getContext("2d"),C=c,S=s,M=m,T=t,dirs=[[0,-1,1,2],[1,0,2,1],[0,1,4,8],[-1,0,8,4]];let g,st,vis,seen,par,path,dead,cur,phase,done,steps,last=0,delay=28,hold=0;
function R(n){return Math.random()*n|0}
function cell(i){return g[i]}
function reset(){g=Array.from({length:N},(_,i)=>({i,w:15,v:0}));let q=R(N);cell(q).v=1;st=[q];vis=1;seen=new Set;par={};path=[];dead=new Set;cur=q;phase=0;done=0;steps=0;hold=0;T.textContent=N;C.textContent=vis;S.textContent=0;M.textContent="Carving"}
function nb(i,un){let X=i%W,Y=i/W|0,r=[];for(let d of dirs){let nx=X+d[0],ny=Y+d[1],j=ny*W+nx;if(nx>=0&&ny>=0&&nx<W&&ny<H&&(!un||!cell(j).v))r.push([j,d])}return r}
function carve(){let i=st[st.length-1],n=nb(i,1);cur=i;if(n.length){let [j,d]=n[R(n.length)];cell(i).w&=~d[2];cell(j).w&=~d[3];cell(j).v=1;st.push(j);vis++;C.textContent=vis}else st.pop();if(vis==N&&!st.length)solveStart()}
function solveStart(){phase=1;cur=0;seen=new Set([0]);par={0:-1};path=[0];dead=new Set;steps=0;M.textContent="Solving";S.textContent=0}
function solve(){if(cur==N-1){phase=2;hold=performance.now()+900;M.textContent="Solved";return}let n=nb(cur,0).map(v=>v[0]).filter(j=>!(cell(cur).w&wall(cur,j))&&!seen.has(j));if(n.length){let j=n[R(n.length)];par[j]=cur;cur=j;seen.add(j);path.push(j)}else{dead.add(cur);path.pop();cur=path[path.length-1]}steps++;S.textContent=steps}
function wall(a,b){let dx=b%W-a%W,dy=(b/W|0)-(a/W|0);return dx==1?2:dx==-1?8:dy==1?4:1}
function draw(){let w=cv.width=innerWidth*devicePixelRatio,h=cv.height=innerHeight*devicePixelRatio,cs=Math.min(w/(W+2),h/(H+2)),ox=(w-W*cs)/2,oy=(h-H*cs)/2;x.fillStyle="#10151b";x.fillRect(0,0,w,h);x.lineCap="round";for(let i=0;i<N;i++){let X=ox+i%W*cs,Y=oy+(i/W|0)*cs;x.fillStyle=cell(i).v?"#1b2834":"#151b22";x.fillRect(X+1,Y+1,cs-2,cs-2);if(seen.has(i)){x.fillStyle=dead.has(i)?"#604650":"#254b62";x.fillRect(X+3,Y+3,cs-6,cs-6)}}
x.strokeStyle="#c8d8e6";x.lineWidth=Math.max(1,cs*.08);x.beginPath();for(let i=0;i<N;i++){let z=cell(i),X=ox+i%W*cs,Y=oy+(i/W|0)*cs;if(z.w&1){x.moveTo(X,Y);x.lineTo(X+cs,Y)}if(z.w&2){x.moveTo(X+cs,Y);x.lineTo(X+cs,Y+cs)}if(z.w&4){x.moveTo(X+cs,Y+cs);x.lineTo(X,Y+cs)}if(z.w&8){x.moveTo(X,Y+cs);x.lineTo(X,Y)}}x.stroke();line(st,"#f4b350",.22);line(path,"#35d08f",.25);dot(cur,phase?"#fff06a":"#ff5d73")}
function line(a,col,lw){if(!a.length)return;x.strokeStyle=col;x.lineWidth=Math.max(2,cv.width/(W+2)*lw);x.beginPath();for(let k=0;k<a.length;k++){let i=a[k],X=(cv.width-(cv.width/(W+2))*W)/2+(i%W+.5)*cv.width/(W+2),Y=(cv.height-(cv.width/(W+2))*H)/2+((i/W|0)+.5)*cv.width/(W+2);k?x.lineTo(X,Y):x.moveTo(X,Y)}x.stroke()}
function dot(i,col){let cs=Math.min(cv.width/(W+2),cv.height/(H+2)),X=(cv.width-W*cs)/2+(i%W+.5)*cs,Y=(cv.height-H*cs)/2+((i/W|0)+.5)*cs;x.fillStyle=col;x.beginPath();x.arc(X,Y,cs*.28,0,7);x.fill()}
function loop(t){if(t-last>delay){last=t;if(phase==0)for(let k=0;k<5&&phase==0;k++)carve();else if(phase==1)solve();else if(t>hold)reset()}draw();requestAnimationFrame(loop)}
reset();requestAnimationFrame(loop)
</script></body></html>
Claude Sonnet 5frontier referenceOK
Show code
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Maze Gen &amp; Solve</title>
<style>
body{margin:0;background:#0d0d12;color:#eee;font-family:sans-serif;display:flex;flex-direction:column;align-items:center}
#info{padding:10px;font-size:15px}
#info span{font-weight:bold;color:#ffe066}
canvas{background:#000;border:1px solid #333}
</style></head><body>
<div id="info">Carved: <span id="c1">0</span>/<span id="tot"></span> &nbsp;&nbsp; Steps: <span id="c2">0</span> &nbsp;&nbsp; <span id="ph"></span></div>
<canvas id="cv"></canvas>
<script>
const cols=25,rows=18,cs=26;
const cv=document.getElementById('cv');
cv.width=cols*cs;cv.height=rows*cs;
const ctx=cv.getContext('2d');
const c1=document.getElementById('c1'),c2=document.getElementById('c2'),ph=document.getElementById('ph');
document.getElementById('tot').textContent=cols*rows;
let grid,stack,carved,phase,solveStack,steps,pauseTimer;
function newCell(x,y){return{x:x,y:y,N:true,E:true,S:true,W:true,v:false,sv:false};}
function idx(x,y){return y*cols+x;}
const DX=[0,1,0,-1],DY=[-1,0,1,0],DN=['N','E','S','W'],OP=['S','W','N','E'];
function initMaze(){
  grid=[];
  for(let y=0;y<rows;y++)for(let x=0;x<cols;x++)grid.push(newCell(x,y));
  const sx=Math.floor(Math.random()*cols),sy=Math.floor(Math.random()*rows);
  grid[idx(sx,sy)].v=true;
  stack=[grid[idx(sx,sy)]];
  carved=1;phase='gen';
  c1.textContent=carved;c2.textContent=0;ph.textContent='Generating maze...';
}
function neighborsUnvisited(cell){
  let res=[];
  for(let i=0;i<4;i++){
    const nx=cell.x+DX[i],ny=cell.y+DY[i];
    if(nx>=0&&nx<cols&&ny>=0&&ny<rows){
      const n=grid[idx(nx,ny)];
      if(!n.v)res.push({cell:n,dir:i});
    }
  }
  return res;
}
function genStep(){
  if(stack.length===0){startSolve();return;}
  const cur=stack[stack.length-1];
  const nb=neighborsUnvisited(cur);
  if(nb.length>0){
    const pick=nb[Math.floor(Math.random()*nb.length)];
    cur[DN[pick.dir]]=false;
    pick.cell[OP[pick.dir]]=false;
    pick.cell.v=true;
    stack.push(pick.cell);
    carved++;
    c1.textContent=carved;
  }else{
    stack.pop();
  }
  if(stack.length===0)startSolve();
}
function startSolve(){
  phase='solve';
  ph.textContent='Solving maze...';
  for(const cell of grid)cell.sv=false;
  const start=grid[idx(0,0)];
  start.sv=true;
  solveStack=[start];
  steps=0;
  c2.textContent=0;
}
function canMove(cell,dir){return!cell[DN[dir]];}
function solveStep(){
  const target=grid[idx(cols-1,rows-1)];
  const cur=solveStack[solveStack.length-1];
  if(cur===target){
    phase='done';
    ph.textContent='Solved! Restarting...';
    pauseTimer=70;
    return;
  }
  let moved=false;
  for(let i=0;i<4;i++){
    if(canMove(cur,i)){
      const nx=cur.x+DX[i],ny=cur.y+DY[i];
      const n=grid[idx(nx,ny)];
      if(!n.sv){
        n.sv=true;
        solveStack.push(n);
        steps++;moved=true;
        break;
      }
    }
  }
  if(!moved){solveStack.pop();steps++;}
  c2.textContent=steps;
}
function draw(){
  ctx.fillStyle='#000';
  ctx.fillRect(0,0,cv.width,cv.height);
  if(phase==='gen'){
    for(const cell of grid)if(cell.v){ctx.fillStyle='#152535';ctx.fillRect(cell.x*cs,cell.y*cs,cs,cs);}
    for(const cell of stack){ctx.fillStyle='#e08030';ctx.fillRect(cell.x*cs+2,cell.y*cs+2,cs-4,cs-4);}
    const cur=stack[stack.length-1];
    if(cur){ctx.fillStyle='#ffe066';ctx.fillRect(cur.x*cs+4,cur.y*cs+4,cs-8,cs-8);}
  }else{
    for(const cell of grid)if(cell.sv){ctx.fillStyle='#2c2c2c';ctx.fillRect(cell.x*cs,cell.y*cs,cs,cs);}
    for(const cell of solveStack){ctx.fillStyle='#40c060';ctx.fillRect(cell.x*cs+3,cell.y*cs+3,cs-6,cs-6);}
    const cur=solveStack[solveStack.length-1];
    if(cur){ctx.fillStyle='#ff5050';ctx.fillRect(cur.x*cs+5,cur.y*cs+5,cs-10,cs-10);}
    ctx.fillStyle='#5050ff';ctx.fillRect(8,8,cs-16,cs-16);
    ctx.fillStyle='#ffaa00';ctx.fillRect((cols-1)*cs+8,(rows-1)*cs+8,cs-16,cs-16);
  }
  ctx.strokeStyle='#999';
  ctx.lineWidth=2;
  ctx.beginPath();
  for(const cell of grid){
    const x=cell.x*cs,y=cell.y*cs;
    if(cell.N){ctx.moveTo(x,y);ctx.lineTo(x+cs,y);}
    if(cell.W){ctx.moveTo(x,y);ctx.lineTo(x,y+cs);}
    if(cell.x===cols-1&&cell.E){ctx.moveTo(x+cs,y);ctx.lineTo(x+cs,y+cs);}
    if(cell.y===rows-1&&cell.S){ctx.moveTo(x,y+cs);ctx.lineTo(x+cs,y+cs);}
  }
  ctx.stroke();
}
function loop(){
  if(phase==='gen'){
    for(let i=0;i<5;i++)if(phase==='gen')genStep();
  }else if(phase==='solve'){
    for(let i=0;i<3;i++)if(phase==='solve')solveStep();
  }else if(phase==='done'){
    pauseTimer--;
    if(pauseTimer<=0)initMaze();
  }
  draw();
  requestAnimationFrame(loop);
}
initMaze();
loop();
</script>
</body></html>
Claude Fable 5frontier referenceOK
Show code
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<title>Maze Carver &amp; Solver</title>
<style>
body{margin:0;min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#0b0e14;color:#cdd6f4;font:14px/1.4 monospace}
#h{margin-bottom:10px;letter-spacing:.5px}
b{color:#89dceb}
canvas{background:#11141c;box-shadow:0 0 24px #000;border-radius:4px}
</style>
<div id="h">carved: <b id="a">0</b>/450 &nbsp;|&nbsp; steps: <b id="b">0</b> &nbsp;|&nbsp; phase: <b id="p">carving</b></div>
<canvas id="c" width="800" height="576"></canvas>
<script>
var cv=document.getElementById('c'),g=cv.getContext('2d'),ea=document.getElementById('a'),eb=document.getElementById('b'),ep=document.getElementById('p');
var C=25,R=18,S=32,N=C*R,GOAL=N-1;
var D=[[0,-1,1,4],[1,0,2,8],[0,1,4,1],[-1,0,8,2]];
var w,vis,st,carved,phase,exp,dead,sst,steps,pause;
function idx(cx,cy){return cy*C+cx}
function reset(){
w=[];vis=[];exp=[];dead=[];
for(var i=0;i<N;i++){w.push(15);vis.push(0);exp.push(0);dead.push(0);}
var s=Math.floor(Math.random()*N);
vis[s]=1;st=[s];carved=1;phase=0;sst=[];steps=0;pause=0;
}
function nbors(i,test){
var cx=i%C,cy=(i-cx)/C,out=[];
for(var d=0;d<4;d++){
var nx=cx+D[d][0],ny=cy+D[d][1];
if(nx<0||ny<0||nx>=C||ny>=R)continue;
var j=idx(nx,ny);
if(test(j,d))out.push([j,d]);
}
return out;
}
function carveStep(){
if(!st.length){phase=1;sst=[0];exp[0]=1;return;}
var cur=st[st.length-1];
var opts=nbors(cur,function(j){return!vis[j]});
if(opts.length){
var pick=opts[Math.floor(Math.random()*opts.length)],j=pick[0],d=pick[1];
w[cur]&=~D[d][2];w[j]&=~D[d][3];
vis[j]=1;st.push(j);carved++;
}else st.pop();
}
function solveStep(){
if(!sst.length)return;
var cur=sst[sst.length-1];
if(cur===GOAL){phase=2;pause=90;return;}
var opts=nbors(cur,function(j,d){return!(w[cur]&D[d][2])&&!exp[j]});
if(opts.length){
var pick=opts[Math.floor(Math.random()*opts.length)];
exp[pick[0]]=1;sst.push(pick[0]);steps++;
}else{
dead[cur]=1;sst.pop();steps++;
}
}
function cell(i,col,pad){
var cx=i%C,cy=(i-cx)/C;
g.fillStyle=col;
g.fillRect(cx*S+pad,cy*S+pad,S-2*pad,S-2*pad);
}
function draw(){
g.fillStyle='#11141c';g.fillRect(0,0,800,576);
var i;
if(phase===0){
for(i=0;i<N;i++)if(vis[i])cell(i,'#1d2433',1);
for(i=0;i<st.length;i++)cell(st[i],'#3b6ea5',3);
if(st.length)cell(st[st.length-1],'#f9e2af',4);
}else{
for(i=0;i<N;i++)cell(i,'#1d2433',1);
for(i=0;i<N;i++)if(dead[i])cell(i,'#3a3f4b',5);
else if(exp[i])cell(i,'#4a5878',5);
for(i=0;i<sst.length;i++)cell(sst[i],phase===2?'#a6e3a1':'#e0af68',5);
cell(0,'#4fd6be',7);cell(GOAL,'#f38ba8',7);
if(sst.length&&phase===1)cell(sst[sst.length-1],'#ffffff',8);
}
g.strokeStyle='#7aa2f7';g.lineWidth=2;g.beginPath();
for(i=0;i<N;i++){
var cx=(i%C)*S,cy=Math.floor(i/C)*S,b=w[i];
if(b&1){g.moveTo(cx,cy);g.lineTo(cx+S,cy);}
if(b&2){g.moveTo(cx+S,cy);g.lineTo(cx+S,cy+S);}
if(b&4){g.moveTo(cx,cy+S);g.lineTo(cx+S,cy+S);}
if(b&8){g.moveTo(cx,cy);g.lineTo(cx,cy+S);}
}
g.stroke();
}
function loop(){
var k;
if(phase===0){for(k=0;k<3&&phase===0;k++)carveStep();}
else if(phase===1){for(k=0;k<2&&phase===1;k++)solveStep();}
else{pause--;if(pause<=0)reset();}
draw();
ea.textContent=carved;
eb.textContent=steps;
ep.textContent=phase===0?'carving':phase===1?'solving':'solved!';
requestAnimationFrame(loop);
}
reset();
requestAnimationFrame(loop);
</script>
</html>
Claude Haiku 4.5frontier referenceERRBLANKMINIFIED
Show code
<!DOCTYPE html><html><head><title>Maze</title><style>body{margin:0;background:#000}canvas{display:block}</style></head><body><canvas id="c"></canvas><script>const CX=25,RX=18,CS=32;let c=document.getElementById('c'),x=c.getContext('2d');c.width=800;c.height=576;let g=[],st=[],cur,cv=0,md='g',wnd,stp=0,fin=0;function ini(){g=[];for(let r=0;r<RX;r++){g[r]=[];for(let c=0;c<CX;c++)g[r][c]={v:0,w:[1,1,1,1]}}st=[];cv=0;let r=Math.floor(Math.random()*RX),c=Math.floor(Math.random()*CX);cur=g[r][c];cur.v=1;cv=1;md='g';stp=0}function gen(){let u=[];[[0,-1],[0,1],[-1,0],[1,0]].forEach((d,i)=>{let nr=cur.r+d[0],nc=cur.c+d[1];if(nr>=0&&nr<RX&&nc>=0&&nc<CX&&!g[nr][nc].v)u.push([g[nr][nc],i])});if(u.length){let[nt,d]=u[Math.floor(Math.random()*u.length)];cur.w[d]=0;nt.w[[1,0,3,2][d]]=0;nt.v=1;st.push(cur);cur=nt;cv++}else if(st.length)cur=st.pop();else{md='s';wnd={r:0,c:0}}}function slv(){let mv=0;[[0,1],[1,0],[0,-1],[-1,0]].forEach((d,i)=>{if(!mv&&!g[wnd.r][wnd.c].w[i]){let nr=wnd.r+d[0],nc=wnd.c+d[1];if(nr>=0&&nr<RX&&nc>=0&&nc<CX&&!g[nr][nc].f){g[wnd.r][wnd.c].e=1;wnd={r:nr,c:nc};mv=1;stp++;if(nr==RX-1&&nc==CX-1)fin=1}}}})}function dra(){x.fillStyle='#000';x.fillRect(0,0,800,576);x.fillStyle='#0f0';x.font='14px monospace';x.fillText(md=='g'?'Carved:'+cv:'Solved:'+stp,10,20);for(let r=0;r<RX;r++)for(let c=0;c<CX;c++){let e=g[r][c];e.r=r;e.c=c;let p=c*CS,q=r*CS;x.strokeStyle='#333';x.lineWidth=1;if(e.w[0])x.beginPath(),x.moveTo(p,q),x.lineTo(p+CS,q),x.stroke();if(e.w[1])x.beginPath(),x.moveTo(p+CS,q),x.lineTo(p+CS,q+CS),x.stroke();if(e.w[2])x.beginPath(),x.moveTo(p,q+CS),x.lineTo(p+CS,q+CS),x.stroke();if(e.w[3])x.beginPath(),x.moveTo(p,q),x.lineTo(p,q+CS),x.stroke();if(e.e){x.fillStyle='#444';x.fillRect(p,q,CS,CS)}}if(md=='g'&&cur){x.fillStyle='#ff0';x.fillRect(cur.c*CS,cur.r*CS,CS,CS);x.fillStyle='#f80';st.forEach(cel=>{x.fillRect(cel.c*CS+1,cel.r*CS+1,CS-2,CS-2)})}if(wnd){x.fillStyle='#f00';x.fillRect(wnd.c*CS,wnd.r*CS,CS,CS)}}(function a(){if(md=='g')gen();else slv();dra();if(fin)fin=0,setTimeout(ini,600);requestAnimationFrame(a)})();ini();</script></body></html>
Results at a glance— every model in this round with score, response time and status.

Who wrote what

ModelBlind scoreLatencyStatus
deepseek-r1:14b 34.8 sOK
llama3.1:8b 109.7 sOK
qwen3-coder:30b 56.8 sOK
qwen3.5:9b 84.9 sOK
mistral-small:24b 142.3 sOK
qwen3:8b 41.5 sOK
gemma4:26b harness
qwen3:14b 44.0 sOK
qwq:32b 250.7 sOK
deepseek-r1:32b 95.2 sOK
command-r:35b DNF