Showcase

Snake, with juice, built by Underdog Saluki 27B

IQ2_XSneeds 10.2 GB at 32Kvia OpenCodellama.cpp
Running live in your browserNew tab
Memory to run
10.2GB
At 32K context, from its benchmark run
Show the code the model wrote
HTML13,331 characters
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Snake</title>
<style>
  html, body { margin: 0; height: 100%; }
  body {
    background: radial-gradient(1200px 800px at 50% 40%, #0a1226, #05070f);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    font-family: "SF Pro Text", system-ui, -apple-system, sans-serif;
    color: #8fa8cc;
  }
  canvas {
    border: 1px solid #1d2b4a;
    border-radius: 12px;
    box-shadow: 0 0 45px rgba(0, 35, 90, 0.45);
    background: #0b1020;
  }
  .hint {
    margin-top: 14px;
    font-size: 12px;
    letter-spacing: 0.06em;
    color: #5c7196;
    user-select: none;
  }
  .hint b { color: #9db4d4; }
</style>
</head>
<body>
<canvas id="game" width="672" height="672"></canvas>
<div class="hint"><b>←→↑↓ / WASD</b> move · <b>P</b> pause · <b>SPACE</b> restart</div>

<script>
"use strict";

/* ---------- board ---------- */
const COLS = 24, ROWS = 24, CELL = 28;
const W = COLS * CELL, H = ROWS * CELL;
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");

const DIRS  = { up: [0, -1], down: [0, 1], left: [-1, 0], right: [1, 0] };
const OPP   = { up: "down", down: "up", left: "right", right: "left" };

/* ---------- state ---------- */
let snake, dir, queue;      // snake: [{x,y}...] head first
let food;                    // {x,y}
let score = 0, best = 0;     // best = this session
let level = 1;               // speed level
let acc = 0;                // ms accumulator for fixed ticks
let dead = false, overT = 0; // overT: time since death
let paused = false;

let shake = { mag: 0 };
let flash = 0;               // red flash alpha
let speedPulse = 0;          // HUD speed text pulse 0..1
let foodPhase = 0;           // pulse phase
let particles = [];
let scorePops = [];
let rings = [];

function cellCenter(c) { return { x: c.x * CELL + CELL / 2, y: c.y * CELL + CELL / 2 }; }

function tickMs() { return Math.max(60, 140 - 12 * (level - 1)); }

function spawnFood() {
  const free = [];
  for (let x = 0; x < COLS; x++)
    for (let y = 0; y < ROWS; y++) {
      let on = false;
      for (const s of snake) if (s.x === x && s.y === y) { on = true; break; }
      if (!on) free.push({ x, y });
    }
  food = free[(Math.random() * free.length) | 0];
}

function reset() {
  snake = [{ x: 12, y: 12 }, { x: 11, y: 12 }, { x: 10, y: 12 }];
  dir = "right";
  queue = [];
  score = 0;
  level = 1;
  acc = 0;
  dead = false;
  overT = 0;
  paused = false;
  particles = [];
  scorePops = [];
  rings = [];
  shake.mag = 0;
  flash = 0;
  speedPulse = 0;
  spawnFood();
}

/* ---------- audio (synthesized, no files) ---------- */
let actx = null;
function ensureAudio() {
  if (!actx) { try { actx = new AudioContext(); } catch (e) { actx = null; } }
  if (actx && actx.state === "suspended") actx.resume();
}
function tone(freq, dur, type = "sine", vol = 0.16, slideTo = null) {
  if (!actx) return;
  const t0 = actx.currentTime;
  const o = actx.createOscillator();
  const g = actx.createGain();
  o.type = type;
  o.frequency.setValueAtTime(freq, t0);
  if (slideTo) o.frequency.exponentialRampToValueAtTime(slideTo, t0 + dur);
  g.gain.setValueAtTime(vol, t0);
  g.gain.exponentialRampToValueAtTime(0.0001, t0 + dur);
  o.connect(g); g.connect(actx.destination);
  o.start(t0); o.stop(t0 + dur + 0.02);
}
const soundEat     = () => { ensureAudio(); tone(660, 0.10, "sine", 0.15, 1180); };
const soundSpeed   = () => { ensureAudio(); tone(500 + level * 90, 0.07, "square", 0.11, 720 + level * 130); };
const soundDeath   = () => { ensureAudio(); tone(220, 0.45, "sawtooth", 0.22, 55); };
const soundRestart = () => { ensureAudio(); tone(440, 0.12, "triangle", 0.14, 880); };
const soundPause   = () => { ensureAudio(); tone(330, 0.06, "sine", 0.09); };

/* ---------- game logic ---------- */
function tick() {
  const d = queue.length ? queue.shift() : dir;
  dir = d;
  const [dx, dy] = DIRS[d];
  const head = { x: snake[0].x + dx, y: snake[0].y + dy };

  if (head.x < 0 || head.x >= COLS || head.y < 0 || head.y >= ROWS) return die();

  const willEat = head.x === food.x && head.y === food.y;
  // tail cell is freed this tick unless we eat, so exclude it
  const body = willEat ? snake : snake.slice(0, -1);
  for (const s of body) if (s.x === head.x && s.y === head.y) return die();

  snake.unshift(head);
  if (willEat) {
    score++;
    onEat(head);
    spawnFood();
  } else {
    snake.pop();
  }
}

function onEat(head) {
  const c = cellCenter(head);
  // particle burst
  for (let i = 0; i < 18; i++) {
    const a = Math.random() * Math.PI * 2;
    const sp = 60 + Math.random() * 160;
    particles.push({
      x: c.x, y: c.y,
      vx: Math.cos(a) * sp, vy: Math.sin(a) * sp,
      life: 0.35 + Math.random() * 0.35,
      size: 1.5 + Math.random() * 2.5,
    });
  }
  // score pop
  scorePops.push({ x: c.x, y: c.y - 6, life: 1 });
  soundEat();

  // speed-up every 5 foods: synthesized tick + visual beat
  if (score % 5 === 0) {
    level++;
    soundSpeed();
    speedPulse = 1;
    rings.push({ x: c.x, y: c.y, r: 6, life: 1 });
  }
}

function die() {
  dead = true;
  overT = 0;
  best = Math.max(best, score);
  shake.mag = 9;
  flash = 0.65;
  soundDeath();
}

/* ---------- input (buffered, 180°-safe) ---------- */
function keyDir(k) {
  switch (k) {
    case "ArrowUp":   case "w": case "W": return "up";
    case "ArrowDown": case "s": case "S": return "down";
    case "ArrowLeft": case "a": case "A": return "left";
    case "ArrowRight":case "d": case "D": return "right";
  }
  return null;
}

addEventListener("keydown", (e) => {
  ensureAudio();
  const k = e.key;

  if (k === " ") {
    e.preventDefault();
    if (dead) { reset(); soundRestart(); }
    return;
  }
  if (k === "p" || k === "P") {
    e.preventDefault();
    if (!dead) { paused = !paused; soundPause(); }
    return;
  }
  const d = keyDir(k);
  if (!d) return;
  e.preventDefault();
  if (dead || paused) return;

  // reject repeats and 180° reversals of the last effective direction
  // (current direction, or the most recent queued move)
  const last = queue.length ? queue[queue.length - 1] : dir;
  if (d === last || d === OPP[last]) return;
  if (queue.length < 2) queue.push(d);
});

/* ---------- update ---------- */
function update(dt) {
  if (!paused && !dead) {
    acc += dt * 1000;
    const t = tickMs();
    while (acc >= t) {
      acc -= t;
      tick();
      if (dead) break;
    }
  }
  if (dead) overT += dt;

  shake.mag *= 0.86;
  if (shake.mag < 0.05) shake.mag = 0;
  flash = Math.max(0, flash - dt * 1.6);
  speedPulse = Math.max(0, speedPulse - dt * 2.5);
  foodPhase += dt;

  for (let i = particles.length - 1; i >= 0; i--) {
    const p = particles[i];
    p.x += p.vx * dt; p.y += p.vy * dt;
    p.vx *= 0.93; p.vy *= 0.93;
    p.life = p.life - dt;
    if (p.life <= 0) particles.splice(i, 1);
  }
  for (let i = scorePops.length - 1; i >= 0; i--) {
    const s = scorePops[i];
    s.y -= 46 * dt;
    s.life -= dt * 1.7;
    if (s.life <= 0) scorePops.splice(i, 1);
  }
  for (let i = rings.length - 1; i >= 0; i--) {
    const r = rings[i];
    r.r += 140 * dt;
    r.life -= dt * 2.2;
    if (r.life <= 0) rings.splice(i, 1);
  }
}

/* ---------- render ---------- */
function lerp(a, b, t) { return a + (b - a) * t; }
function bodyHue(t) { return 130 + t * 62; }      // lime -> cyan
function bodyColor(t) { return `hsl(${bodyHue(t)}, 82%, ${64 - t * 14}%)`; }

function drawBoard() {
  // subtle checkerboard
  for (let x = 0; x < COLS; x++)
    for (let y = 0; y < ROWS; y++) {
      ctx.fillStyle = (x + y) % 2 ? "rgba(255,255,255,0.016)" : "rgba(255,255,255,0.006)";
      ctx.fillRect(x * CELL, y * CELL, CELL, CELL);
    }
  // grid lines
  ctx.strokeStyle = "rgba(255,255,255,0.045)";
  ctx.lineWidth = 1;
  for (let i = 0; i <= COLS; i++) {
    ctx.beginPath(); ctx.moveTo(i * CELL + 0.5, 0); ctx.lineTo(i * CELL + 0.5, H); ctx.stroke();
  }
  for (let i = 0; i <= ROWS; i++) {
    ctx.beginPath(); ctx.moveTo(0, i * CELL + 0.5); ctx.lineTo(W, i * CELL + 0.5); ctx.stroke();
  }
}

function drawFood() {
  const c = cellCenter(food);
  const pulse = 1 + 0.13 * Math.sin(foodPhase * 5.2);
  const r = 0.30 * CELL * pulse;
  ctx.save();
  ctx.shadowColor = "rgba(255,120,70,0.9)";
  ctx.shadowBlur = 14;
  const g = ctx.createRadialGradient(c.x, c.y, 0, c.x, c.y, r);
  g.addColorStop(0, "#ffe6c8");
  g.addColorStop(0.55, "#ff7a45");
  g.addColorStop(1, "rgba(255,90,40,0.25)");
  ctx.fillStyle = g;
  ctx.beginPath(); ctx.arc(c.x, c.y, r, 0, Math.PI * 2); ctx.fill();
  ctx.shadowBlur = 0;
  // breathing ring
  ctx.strokeStyle = `rgba(255,170,110,${0.25 + 0.2 * Math.sin(foodPhase * 5.2)})`;
  ctx.lineWidth = 1.5;
  ctx.beginPath(); ctx.arc(c.x, c.y, r + 3.5, 0, Math.PI * 2); ctx.stroke();
  ctx.restore();
}

function drawSnake() {
  const n = snake.length;
  // glow pass
  ctx.lineCap = "round"; ctx.lineJoin = "round";
  for (let i = n - 1; i >= 1; i--) {
    const a = cellCenter(snake[i]), b = cellCenter(snake[i - 1]);
    const t = (n - 1 - i) / Math.max(1, n - 1);
    ctx.strokeStyle = "rgba(140,255,180,0.10)";
    ctx.lineWidth = lerp(0.44, 0.26, t) * CELL * 2.4;
    ctx.beginPath(); ctx.moveTo(a.x, a.y); ctx.lineTo(b.x, b.y); ctx.stroke();
  }
  // body pass with head→tail gradient
  for (let i = n - 1; i >= 1; i--) {
    const a = cellCenter(snake[i]), b = cellCenter(snake[i - 1]);
    const t = (n - 1 - i) / Math.max(1, n - 1);
    ctx.strokeStyle = bodyColor(t);
    ctx.lineWidth = lerp(0.44, 0.26, t) * CELL * 2;
    ctx.beginPath(); ctx.moveTo(a.x, a.y); ctx.lineTo(b.x, b.y); ctx.stroke();
  }
  // head: leans into the move direction
  const c = cellCenter(snake[0]);
  const [dx, dy] = DIRS[dir];
  const off = 0.15 * CELL;
  const hx = c.x + dx * off, hy = c.y + dy * off;
  const hr = 0.42 * CELL;
  ctx.save();
  ctx.shadowColor = "rgba(160,255,150,0.85)";
  ctx.shadowBlur = 12;
  ctx.fillStyle = "hsl(128, 92%, 70%)";
  ctx.beginPath(); ctx.arc(hx, hy, hr, 0, Math.PI * 2); ctx.fill();
  ctx.restore();
  // eyes
  const px = -dy, py = dx; // perpendicular
  ctx.fillStyle = "#0c1a12";
  ctx.beginPath(); ctx.arc(hx + px * 5 + dx * 4, hy + py * 5 + dy * 4, 2.2, 0, Math.PI * 2); ctx.fill();
  ctx.beginPath(); ctx.arc(hx - px * 5 + dx * 4, hy - py * 5 + dy * 4, 2.2, 0, Math.PI * 2); ctx.fill();
}

function drawFx() {
  for (const p of particles) {
    ctx.fillStyle = `rgba(255,150,80,${Math.max(0, p.life / 0.7)})`;
    ctx.beginPath(); ctx.arc(p.x, p.y, p.size * (0.4 + p.life), 0, Math.PI * 2); ctx.fill();
  }
  for (const s of scorePops) {
    ctx.save();
    ctx.globalAlpha = Math.max(0, s.life);
    ctx.fillStyle = "#ffd76a";
    ctx.font = "700 16px system-ui, sans-serif";
    ctx.textAlign = "center";
    ctx.fillText("+1", s.x, s.y);
    ctx.restore();
  }
  for (const r of rings) {
    ctx.strokeStyle = `rgba(140,255,180,${Math.max(0, r.life)})`;
    ctx.lineWidth = 2;
    ctx.beginPath(); ctx.arc(r.x, r.y, r.r, 0, Math.PI * 2); ctx.stroke();
  }
}

function drawHud(now) {
  ctx.fillStyle = "#dce9ff";
  ctx.font = "600 14px system-ui, sans-serif";
  ctx.textAlign = "left";
  ctx.fillText("SCORE " + score, 12, 22);

  // speed with pulse beat
  const s = 1 + speedPulse * 0.35;
  ctx.save();
  ctx.translate(W - 12, 22);
  ctx.scale(s, s);
  ctx.textAlign = "right";
  ctx.fillStyle = speedPulse > 0.4 ? "#aef78c" : "#dce9ff";
  ctx.fillText("SPD " + level, 0, 0);
  ctx.restore();

  if (paused && !dead) {
    ctx.fillStyle = "rgba(220,235,255,0.9)";
    ctx.font = "700 26px system-ui, sans-serif";
    ctx.textAlign = "center";
    ctx.fillText("PAUSED", W / 2, H / 2 - 8);
    ctx.font = "500 13px system-ui, sans-serif";
    ctx.fillStyle = "rgba(160,180,220,0.7)";
    ctx.fillText("press P to resume", W / 2, H / 2 + 16);
  }
}

function drawGameOver(now) {
  ctx.fillStyle = "rgba(0,0,0,0.55)";
  ctx.fillRect(0, 0, W, H);
  ctx.textAlign = "center";
  ctx.fillStyle = "#ff8a5c";
  ctx.font = "800 40px system-ui, sans-serif";
  ctx.fillText("GAME OVER", W / 2, H / 2 - 34);
  ctx.fillStyle = "#e8f4ff";
  ctx.font = "600 20px system-ui, sans-serif";
  ctx.fillText("SCORE  " + score, W / 2, H / 2 + 12);
  ctx.fillStyle = "#ffd76a";
  ctx.fillText("BEST   " + best, W / 2, H / 2 + 40);
  const a = 0.55 + 0.45 * Math.sin(now / 260);
  ctx.fillStyle = `rgba(174,247,140,${a})`;
  ctx.font = "600 16px system-ui, sans-serif";
  ctx.fillText("PRESS SPACE TO RESTART", W / 2, H / 2 + 78);
}

function render(now) {
  ctx.save();
  if (shake.mag > 0) {
    ctx.translate((Math.random() * 2 - 1) * shake.mag, (Math.random() * 2 - 1) * shake.mag);
  }
  ctx.fillStyle = "#0b1020";
  ctx.fillRect(-20, -20, W + 40, H + 40);
  drawBoard();
  drawFood();
  drawSnake();
  drawFx();
  if (flash > 0) {
    ctx.fillStyle = `rgba(255,60,50,${flash})`;
    ctx.fillRect(-20, -20, W + 40, H + 40);
  }
  drawHud(now);
  if (dead && overT > 0.35) drawGameOver(now);
  ctx.restore();
}

/* ---------- main loop ---------- */
let last = performance.now();
function frame(now) {
  const dt = Math.min(0.1, (now - last) / 1000); // clamp tab-hidden spikes
  last = now;
  update(dt);
  render(now);
  requestAnimationFrame(frame);
}

reset();
requestAnimationFrame(frame);
</script>
</body>
</html>

One email when a new model lands on the board or in the showcase. Unsubscribe anytime.