Skip to main content

snake.html

A snake game for https://t0.vc/g, created using Claude.ai.

gist link


snake. use arrow keys. mouse over to prevent scrolling.
Claude made it. Maybe has touch support.
<canvas id="snake" width="500" height="375" style="border:2px solid #666"></canvas>
<script>
((cellSize, gameActive, score, rand, _fillStyle, _fillRect, _fillText, _changedTouches, _clientX, _clientY, canvas, ctx, snake, direction, food, touchX, touchY, randomizeFood, draw, reset, handleKey, isHovering) => {
  canvas = document.getElementById('snake');
  ctx = canvas.getContext('2d');
  ctx.textBaseline = 'top';
  
  randomizeFood = (limit=5) => {
    food = [rand()*20|0, rand()*15|0];
    if(snake.some(s=>s[0]===food[0]&&s[1]===food[1]) && limit) randomizeFood(limit-1);
  };
  
  reset = () => {
    snake = [[10,7],[9,7],[8,7]];
    direction = [1,0];
    gameActive = true;
    score = 0;
    randomizeFood();
  };
  
  reset();
  
  draw = (head) => {
    if(!gameActive) return;
    
    head = [snake[0][0]+direction[0], snake[0][1]+direction[1]];
    
    if(head[0]<0||head[0]>=20||head[1]<0||head[1]>=15||snake.some(s=>s[0]===head[0]&&s[1]===head[1])){
      gameActive = false;
      ctx.textAlign = 'center';
      ctx[_fillStyle] = '#fff';
      ctx.font = '60px Arial';
      ctx[_fillText]('GAME OVER',250,200);
      return;
    }
    
    snake.unshift(head);
    
    if(head[0]===food[0] && head[1]===food[1]){
      randomizeFood();
      score++;
    } else {
      snake.pop();
    }
    
    ctx[_fillStyle] = '#222';
    ctx[_fillRect](0,0,500,375);
    ctx.textAlign = 'left';
    ctx.font = '30px';
    snake.map(s=>ctx[_fillText]('🟩',s[0]*cellSize,s[1]*cellSize));
    ctx[_fillText]('🍎',food[0]*cellSize,food[1]*cellSize);
    ctx[_fillStyle] = '#fff';
    ctx.font = '20px Arial';
    ctx[_fillText](score,10,10);
  };
  
  handleKey = (e, newDir) => {
    if(!gameActive) reset();
    newDir = {ArrowLeft:[-1,0],ArrowUp:[0,-1],ArrowRight:[1,0],ArrowDown:[0,1]}[e.key];
    if(newDir){
      if(isHovering) e.preventDefault();
      if(!(newDir[0]===-direction[0] && newDir[1]===-direction[1])) direction = newDir;
    }
  };
  
  document.onkeydown = handleKey;
  
  canvas.onmouseenter = () => isHovering = true;
  canvas.onmouseleave = () => isHovering = false;
  
  canvas.ontouchstart = e => {
    if(!gameActive) reset();
    touchX = e.touches[0][_clientX];
    touchY = e.touches[0][_clientY];
  };
  
  canvas.ontouchend = (e, dx, dy, newDir) => {
    dx = e[_changedTouches][0][_clientX] - touchX;
    dy = e[_changedTouches][0][_clientY] - touchY;
    newDir = Math.abs(dx)>Math.abs(dy) ? (dx>0?[1,0]:[-1,0]) : (dy>0?[0,1]:[0,-1]);
    if(!(newDir[0]===-direction[0] && newDir[1]===-direction[1])) direction = newDir;
    e.preventDefault();
  };
  
  setInterval(draw, 150);
})(25, true, 0, Math.random, 'fillStyle', 'fillRect', 'fillText', 'changedTouches', 'clientX', 'clientY');
</script>