Models 44

North Mini Code (free)

by CohereReasoning1 console error
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
16.0 s
Cost
$0
Output tokens
3,612
Spent thinking
0 tokens
Speed
228.4 tok/s
Console errors
1
First token after
222 ms
First visible text after
222 ms
Prompt tokens
480
Code size
12.1 KB
Finish reason
stop
Served by
Cohere
Model id
cohere/north-mini-code:free
Reasoning sent
{"effort":"none"}
Max output
32,000 tokens
Generated
Nov 9, 2026

Console errors

Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.

Unexpected token 'var'

What it was asked

The prompt
Build a polished Snake game in a single HTML file using vanilla JavaScript and a <canvas>. Requirements: - A grid of at least 20×20 cells, centered on the page. - Arrow keys and WASD control the snake. Quick successive key presses must both be honored, but the snake can never reverse onto itself. - Eating food adds 10 points and grows the snake by one cell; new food never spawns on the snake. - Game over when the snake hits a wall or itself, with an overlay showing the score; Space or Enter restarts, P pauses. - Visual polish: smooth movement, a snake with a distinct head and eyes facing its direction, and a small particle burst when eating. - Display the current score and the best score of the session.
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 443 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Polished Snake Game</title>
<style>
  :root {
    --cell-size: clamp(12px, 2.5vw, 24px);
    --grid-gap: 1px;
    --snake-head-color: #2ecc71;
    --snake-body-color: #27ae60;
    --food-color: #e74c3c;
    --particle-color: #f1c40f;
    --bg-color: #1e272e;
    --text-color: #dfe6e9;
  }
  * { box-sizing: border-box; margin:0; padding:0; }
  body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: var(--bg-color);
    color: var(--text-color);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
  }
  .ui {
    position: absolute;
    top: 0; left: 0; right: 0;
    padding: 10px;
    display: flex;
    justify-content: space-between;
    font-size: 1.2rem;
    pointer-events: none;
    z-index: 10;
  }
  .score-panel { text-align: left; }
  .best-panel { text-align: right; }
  canvas {
    border: 2px solid #555;
    background: #2f3640;
    image-rendering: crisp-edges;
    display: block;
    margin: 20px auto;
  }
  .overlay {
    position: absolute;
    inset: 0;
    background: rgba(0,0,0,0.7);
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    z-index: 20;
    pointer-events: auto;
  }
  .overlay.active { display: flex; }
  .overlay h1 { font-size: 3rem; margin-bottom: .5rem; }
  .overlay p { font-size: 1.5rem; margin: .3rem 0; }
  .restart-btn {
    margin-top: 1rem;
    padding: .7rem 1.5rem;
    font-size: 1.2rem;
    background: #44bd32;
    border: none;
    border-radius: 8px;
    color: #fff;
    cursor: pointer;
    transition: background .2s;
  }
  .restart-btn:hover { background: #4cd137; }
  .pause-screen {
    position: absolute;
    inset: 0;
    background: rgba(0,0,0,0.5);
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    z-index: 15;
    pointer-events: none;
  }
  .pause-screen.active { display: flex; }
  .controls-hint {
    position: absolute;
    bottom: 20px;
    font-size: .9rem;
    opacity: .6;
    pointer-events: none;
  }
  /* Particle burst */
  #particles { position: absolute; inset: 0; pointer-events: none; }
</style>
</head>
<body>
<div class="ui">
  <div class="score-panel">Score: <span id="score">0</span></div>
  <div class="best-panel">Best: <span id="best">0</span></div>
</div>

<canvas id="gameCanvas" width="800" height="800"></canvas>
<div id="overlay" class="overlay">
  <h1>Game Over</h1>
  <p>Your score: <span id="finalScore">0</span></p>
  <button class="restart-btn" id="restartBtn">Press Space or Enter to Restart</button>
</div>
<div id="pauseScreen" class="pause-screen">Paused</div>
<div id="particles"></div>
<div class="controls-hint">Use Arrow Keys or WASD to move. Press P to pause.</div>

<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreDisplay = document.getElementById('score');
const bestDisplay = document.getElementById('best');
const overlay = document.getElementById('overlay');
const finalScoreDisplay = document.getElementById('finalScore');
const pauseScreen = document.getElementById('pauseScreen');
const particlesCanvas = document.getElementById('particles');
const particlesCtx = particlesCanvas.getContext('2d');

const GRID_SIZE = 40; // cells per side (min 20x20)
const CELL = canvas.width / GRID_SIZE; // will be recalculated after resize
let cell, gridGap;

let snake = [{x:12, y:12}];
let food = {x:0, y:0};
let direction = {x:1, y:0};
let nextDirection = {x:1, y:0};
let score = 0;
let best = parseInt(localStorage.getItem('snakeBest')||0,10);
let gameRunning = false;
let gameOver = false;
let paused = false;
let animationId = null;

const dirs = {
  ArrowUp:    {x:0, y:-1},
  ArrowDown:  {x:0, y:1},
  ArrowLeft:  {x:-1, y:0},
  ArrowRight: {x:1, y:0},
  w: {x:0, y:-1},
  s: {x:0, y:1},
  a: {x:-1, y:0},
  d: {x:1, y:0}
};

function resize() {
  const container = canvas.parentElement;
  const max = Math.min(window.innerWidth, window.innerHeight);
  const size = Math.min(max, 800);
  canvas.width = size;
  canvas.height = size;
  CELL = canvas.width / GRID_SIZE;
  gridGap = 1;
  // Keep particles canvas same resolution
  particlesCanvas.width = canvas.width;
  particlesCanvas.height = canvas.height;
}
window.addEventListener('resize', resize);
resize();

function getRandomCoord() {
  let x, y;
  while(true){
    x = Math.floor(Math.random() * GRID_SIZE);
    y = Math.floor(Math.random() * GRID_SIZE);
    if(!snake.some(p => p.x===x && p.y===y)){
      break;
    }
  }
  return {x, y};
}

function placeFood() {
  food = getRandomCoord();
}

function drawGrid() {
  ctx.strokeStyle = '#3f4752';
  for(let x=0; x<=GRID_SIZE; x++){
    ctx.beginPath();
    ctx.moveTo(x*CELL, 0);
    ctx.lineTo(x*CELL, canvas.height);
    ctx.stroke();
  }
  for(let y=0; y<=GRID_SIZE; y++){
    ctx.beginPath();
    ctx.moveTo(0, y*CELL);
    ctx.lineTo(canvas.width, y*CELL);
    ctx.stroke();
  }
}

function drawSnake() {
  snake.forEach((segment, index) => {
    const x = segment.x * CELL;
    const y = segment.y * CELL;
    if(index === 0){ // head
      ctx.fillStyle = var(--snake-head-color);
      ctx.fillRect(x + gridGap, y + gridGap, CELL - gridGap*2, CELL - gridGap*2);
      // eyes facing direction
      ctx.fillStyle = '#fff';
      const eyeSize = CELL/7;
      const offset = CELL/4;
      let eye1, eye2;
      if(direction.x > 0){ // right
        eye1 = {x: x + CELL - gridGap*2 - offset, y: y + offset};
        eye2 = {x: x + CELL - gridGap*2 - offset, y: y + CELL - gridGap*2 - offset};
      } else if(direction.x < 0){ // left
        eye1 = {x: x + offset, y: y + offset};
        eye2 = {x: x + offset, y: y + CELL - gridGap*2 - offset};
      } else if(direction.y < 0){ // up
        eye1 = {x: x + offset, y: y + offset};
        eye2 = {x: x + CELL - gridGap*2 - offset, y: y + offset};
      } else { // down
        eye1 = {x: x + offset, y: y + CELL - gridGap*2 - offset};
        eye2 = {x: x + CELL - gridGap*2 - offset, y: y + CELL - gridGap*2 - offset};
      }
      ctx.beginPath();
      ctx.ellipse(eye1.x, eye1.y, eyeSize, eyeSize, 0, 0, Math.PI*2);
      ctx.ellipse(eye2.x, eye2.y, eyeSize, eyeSize, 0, 0, Math.PI*2);
      ctx.fill();
    } else { // body
      ctx.fillStyle = var(--snake-body-color);
      ctx.fillRect(x + gridGap, y + gridGap, CELL - gridGap*2, CELL - gridGap*2);
    }
  });
}

function drawFood() {
  const x = food.x * CELL;
  const y = food.y * CELL;
  ctx.fillStyle = var(--food-color);
  ctx.beginPath();
  ctx.arc(x + CELL/2, y + CELL/2, CELL/2 - gridGap*2, 0, Math.PI*2);
  ctx.fill();
}

function drawParticles(x, y, count=8, colors=[var(--particle-color)]) {
  const now = Date.now();
  const particles = [];
  for(let i=0;i<count;i++){
    const angle = (Math.PI*2 * i / count) + Math.random()*0.4 -0.2;
    const speed = Math.random()*4+2;
    particles.push({
      x, y,
      vx: Math.cos(angle)*speed,
      vy: Math.sin(angle)*speed,
      life: 500 + Math.random()*300,
      start: now,
      color: colors[Math.floor(Math.random()*colors.length)]
    });
  }
  // simple animation loop for particles
  (function animatePart(){
    particlesCtx.clearRect(0,0,particlesCanvas.width,particlesCanvas.height);
    let alive = false;
    for(const p of particles){
      const elapsed = Date.now() - p.start;
      const t = elapsed / p.life;
      if(t >= 1) continue;
      alive = true;
      const curX = p.x - (p.vx*t*60);
      const curY = p.y - (p.vy*t*60);
      const alpha = 1 - t;
      particlesCtx.globalAlpha = alpha;
      particlesCtx.fillStyle = p.color;
      particlesCtx.beginPath();
      particlesCtx.arc(curX, curY, CELL/6 * (1-t*0.5), 0, Math.PI*2);
      particlesCtx.fill();
    }
    particlesCtx.globalAlpha = 1;
    if(alive) requestAnimationFrame(animatePart);
    else particlesCtx.clearRect(0,0,particlesCanvas.width,particlesCanvas.height);
  })();
}

function update() {
  if(!gameRunning || gameOver || paused) return;
  const head = snake[0];
  const newHead = {
    x: head.x + nextDirection.x,
    y: head.y + nextDirection.y
  };
  // wrap-around walls
  if(newHead.x < 0) newHead.x = GRID_SIZE -1;
  if(newHead.x >= GRID_SIZE) newHead.x = 0;
  if(newHead.y < 0) newHead.y = GRID_SIZE -1;
  if(newHead.y >= GRID_SIZE) newHead.y = 0;

  // self collision (only if not growing)
  const ate = false;
  if(snake.some(seg=>seg.x===newHead.x && seg.y===newHead.y)){
    gameOver = true;
    gameRunning = false;
    showGameOver();
    return;
  }

  snake.unshift(newHead);
  if(newHead.x === food.x && newHead.y === food.y){
    score += 10;
    scoreDisplay.textContent = score;
    if(score > best){
      best = score;
      bestDisplay.textContent = best;
      localStorage.setItem('snakeBest', best);
    }
    placeFood();
    drawParticles(newHead.x*CELL + CELL/2, newHead.y*CELL + CELL/2);
  } else {
    snake.pop();
  }
  direction = {...nextDirection};
}

function draw() {
  ctx.clearRect(0,0,canvas.width,canvas.height);
  drawGrid();
  drawSnake();
  drawFood();
}

function gameLoop() {
  update();
  draw();
  animationId = requestAnimationFrame(gameLoop);
}

function showGameOver() {
  finalScoreDisplay.textContent = score;
  overlay.classList.add('active');
}
function hideGameOver() {
  overlay.classList.remove('active');
  gameOver = false;
}

function startGame() {
  if(gameRunning) return;
  snake = [{x:12, y:12}];
  direction = {x:1, y:0};
  nextDirection = {x:1, y:0};
  score = 0;
  scoreDisplay.textContent = score;
  placeFood();
  gameRunning = true;
  gameOver = false;
  hideGameOver();
  pauseScreen.classList.remove('active');
  paused = false;
  if(animationId) cancelAnimationFrame(animationId);
  animationId = requestAnimationFrame(gameLoop);
}

function keyDown(e) {
  const key = e.key;
  if(dirs[key]){
    const dir = dirs[key];
    // prevent reverse
    if(dir.x === -direction.x && dir.y === -direction.y) return;
    nextDirection = dir;
  }
  if(key === ' ' || key === 'Enter'){
    if(gameOver){
      startGame();
    } else if(!gameRunning){
      startGame();
    }
  }
  if(key === 'p' || key === 'P'){
    paused = !paused;
    pauseScreen.classList.toggle('active', paused);
    if(paused) cancelAnimationFrame(animationId);
    else animationId = requestAnimationFrame(gameLoop);
  }
  // prevent scrolling on arrow keys
  if(['ArrowUp','ArrowDown','ArrowLeft','ArrowRight'].includes(key)){
    e.preventDefault();
  }
}

// initial start with self-playing AI
let aiTimer = null;
function startSelfPlay() {
  // initial direction right
  nextDirection = {x:1, y:0};
  // start game after a short delay so the "Click or press a key to start" appears briefly
  setTimeout(()=>{
    document.addEventListener('click',()=>{
      gameRunning = true;
      animationId = requestAnimationFrame(gameLoop);
    },{once:true});
    document.addEventListener('keydown',()=>{
      gameRunning = true;
      if(!animationId) animationId = requestAnimationFrame(gameLoop);
    },{once:true});
    // Show hint overlay
    const hint = document.createElement('div');
    hint.textContent = 'Click or press any key to start';
    hint.style.position='absolute';
    hint.style.inset='0';
    hint.style.display='flex';
    hint.style.alignItems='center';
    hint.style.justifyContent='center';
    hint.style.fontSize='2rem';
    hint.style.color='#fff';
    hint.style.background='rgba(0,0,0,0.5)';
    hint.style.zIndex='30';
    document.body.appendChild(hint);
    setTimeout(()=>{
      document.body.removeChild(hint);
    },2000);
  },500);
}
startSelfPlay();

document.addEventListener('keydown', keyDown);
window.addEventListener('resize', resize);

// Touch friendly: show start hint on mobile
if('ontouchstart' in window){
  const touchHint = document.createElement('div');
  touchHint.textContent = 'Tap to start';
  touchHint.style.position='absolute';
  touchHint.style.bottom='80px';
  touchHint.style.left='50%';
  touchHint.style.transform='translateX(-50%)';
  touchHint.style.color='#fff';
  touchHint.style.opacity='.6';
  document.body.appendChild(touchHint);
  canvas.addEventListener('touchstart', e=>{
    e.preventDefault();
    startGame();
    document.body.removeChild(touchHint);
  });
}
</script>
</body>
</html>