<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Infinite Snake</title>
<style>
body{
  margin:0;
  background:#111;
  font-family:Arial,sans-serif;
  text-align:center;
  color:white;
}
#game{
  max-width:600px;
  margin:auto;
  background:#1d2430;
  padding:10px;
  min-height:100vh;
}
h1{
  margin:5px;
  color:#72ff72;
}
#hud{
  display:flex;
  justify-content:space-around;
  background:#080b10;
  padding:10px;
  font-weight:bold;
  color:#7cff69;
}
#board{
  position:relative;
  margin:10px auto;
  width:360px;
  height:360px;
  max-width:90vw;
  max-height:90vw;
  background:#07110a;
  border:5px solid #555;
  overflow:hidden;
  touch-action:none;
}
.cell{
  position:absolute;
  width:9%;
  height:9%;
}
.snake{
  background:#35d957;
  border:1px solid #123;
  border-radius:3px;
}
.head{
  background:#a5ff45;
  border-radius:5px;
}
.food{
  background:#ff4141;
  border-radius:50%;
}
.wall{
  background:#626a75;
  border:1px solid #aaa;
}
#controls{
  display:grid;
  grid-template-columns:repeat(3,80px);
  justify-content:center;
  gap:7px;
  margin-top:10px;
}
button{
  height:60px;
  font-size:22px;
  font-weight:bold;
  border-radius:10px;
  border:3px outset #fff;
  background:#333b4a;
  color:white;
}
button:active{
  border-style:inset;
  transform:scale(.95);
}
.empty{
  visibility:hidden;
}
#start{
  font-size:16px;
  height:48px;
  padding:0 25px;
  margin:5px;
}
#msg{
  min-height:25px;
  color:#ccc;
  font-size:14px;
}
</style>
</head>
<body>
<div id="game">
<h1>🐍 INFINITE SNAKE</h1>
<div id="hud">
<div>LEVEL <span id="level">1</span></div>
<div>SCORE <span id="score">0</span></div>
<div>❤️ <span id="lives">3</span></div>
</div>
<div id="board"></div>

START / RESTART

<div id="msg">
Eat the food and survive!
</div>
<div id="controls">

⬆️
⬅️
⏸️
➡️

⬇️
</div>
</div>
<script>
const SIZE=10;
let snake;
let food;
let walls;
let dx=1;
let dy=0;
let level=1;
let score=0;
let lives=3;
let running=false;
let paused=false;
let speed=180;
let loop;
const board=document.getElementById("board");
function cell(x,y){
let e=document.createElement("div");
e.className="cell";
e.style.left=(x*10)+"%";
e.style.top=(y*10)+"%";
return e;
}
function draw(){
board.innerHTML="";
for(let w of walls){
let e=cell(w.x,w.y);
e.classList.add("wall");
board.appendChild(e);
}
let f=cell(food.x,food.y);
f.classList.add("food");
board.appendChild(f);
snake.forEach((s,i)=>{
let e=cell(s.x,s.y);
e.classList.add("snake");
if(i==0)
e.classList.add("head");
board.appendChild(e);
});
}
function randomSpot(){
while(true){
let x=Math.floor(Math.random()*SIZE);
let y=Math.floor(Math.random()*SIZE);
let bad=false;
for(let s of snake){
if(s.x==x && s.y==y)
bad=true;
}
for(let w of walls){
if(w.x==x && w.y==y)
bad=true;
}
if(!bad)
return {x:x,y:y};
}
}
function makeWalls(){
walls=[];
let amount=Math.min(2+level,35);
for(let i=0;i<amount;i++){
let w={
x:Math.floor(Math.random()*SIZE),
y:Math.floor(Math.random()*SIZE)
};
if(
(w.x==4 && w.y==5) ||
(w.x==5 && w.y==5)
){
i--;
continue;
}
walls.push(w);
}
}
function newLevel(){
makeWalls();
snake=[
{x:4,y:5},
{x:3,y:5},
{x:2,y:5}
];
dx=1;
dy=0;
food=randomSpot();
speed=Math.max(75,180-(Math.min(level,10)-1)*10);
document.getElementById("level").innerText=level;
draw();
message(
"LEVEL "+level+" — New layout!"
);
}
function startGame(){
level=1;
score=0;
lives=3;
running=true;
paused=false;
document.getElementById("score").innerText=score;
document.getElementById("lives").innerText=lives;
newLevel();
clearInterval(loop);
loop=setInterval(tick,speed);
}
function tick(){
if(!running || paused)
return;
let head=snake[0];
let nx=head.x+dx;
let ny=head.y+dy;
if(
nx<0 ||
ny<0 ||
nx>=SIZE ||
ny>=SIZE ||
walls.some(w=>w.x==nx && w.y==ny) ||
snake.some(s=>s.x==nx && s.y==ny)
){
loseLife();
return;
}
let newHead={x:nx,y:ny};
snake.unshift(newHead);
if(nx==food.x && ny==food.y){
score+=10;
document.getElementById("score").innerText=score;
if(snake.length>=8+level){
level++;
document.getElementById("level").innerText=level;
newLevel();
clearInterval(loop);
loop=setInterval(tick,speed);
return;
}
food=randomSpot();
}else{
snake.pop();
}
draw();
}
function loseLife(){
lives--;
document.getElementById("lives").innerText=lives;
if(lives<=0){
running=false;
clearInterval(loop);
alert(
"GAME OVER!\nScore: "+score+
"\nYou reached level "+level
);
return;
}
message("💥 Ouch! Life lost.");
newLevel();
}
function changeDir(x,y){
if(!running || paused)
return;
if(x==-dx && y==-dy)
return;
dx=x;
dy=y;
}
function pauseGame(){
if(!running)
return;
paused=!paused;
message(
paused ?
"⏸️ PAUSED" :
"▶️ BACK TO IT!"
);
}
function message(text){
document.getElementById("msg").innerText=text;
}
// KEYBOARD CONTROLS
// Arrow keys and WASD move the snake.
// Space pauses or resumes the game.
// preventDefault() stops the browser from scrolling.
document.addEventListener("keydown",function(e){
let key=e.key.toLowerCase();
let gameplayKey=[
"arrowup",
"arrowdown",
"arrowleft",
"arrowright",
"w",
"a",
"s",
"d",
" "
].includes(key);
if(gameplayKey){
e.preventDefault();
}
if(key=="arrowup" || key=="w"){
changeDir(0,-1);
}
else if(key=="arrowdown" || key=="s"){
changeDir(0,1);
}
else if(key=="arrowleft" || key=="a"){
changeDir(-1,0);
}
else if(key=="arrowright" || key=="d"){
changeDir(1,0);
}
else if(key==" "){
pauseGame();
}
});
// SWIPE CONTROLS
let startX=0;
let startY=0;
board.addEventListener("touchstart",function(e){
startX=e.touches[0].clientX;
startY=e.touches[0].clientY;
},{passive:true});
board.addEventListener("touchend",function(e){
let x=e.changedTouches[0].clientX;
let y=e.changedTouches[0].clientY;
let ax=Math.abs(x-startX);
let ay=Math.abs(y-startY);
if(Math.max(ax,ay)<20)
return;
if(ax>ay){
changeDir(x>startX?1:-1,0);
}else{
changeDir(0,y>startY?1:-1);
}
},{passive:true});
</script>
</body>
</html>