{
  "id": "snake",
  "name": "Snake",
  "category": "gaming",
  "tags": ["game", "snake", "arcade", "retro", "classic"],
  "description": "Classic Snake game with score, high score, and speed increase.",
  "triggers": ["snake", "snake game", "play snake", "retro game", "arcade"],
  "defaultSize": { "w": 5, "h": 6 },
  "source": "function SnakeGame() {\n  const [snake, setSnake] = React.useState([{x:10,y:10}]);\n  const [food, setFood] = React.useState({x:15,y:15});\n  const [dir, setDir] = React.useState({x:1,y:0});\n  const [score, setScore] = React.useState(0);\n  const [high, setHigh] = React.useState(0);\n  const [over, setOver] = React.useState(false);\n  const [running, setRunning] = React.useState(false);\n  const canvasRef = React.useRef(null);\n\n  const rand = ()=>({x:Math.floor(Math.random()*20),y:Math.floor(Math.random()*20)});\n\n  React.useEffect(()=>{\n    if(!running||over)return;\n    const id = setInterval(()=>{\n      setSnake(prev=>{\n        const head = {x:prev[0].x+dir.x,y:prev[0].y+dir.y};\n        if(head.x<0||head.x>=20||head.y<0||head.y>=20||prev.some(s=>s.x===head.x&&s.y===head.y)){\n          setOver(true);setRunning(false);setHigh(h=>Math.max(h,score));return prev;\n        }\n        const next = [head,...prev];\n        if(head.x===food.x&&head.y===food.y){setScore(s=>s+10);setFood(rand());}\n        else next.pop();\n        return next;\n      });\n    },150);\n    return ()=>clearInterval(id);\n  },[running,over,dir,food,score]);\n\n  React.useEffect(()=>{\n    const c = canvasRef.current; if(!c)return;\n    const ctx = c.getContext('2d');\n    ctx.fillStyle='#000';ctx.fillRect(0,0,300,300);\n    ctx.fillStyle='#34C759';\n    snake.forEach(s=>ctx.fillRect(s.x*15,s.y*15,14,14));\n    ctx.fillStyle='#FF3B30';ctx.fillRect(food.x*15,food.y*15,14,14);\n  },[snake,food]);\n\n  const key = (e)=>{\n    const k = e.key;\n    if(k==='ArrowUp'&&dir.y!==1)setDir({x:0,y:-1});\n    if(k==='ArrowDown'&&dir.y!==-1)setDir({x:0,y:1});\n    if(k==='ArrowLeft'&&dir.x!==1)setDir({x:-1,y:0});\n    if(k==='ArrowRight'&&dir.x!==-1)setDir({x:1,y:0});\n  };\n\n  React.useEffect(()=>{window.addEventListener('keydown',key);return()=>window.removeEventListener('keydown',key);},[dir]);\n\n  const restart = ()=>{setSnake([{x:10,y:10}]);setFood(rand());setDir({x:1,y:0});setScore(0);setOver(false);setRunning(true);};\n\n  return (\n    <div style={{padding:12,fontFamily:'system-ui',display:'flex',flexDirection:'column',alignItems:'center',height:'100%'}}>\n      <div style={{display:'flex',justifyContent:'space-between',width:300,marginBottom:8}}>\n        <span style={{fontSize:14,fontWeight:700}}>Score: {score}</span>\n        <span style={{fontSize:14,color:'#888'}}>High: {high}</span>\n      </div>\n      <canvas ref={canvasRef} width={300} height={300} style={{borderRadius:8,background:'#000'}}/>\n      <div style={{marginTop:12}}>\n        {!running&&!over&&<button onClick={()=>setRunning(true)} style={{padding:'8px 20px',borderRadius:8,background:'#34C759',color:'#fff',border:'none',cursor:'pointer'}}>Start</button>}\n        {over&&<button onClick={restart} style={{padding:'8px 20px',borderRadius:8,background:'#FF3B30',color:'#fff',border:'none',cursor:'pointer'}}>Game Over — Retry</button>}\n        {running&&<button onClick={()=>setRunning(false)} style={{padding:'8px 20px',borderRadius:8,background:'#888',color:'#fff',border:'none',cursor:'pointer'}}>Pause</button>}\n      </div>\n      <div style={{fontSize:11,color:'#aaa',marginTop:8}}>Use arrow keys to move</div>\n    </div>\n  );\n}\nrender(<SnakeGame/>);",
  "placeholders": []
}
