MODEL Allama3.1:8bDNF
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
Answers below are anonymized and shuffled. Read, judge, pick a favourite — then scroll down and reveal the models.
The reveal also holds a frontier reference on the same task (Claude Opus 5) — kept out of sight here so it cannot steer your judgement.
Create ONE self-contained HTML file (STRICT LIMIT: max 120 lines total) that animates a robot navigating a 30x20 grid to a goal on a <canvas> while the map changes underneath it. Plan a shortest path, then move the robot along it one cell at a time; every few steps drop a new wall somewhere ahead of the robot. When the current path is blocked, visibly replan from the robot's present position and draw the new path in a different colour. Show the number of replans and the steps taken. 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.
<!DOCTYPE html>
<html>
<head>
<title>Dynamic Pathfinding Robot</title>
<style>
body { background: #111; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
canvas { border: 2px solid #333; background: #000; }
#stats { color: #fff; position: absolute; top: 10px; left: 50%; transform: translateX(-50%); font-family: monospace; }
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<div id="stats"></div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const statsDiv = document.getElementById('stats');
const GRID_W = 30;
const GRID_H = 20;
const CELL_SIZE = 18;
canvas.width = GRID_W * CELL_SIZE;
canvas.height = GRID_H * CELL_SIZE;
let grid = [];
let robotPos = { x: 0, y: 0 };
let goalPos = { x: GRID_W - 1, y: GRID_H - 1 };
let currentPath = [];
let stepIndex = 0;
let stepsCount = 0;
let replanCount = 0;
let gameRunning = true;
let lastTime = 0;
function initializeGrid() {
grid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(0)); // 0=open, 1=wall
robotPos = { x: 2, y: GRID_H - 3 };
goalPos = { x: GRID_W - 2, y: 2 };
stepsCount = 0;
replanCount = 0;
currentPath = [];
stepIndex = 0;
for (let y = 0; y < GRID_H; y++) {
for (let x = 0; x < GRID_W; x++) {
if ((x % 5 === 0 && y > 0 && y < GRID_H - 1) || (y % 5 === 0 && x > 0 && x < GRID_W - 1)) {
grid[y][x] = Math.random() * 2;
} else {
grid[y][x] = 0;
}
}
}
robotPos.x = 2; robotPos.y = GRID_H - 3;
}
function findPath(start, end) {
let queue = [{ x: start.x, y: start.y, path: [] }];
let visited = new Set();
visited.add(`${start.x},${start.y}`);
while (queue.length > 0) {
let current = queue.shift();
if (current.x === end.x && current.y === end.y) return [...current.path, start, ...current.path];
let neighbors = [[0, 1], [0, -1], [1, 0], [-1, 0]];
for (const [dx, dy] of neighbors) {
let nx = current.x + dx;
let ny = current.y + dy;
if (nx >= 0 && nx < GRID_W && ny >= 0 && ny < GRID_H && !visited.has(`${nx},${ny}`) && grid[ny][nx] === 0) {
visited.add(`${nx},${ny}`);
let newPath = [...current.path, { x: current.x, y: current.y }];
queue.push({ x: nx, y: ny, path: newPath });
}
}
}
return null;
}
function dropWall() {
let placed = false;
while (!placed) {
let wx = Math.floor(Math.random() * (GRID_W - 2)) + 1;
let wy = Math.floor(Math.random() * (GRID_H - 2)) + 1;
if (grid[wy][wx] === 0 && !(wx === robotPos.x && wy === robotPos.y) && !(wx === goalPos.x && wy === goalPos.y)) {
// Ensure the wall doesn't block immediate passage or create a trivial loop
let neighbors = [[0, 1], [0, -1], [1, 0], [-1, 0]];
if (neighbors.some(([dx, dy]) => grid[wy + dy][wx + dx] === 0)) {
grid[wy][wx] = 1;
placed = true;
}
}
}
}
function updateState() {
if (!gameRunning) return;
// Wall generation control (drop a wall every 5 steps)
if (stepsCount > 0 && stepsCount % 5 === 0) {
dropWall();
}
let newPath = findPath(robotPos, goalPos);
if (!newPath || newPath.length < 2) {
// Path blocked or already at goal
if (stepsCount > 1 && currentPath.length === 0) {
gameRunning = false;
}
return;
}
let nextTarget = newPath[1];
// Check if the current path is invalid due to a dropped wall or blocked cell
if (currentPath.length > 0 &&
(nextTarget.x !== currentPath[stepIndex + 1].x || nextTarget.y !== currentPath[stepIndex + 1].y) ) {
// Replan required
replanCount++;
currentPath = newPath;
} else if (currentPath.length === 0) {
// Initial plan
currentPath = newPath;
}
if (stepIndex < currentPath.length - 1) {
let target = currentPath[Math.min(stepIndex + 1, currentPath.length - 1)];
robotPos.x = target.x;
robotPos.y = target.y;
stepIndex++;
} else if (currentPath.length > 0) {
// Reached goal or cannot move further
gameRunning = false;
}
stepsCount++;
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let y = 0; y < GRID_H; y++) {
for (let x = 0; x < GRID_W; x++) {
if (grid[y][x] === 1) {
ctx.fillStyle = '#444'; // Wall color
ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
} else {
ctx.fillStyle = '#000'; // Open space
ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
}
}
// Draw Path (Initial path color: Green)
if (currentPath.length > 1) {
ctx.strokeStyle = 'rgba(0, 255, 0, 0.8)';
ctx.lineWidth = CELL_SIZE * 0.6;
ctx.beginPath();
for (let i = 0; i < currentPath.length - 1; i++) {
const p = currentPath[i];
const n = currentPath[i+1];
ctx.moveTo(p.x * CELL_SIZE + CELL_SIZE/2, p.y * CELL_SIZE + CELL_SIZE/2);
ctx.lineTo(n.x * CELL_SIZE + CELL_SIZE/2, n.y * CELL_SIZE + CELL_SIZE/2);
}
ctx.stroke();
}
// Draw Replan Path (New path color: Yellow) - Only draw the segment ahead of the robot
if (currentPath.length > 1 && currentPath[stepIndex] !== undefined) {
ctx.strokeStyle = 'rgba(255, 255, 0, 0.8)';
ctx.lineWidth = CELL_SIZE * 0.6;
ctx.beginPath();
for (let i = stepIndex + 1; i < currentPath.length - 1 && i <= currentPath.length; i++) {
const p = currentPath[i];
const n = currentPath[i+1];
ctx.moveTo(p.x * CELL_SIZE + CELL_SIZE/2, p.y * CELL_SIZE + CELL_SIZE/2);
ctx.lineTo(n.x * CELL_SIZE + CELL_SIZE/2, n.y * CELL_SIZE + CELL_SIZE/2);
}
ctx.stroke();
}
// Draw Robot (Blue circle)
ctx.fillStyle = '#00ccff';
ctx.beginPath();
ctx.arc(robotPos.x * CELL_SIZE + CELL_SIZE / 2, robotPos.y * CELL_SIZE + CELL_SIZE / 2, CELL_SIZE * 0.4, 0, Math.PI * 2);
ctx.fill();
// Draw Goal (Red circle)
ctx.fillStyle = '#ff3333';
ctx.beginPath();
ctx.arc(goalPos.x * CELL_SIZE + CELL_SIZE / 2, goalPos.y * CELL_SIZE + CELL_SIZE / 2, CELL_SIZE * 0.4, 0, Math.PI * 2);
ctx.fill();
// Update Stats
statsDiv.innerHTML = `Steps: ${stepsCount} | Replans: ${replanCount} | Status: ${gameRunning ? 'Moving' : (currentPath.length > 0 ? 'Goal Reached!' : 'Blocked')}`;
}
function gameLoop(timestamp) {
if (!lastTime) lastTime = timestamp;
const delta = timestamp - lastTime;
draw();
updateState();
lastTime = timestamp;
if (gameRunning && stepsCount < 1000) { // Safety break to prevent infinite loop visualization
requestAnimationFrame(gameLoop);
} else if (!gameRunning && currentPath.length > 0) {
// Stop animation when goal is reached or blocked
} else if```html
<!DOCTYPE html>
<html><body style="margin:0;overflow:hidden">
<canvas id=c></canvas>
<div id=d></div>
<style>canvas{border:1px solid #333}#d{position:absolute;top:20;left:20;color:#fff}</style>
<script>
const c=document.getElementById('c'),d=document.getElementById('d');
const w=30,h=20,csize=c.width/(w*2),hSize=c.height/h;
let scale=Math.min(csize,hSize);
c.width=w*scale*2;c.height=h*scale*2;
const grid=[],start={x:0,y:0},goal={x:w-1,y:h-1};
for(let y=0;y<h;y++)grid[y]=new Array(w).fill(0);
function aStar(start,goal){
const open=new Set();closed=new Set();
open.add({x:start.x,y:start.y,f:0});
const cameFrom={};
while(open.size>0){
let current=null;let minF=Infinity;
for(let pos of open){if(pos.f<minF){current=pos,minF=pos.f}}
if(current.x==goal.x&¤t.y==goal.y)return [];
open.delete(current);
closed.add(current);
const neighbors=[{x:current.x+1,y:current.y},{x:current.x-1,y:current.y},
{x:current.x,y:current.y+1},{x:current.x,y:current.y-1}];
for(let n of neighbors){
if(n.x<0||n.x>=w||n.y<0||n.y>=h||grid[n.y][n.x]||closed.has(n))continue;
const newF=current.f+1+(Math.abs(n.x-goal.x)+Math.abs(n.y-goal.y));
const state={x:n.x,y:n.y,f:newF};
if(!open.has(state)){
cameFrom[JSON.stringify(state)]=current;
open.add(state);
}
}
}
return [];
}
let robot={x:0,y:0,path:[],step:0,replans:0},path=aStar(start,goal);
function draw(){c.getContext('2d').clearRect(0,0,c.width,c.height);
// Draw grid
for(let y=0;y<h;y++)for(let x=0;x<w;x++)if(grid[y][x])draw.rect(x*scale,y*scale,scale,scale,'red');
// Draw path
path.forEach((p,i)=>{if(i<robot.step)draw.line(p.x*scale,p.y*scale,(i+1).x*scale,(i+1).y*scale,'blue');});
// Current position
draw.rect(robot.x*scale,robot.y*scale,scale-2,scale-2,'green');
// Goal
draw.rect((w-1)*scale,(h-1)*scale,scale-2,scale-2,'yellow');
}
function move(){
if(robot.step<path.length){
robot.x=robot.path[robot.step].x;
robot.y=robot.path[robot.step].y;
robot.step++;
if(robot.step%30==0&&Math.random()<.1){let x=Math.floor(Math.random()*w),y=Math.floor(Math.random()*h);
if(!grid[y][x]&&(robot.x+Math.sign(x-robot.x)>0||robot.y+Math.sign(y-robot.y)>0)){
grid[y][x]=1;
path=aStar({x:robot.x,y:robot.y},goal);
robot.replans++;
}
}
}else{
c.width=c.width;location.reload();
}
}
function drawLine(x1,y1,x2,y2,color){
const ctx=c.getContext('2d');ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.strokeStyle=color;
ctx.lineWidth=2;ctx.stroke();
}
function rect(x,y,width,height,color){const ctx=c.getContext('2d');ctx.fillStyle=color;ctx.fillRect(x,y,width,height);}
let lastTime=null,interpolate=0;
function animate(timestamp){
if(!lastTime)lastTime=timestamp;
const deltaTime=timestamp-lastTime;
lastTime=timestamp;
interpolate+=deltaTime/1000*.5;
move();
draw();
d.textContent=`Steps: ${robot.step} | Replans: ${robot.replans}`;
requestAnimationFrame(animate);
}
animate(0);
</script>
</body></html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dynamic Grid Navigation</title>
<style>body { background: #111; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } canvas { border: 2px solid #333; }</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
let COLS = 30, ROWS = 20;
let CELL_SIZE = 20;
canvas.width = COLS * CELL_SIZE;
canvas.height = ROWS * CELL_SIZE;
let map = Array(ROWS).fill(0).map(() => Array(COLS).fill(false)); // false=open, true=wall
let robotPos = { x: 1, y: 1 };
let goalPos = { x: COLS - 2, y: ROWS - 2 };
let currentPath = [];
let stepCount = 0;
let replanCounter = 0;
let gameRunning = true;
function initializeMap() {
map = Array(ROWS).fill(0).map(() => Array(COLS).fill(false));
for (let i = 1; i < ROWS - 1; i++) {
for (let j = 1; j < COLS - 1; j++) {
if ((i + j) % 5 === 0 && Math.random() > 0.7) map[i][j] = true;
}
}
}
function heuristic(a, b) { return Math.abs(a.x - b.x) + Math.abs(a.y - b.y); }
function findPathAStar() {
const start = robotPos;
const goal = goalPos;
let openSet = [start];
let cameFrom = {};
let gScore = Array(ROWS).fill(0).map(() => Array(COLS).fill(Infinity));
gScore[start.y][start.x] = 0;
while (openSet.length > 0) {
openSet.sort((a, b) => heuristic(a, goal) - heuristic(b, goal));
let current = openSet.shift();
if (current.x === goal.x && current.y === goal.y) break;
for (const [dx, dy] of [[0, 1], [0, -1], [1, 0], [-1, 0]]) {
let neighbor = { x: current.x + dx, y: current.y + dy };
if (neighbor.x < 0 || neighbor.x >= COLS || neighbor.y < 0 || neighbor.y >= ROWS) continue;
if (map[neighbor.y][neighbor.x]) continue; // Cannot move through walls
let tentativeGScore = gScore[current.y][current.x] + 1;
if (tentativeGScore < gScore[neighbor.y][neighbor.x]) {
cameFrom[JSON.stringify(neighbor)] = current;
gScore[neighbor.y][neighbor.x] = tentativeGScore;
if (!openSet.some(n => n.x === neighbor.x && n.y === neighbor.y)) openSet.push(neighbor);
}
}
}
let path = [];
let currentKey = JSON.stringify({ x: goal.x, y: goal.y });
while (cameFrom[currentKey]) {
let current = { x: parseInt(currentKey.split(',')[0]), y: parseInt(currentKey.split(',')[1]) };
path.unshift(current);
let next = cameFrom[currentKey];
currentKey = JSON.stringify(next);
}
return path;
}
function draw() {
ctx.fillStyle = '#222';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw walls
for (let y = 0; y < ROWS; y++) {
for (let x = 0; x < COLS; x++) {
if (map[y][x]) {
ctx.fillStyle = '#666';
ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
}
}
// Draw path
ctx.strokeStyle = 'rgba(0, 150, 255, 0.8)';
ctx.lineWidth = CELL_SIZE / 3;
if (currentPath.length > 0) {
ctx.beginPath();
for (let i = 0; i < currentPath.length - 1; i++) {
const p1 = currentPath[i];
const p2 = currentPath[i+1];
if (i === 0) ctx.moveTo(p1.x * CELL_SIZE + CELL_SIZE / 2, p1.y * CELL_SIZE + CELL_SIZE / 2);
ctx.lineTo(p2.x * CELL_SIZE + CELL_SIZE / 2, p2.y * CELL_SIZE + CELL_SIZE / 2);
}
ctx.stroke();
}
// Draw robot
ctx.fillStyle = '#FFD700';
ctx.beginPath();
ctx.arc(robotPos.x * CELL_SIZE + CELL_SIZE / 2, robotPos.y * CELL_SIZE + CELL_SIZE / 2, CELL_SIZE / 3, 0, Math.PI * 2);
ctx.fill();
// Draw goal
ctx.fillStyle = '#4CAF50';
ctx.beginPath();
ctx.arc(goalPos.x * CELL_SIZE + CELL_SIZE / 2, goalPos.y * CELL_SIZE + CELL_SIZE / 2, CELL_SIZE / 3, 0, Math.PI * 2);
ctx.fill();
// Draw stats
ctx.fillStyle = 'white';
ctx.font = '14px Arial';
ctx.fillText(`Steps: ${stepCount}`, 10, 20);
ctx.fillText(`Replans: ${replanCounter}`, 10, 40);
}
function placeWall(x, y) {
if (x >= 1 && x <= COLS - 2 && y >= 1 && y <= ROWS - 2 && !map[y][x]) {
map[y][x] = true;
}
}
function dropNewWall() {
const randX = Math.floor(Math.random() * (COLS - 4)) + 1;
const randY = Math.floor(Math.random() * (ROWS - 4)) + 1;
placeWall(randX, randY);
}
function updateGame() {
if (!gameRunning) return;
// 1. Movement/Path Following
let nextStep = currentPath[0];
if (nextStep && nextStep.x === robotPos.x && nextStep.y === robotPos.y) {
// We reached the target of the path segment
currentPath.shift(); // Consume the step
robotPos = currentPath.length > 0 ? currentPath[0] : goalPos;
} else if (nextStep) {
// Move to the next step
robotPos = nextStep;
currentPath.shift();
} else if (robotPos.x === goalPos.x && robotPos.y === goalPos.y) {
gameRunning = false; // Reached goal
}
stepCount++;
// 2. Check for Blockage and Replanning
const nextTarget = currentPath[0];
let blocked = false;
if (nextTarget && map[nextTarget.y][nextTarget.x]) {
blocked = true;
} else if (!nextTarget) {
// Check theoretical next move toward goal if the path was completed
const requiredMove = { x: Math.sign(goalPos.x - robotPos.x), y: Math.sign(goalPos.y - robotPos.y) };
if (Math.abs(goalPos.x - robotPos.x) > 0 && map[robotPos.y][robotPos.x + requiredMove.x]) {
blocked = true; // Cannot move in the direction of goal due to new wall
} else if (Math.abs(goalPos.y - robotPos.y) > 0 && map[robotPos.y + requiredMove.y][robotPos.x]) {
blocked = true;
}
}
if (blocked || !nextTarget) {
replanCounter++;
currentPath = findPathAStar();
if (currentPath.length > 0) {
// Set the immediate next step for movement in the subsequent frame
} else {
gameRunning = false; // Truly stuck
}
}
// 3. Wall Generation (Every 15 steps)
if (stepCount % 15 === 0) {
dropNewWall();
}
draw();
}
function animate() {
updateGame();
requestAnimationFrame(animate);
}
// Setup and start
initializeMap();
currentPath = findPathAStar();
if (currentPath.length > 0) {
robotPos = currentPath[0]; // Start at the first path point
} else {
console.error("Failed to calculate initial path.");
}
animate();
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dynamic Pathfinding Robot</title>
<style>body { background: #222; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: monospace; color: white;} canvas { border: 1px solid #444; }</style>
</head>
<body>
<canvas id="gridCanvas" width="600" height="400"></canvas>
<script>
const canvas = document.getElementById('gridCanvas');
const ctx = canvas.getContext('2d');
const COLS = 30;
const ROWS = 20;
const CELL_SIZE = Math.min(canvas.width, canvas.height) / Math.max(COLS, ROWS);
let map = [];
let robotPos = { x: 1, y: 1 };
let goalPos = { x: COLS - 2, y: ROWS - 2 };
let currentPath = [];
let stepsTaken = 0;
let replanCount = 0;
let lastMoveTime = 0;
const MOVE_INTERVAL = 150; // ms
function initMap() {
map = Array(ROWS).fill(0).map(() => Array(COLS).fill(false));
for (let r = 0; r < ROWS; r++) {
for (let c = 0; c < COLS; c++) {
if ((r === 0 || r === ROWS - 1 || c === 0 || c === COLS - 1) && !(c === robotPos.x && r === robotPos.y)) {
map[r][c] = true; // Wall/Blocked initially
} else if (r === goalPos.y && c === goalPos.x) {
map[r][c] = false;
} else {
map[r][c] = false;
}
}
}
robotPos = { x: 1, y: 1 };
goalPos = { x: COLS - 2, y: ROWS - 2 };
}
function bfs(start, end) {
let queue = [{ pos: start, path: [start] }];
let visited = new Set();
visited.add(`${start.x},${start.y}`);
while (queue.length > 0) {
let { pos, path } = queue.shift();
if (pos.x === end.x && pos.y === end.y) return path;
[[0, 1], [0, -1], [1, 0], [-1, 0]].forEach(([dx, dy]) => {
let next = { x: pos.x + dx, y: pos.y + dy };
if (next.x >= 0 && next.x < COLS && next.y >= 0 && next.y < ROWS && !map[next.y][next.x] && !visited.has(`${next.x},${next.y}`)) {
let newPath = [...path, next];
visited.add(`${next.x},${next.y}`);
queue.push({ pos: next, path: newPath });
}
});
}
return null;
}
function generateWall(safePos) {
let x = safePos.x + Math.floor(Math.random() * 5) - 2;
let y = safePos.y + Math.floor(Math.random() * 5) - 2;
if (x < 0 || x >= COLS || y < 0 || y >= ROWS) return false;
return map[y][x] = true;
}
function planPath() {
currentPath = bfs(robotPos, goalPos);
if (currentPath) {
// The path includes the start point (which is where we are now). We only need steps *after* the current position.
currentPath = currentPath.slice(1);
} else {
currentPath = [];
}
}
function updateGame() {
const currentTime = Date.now();
if (currentTime - lastMoveTime < MOVE_INTERVAL) return;
lastMoveTime = currentTime;
if (!currentPath || currentPath.length === 0) {
planPath();
}
if (robotPos.x === goalPos.x && robotPos.y === goalPos.y) {
// Game finished, force replan to restart loop
initMap();
planPath();
stepsTaken = 0;
replanCount = 0;
} else if (currentPath.length > 0) {
let nextStep = currentPath[0];
// Check for blocked path BEFORE moving
if (map[nextStep.y][nextStep.x]) {
replanCount++;
planPath(); // Attempt to replan
return;
}
// Move robot
robotPos.x = nextStep.x;
robotPos.y = nextStep.y;
currentPath.shift();
stepsTaken++;
} else {
// Stuck or finished path
if (replanCount > 0) planPath();
}
// Dynamic Wall Generation: Block the immediate area ahead of the robot, but not the current path segment.
let nextTarget = currentPath[0] || goalPos;
if (Math.random() < 0.5 && stepsTaken > 5) {
generateWall(nextTarget);
}
}
function drawMap() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let y = 0; y < ROWS; y++) {
for (let x = 0; x < COLS; x++) {
let color = map[y][x] ? '#333' : '#1a1a1a'; // Wall or empty ground
ctx.fillStyle = color;
ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
}
}
// Draw Goal
ctx.fillStyle = '#4CAF50';
ctx.fillRect(goalPos.x * CELL_SIZE, goalPos.y * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
// Draw Path (Current plan)
if (currentPath.length > 0) {
for (let i = 0; i < currentPath.length; i++) {
const p = currentPath[i];
ctx.fillStyle = '#44bbff'; // Blue path color
ctx.fillRect(p.x * CELL_SIZE, p.y * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
}
}
// Draw Robot
ctx.fillStyle = '#FFD700';
ctx.beginPath();
ctx.arc(robotPos.x * CELL_SIZE + CELL_SIZE / 2, robotPos.y * CELL_SIZE + CELL_SIZE / 2, Math.min(CELL_SIZE, 8), 0, Math.PI * 2);
ctx.fill();
}
function drawStats() {
ctx.fillStyle = '#aaa';
ctx.font = '14px monospace';
let statsText = `STEPS: ${stepsTaken} | REPLANS: ${replanCount}`;
if (currentPath && currentPath[0]) {
statsText += ` | NEXT: (${currentPath[0].x}, ${currentPath[0].y})`;
} else if (robotPos.x === goalPos.x && robotPos.y === goalPos.y) {
statsText = "GOAL REACHED! Restarting...";
}
ctx.fillText(statsText, 10, 20);
}
function gameLoop() {
updateGame();
drawMap();
drawStats();
requestAnimationFrame(gameLoop);
}
// Initialization and Start
initMap();
planPath();
gameLoop();
</script>
</body>
</html>
```| Blind label | Model | Blind score | Latency | Status |
|---|---|---|---|---|
| MODEL A | llama3.1:8b | — | — | DNF |
| MODEL B | qwen3.5:9b | — | 73.6 s | OK |
| MODEL C | mistral-small:24b | — | — | DNF |
| MODEL D | qwen3:8b | — | — | DNF |
| MODEL E | gemma4:26b | — | — | DNF |
| MODEL F | deepseek-r1:14b | — | 75.5 s | OK |
| MODEL G | qwen3:14b | — | 59.9 s | OK |
| MODEL H | qwen3-coder:30b | — | 32.2 s | OK |
These models answered the identical prompt outside the blind field. They are deliberately not scored and not part of the blind comparison — they are there so you can see where a frontier model lands on the same task.
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Dynamic Replanning Robot</title>
<style>
:root{color-scheme:dark}
*{box-sizing:border-box}
body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:radial-gradient(120% 120% at 50% 0%,#141c34 0%,#070a14 70%);color:#e6ecff;font:14px/1.4 ui-sans-serif,system-ui,"Segoe UI",Roboto,sans-serif;padding:18px}
.wrap{width:min(760px,100%)}
h1{margin:0 0 10px;font-size:17px;letter-spacing:.02em;font-weight:650}
.hud{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px}
.p{background:#151d33;border:1px solid #263252;border-radius:8px;padding:6px 10px;font-variant-numeric:tabular-nums}
.p b{color:#8fa4d4;font-weight:500;margin-right:6px;font-size:12px;text-transform:uppercase;letter-spacing:.06em}
canvas{width:100%;height:auto;display:block;border:1px solid #263252;border-radius:10px;background:#0b1020}
.leg{margin-top:9px;color:#8fa4d4;font-size:12px}
</style></head>
<body><div class="wrap">
<h1>Robot replanning on a changing map</h1>
<div class="hud"><div class="p"><b>Steps</b><span id="s">0</span></div><div class="p"><b>Replans</b><span id="r">0</span></div><div class="p"><b>Walls</b><span id="w">0</span></div><div class="p"><b>Status</b><span id="t">planning</span></div></div>
<canvas id="c"></canvas>
<div class="leg">Breadth-first shortest path on a 30×20 grid. New walls appear ahead of the robot; a blocked route triggers an immediate replan from its current cell, drawn in a fresh colour.</div>
</div>
<script>
const W=30,H=20,CS=25,COL=["#38bdf8","#f472b6","#facc15","#4ade80","#c084fc","#fb923c","#22d3ee"];
const cv=document.getElementById("c");cv.width=W*CS;cv.height=H*CS;const ctx=cv.getContext("2d");
const el=i=>document.getElementById(i);
let g,path,pi,rob,goalI,steps,replans,nwalls,t,ci,pulse,done,status;
const ix=(x,y)=>y*W+x,X=i=>i%W,Y=i=>(i/W)|0,ri=n=>(Math.random()*n)|0;
function bfs(s,e){const pv=new Int32Array(W*H).fill(-1),q=[s];pv[s]=s;let h=0;
while(h<q.length){const c=q[h++];if(c===e){const p=[];let k=c;while(k!==pv[k]){p.push(k);k=pv[k]}p.push(k);return p.reverse()}
const cx=X(c),cy=Y(c);
for(const[dx,dy]of[[1,0],[0,1],[-1,0],[0,-1]]){const nx=cx+dx,ny=cy+dy;if(nx<0||ny<0||nx>=W||ny>=H)continue;const n=ix(nx,ny);if(g[n]||pv[n]>=0)continue;pv[n]=c;q.push(n)}}
return null}
function init(){for(;;){g=new Uint8Array(W*H);nwalls=0;
for(let i=0;i<W*H;i++)if(Math.random()<.13){g[i]=1;nwalls++}
const s=ix(1+ri(3),1+ri(H-2)),e=ix(W-2-ri(3),1+ri(H-2));if(s===e)continue;
g[s]=0;g[e]=0;const p=bfs(s,e);if(!p)continue;
rob=s;goalI=e;path=p;pi=0;steps=0;replans=0;t=0;ci=0;pulse=[];done=0;status="following path";return}}
function remainingBlocked(){for(let k=pi;k<path.length;k++)if(g[path[k]])return true;return false}
function dropWall(){const ahead=[];for(let k=pi+2;k<path.length-1;k++)ahead.push(path[k]);
let c=-1;
if(ahead.length&&Math.random()<.85)c=ahead[ri(Math.min(ahead.length,6))];
else{for(let a=0;a<40;a++){const q=ix(ri(W),ri(H));if(!g[q]&&q!==goalI&&q!==rob){c=q;break}}}
if(c<0||c===goalI||c===rob)return;g[c]=1;nwalls++;pulse.push({c,t:.7})}
function replan(){const p=bfs(rob,goalI);
if(!p){status="trapped - new map";done=1.1;return}
path=p;pi=0;replans++;ci=(ci+1)%COL.length;status="replanned";}
function stepDone(){pi++;steps++;rob=path[pi];
if(rob===goalI){status="goal reached";done=1.4;return}
if(steps%3===0)dropWall();
if(remainingBlocked())replan();else if(status==="replanned")status="following path"}
function cell(i,pad,col,rad){ctx.fillStyle=col;ctx.beginPath();ctx.roundRect(X(i)*CS+pad,Y(i)*CS+pad,CS-2*pad,CS-2*pad,rad);ctx.fill()}
function draw(now){ctx.fillStyle="#0b1020";ctx.fillRect(0,0,cv.width,cv.height);
ctx.strokeStyle="rgba(140,170,255,.07)";ctx.lineWidth=1;ctx.beginPath();
for(let x=0;x<=W;x++){ctx.moveTo(x*CS+.5,0);ctx.lineTo(x*CS+.5,H*CS)}
for(let y=0;y<=H;y++){ctx.moveTo(0,y*CS+.5);ctx.lineTo(W*CS,y*CS+.5)}ctx.stroke();
for(let i=0;i<W*H;i++)if(g[i])cell(i,1,"#2b3a5e",3);
const c=COL[ci];
for(let k=pi;k<path.length;k++)cell(path[k],CS*.36,c+"55",2);
for(const p of pulse){const a=p.t/.7;ctx.strokeStyle="rgba(255,90,90,"+a+")";ctx.lineWidth=2;ctx.strokeRect(X(p.c)*CS+1.5,Y(p.c)*CS+1.5,CS-3,CS-3)}
const gp=.5+.5*Math.sin(now/260);
ctx.strokeStyle="rgba(74,222,128,"+(.45+.5*gp)+")";ctx.lineWidth=2;
ctx.strokeRect(X(goalI)*CS+3.5,Y(goalI)*CS+3.5,CS-7,CS-7);
cell(goalI,CS*.34,"#4ade80",2);
let px=X(rob),py=Y(rob);
if(!done&&pi+1<path.length){const n=path[pi+1];px+=(X(n)-px)*t;py+=(Y(n)-py)*t}
const rx=px*CS+CS/2,ry=py*CS+CS/2;
ctx.fillStyle=c+"33";ctx.beginPath();ctx.arc(rx,ry,CS*.72,0,7);ctx.fill();
ctx.fillStyle=c;ctx.beginPath();ctx.arc(rx,ry,CS*.34,0,7);ctx.fill();
ctx.fillStyle="#0b1020";ctx.beginPath();ctx.arc(rx,ry,CS*.13,0,7);ctx.fill()}
let last=0;
function frame(ts){const dt=Math.min(.05,last?(ts-last)/1000:0);last=ts;
if(done>0){done-=dt;if(done<=0)init()}
else{t+=dt*8.5;let guard=0;while(t>=1&&!done&&guard++<4){t-=1;stepDone()}if(done)t=0}
for(const p of pulse)p.t-=dt;pulse=pulse.filter(p=>p.t>0);
el("s").textContent=steps;el("r").textContent=replans;el("w").textContent=nwalls;el("t").textContent=status;
draw(ts);requestAnimationFrame(frame)}
init();requestAnimationFrame(frame);
</script></body></html>