DEV Community

Alexya
Alexya

Posted on

The old school snake game with just 100 lines of JS code

If you grew up in the late '90s or early 2000s, you probably remember the classic Snake game.

It was simple, addictive, and a PUBG of early mobile gaming. I recently decided to recreate it using just 100 lines of Javascript.

Here is the HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Snake Game</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="container">
    <h1>Snake Game</h1>
    <div id="score">Score: 0</div>
    <div id="game-board"></div>
    <button id="start-restart">Start / Restart</button>
  </div>
  <script src="script.js"></script>
</body>
</html>

Enter fullscreen mode Exit fullscreen mode

CSS:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #f3f3f3;
}

.container {
  text-align: center;
}

#game-board {
  display: grid;
  grid-template-columns: repeat(20, 20px);
  grid-template-rows: repeat(20, 20px);
  gap: 1px;
  background-color: #e0e0e0;
  margin: 20px auto;
  width: 400px;
  height: 400px;
  position: relative;
}

.cell {
  width: 20px;
  height: 20px;
  background-color: #f3f3f3;
}

.snake {
  background-color: green;
}

.food {
  background-color: red;
}

#score {
  font-size: 20px;
  margin: 10px 0;
}

button {
  padding: 10px 20px;
  font-size: 16px;
  cursor: pointer;
  border: none;
  background-color: #007BFF;
  color: white;
  border-radius: 5px;
}

button:hover {
  background-color: #0056b3;
}

Enter fullscreen mode Exit fullscreen mode

JS:

const board = document.getElementById('game-board');
const scoreDisplay = document.getElementById('score');
const startRestartButton = document.getElementById('start-restart');

const gridSize = 20;
const boardSize = gridSize * gridSize;
let snake = [42, 41, 40]; // Starting position
let direction = 1; // Moving right
let nextDirection = 1; // Buffer for next direction
let food = null;
let score = 0;
let intervalId = null;
const speed = 100;

function createBoard() {
  board.innerHTML = '';
  for (let i = 0; i < boardSize; i++) {
    const cell = document.createElement('div');
    cell.classList.add('cell');
    board.appendChild(cell);
  }
}

function updateBoard() {
  const cells = document.querySelectorAll('.cell');
  cells.forEach(cell => cell.classList.remove('snake', 'food'));

  snake.forEach(index => cells[index].classList.add('snake'));
  if (food !== null) cells[food].classList.add('food');
}

function spawnFood() {
  let newFood;
  do {
    newFood = Math.floor(Math.random() * boardSize);
  } while (snake.includes(newFood));
  food = newFood;
}

function moveSnake() {
  const head = snake[0];
  const newHead = getNewHead(head);

  // Check for collisions with itself
  if (snake.includes(newHead)) {
    clearInterval(intervalId);
    alert(`Game Over! Your final score is ${score}.`);
    return;
  }

  // Move snake
  snake.unshift(newHead);
  if (newHead === food) {
    score++;
    scoreDisplay.textContent = `Score: ${score}`;
    spawnFood();
  } else {
    snake.pop();
  }
  direction = nextDirection;
  updateBoard();
}

function getNewHead(head) {
  let newHead = head + nextDirection;

  if (nextDirection === 1 && head % gridSize === gridSize - 1) {
    newHead = head - (gridSize - 1); // Wrap to the left
  } else if (nextDirection === -1 && head % gridSize === 0) {
    newHead = head + (gridSize - 1); // Wrap to the right
  } else if (nextDirection === gridSize && head + gridSize >= boardSize) {
    newHead = head % gridSize; // Wrap to the top
  } else if (nextDirection === -gridSize && head - gridSize < 0) {
    newHead = head + boardSize - gridSize; // Wrap to the bottom
  }

  return newHead;
}

function changeDirection(e) {
  const key = e.key;

  // Prevent reversing direction
  if (key === 'ArrowUp' && direction !== gridSize) nextDirection = -gridSize;
  if (key === 'ArrowDown' && direction !== -gridSize) nextDirection = gridSize;
  if (key === 'ArrowLeft' && direction !== 1) nextDirection = -1;
  if (key === 'ArrowRight' && direction !== -1) nextDirection = 1;
}

function startGame() {
  snake = [42, 41, 40];
  direction = 1;
  nextDirection = 1;
  score = 0;
  scoreDisplay.textContent = `Score: ${score}`;
  spawnFood();
  updateBoard();

  if (intervalId) clearInterval(intervalId);
  intervalId = setInterval(moveSnake, speed);
}

createBoard();
startRestartButton.addEventListener('click', startGame);
document.addEventListener('keydown', changeDirection);

Enter fullscreen mode Exit fullscreen mode

You can make changes to above code according to what more creativity you can add.

Try playing here: https://codepen.io/alexya99/pen/EaYbaxo

As a game developer I have worked on many gaming projects. You can review our one of gaming portfolio site such as geometry dash spam full of such web based games.

Warp.dev image

Warp is the highest-rated coding agent—proven by benchmarks.

Warp outperforms every other coding agent on the market, and gives you full control over which model you use. Get started now for free, or upgrade and unlock 2.5x AI credits on Warp's paid plans.

Download Warp

Top comments (1)

Collapse
 
albert_001ae66d1b1278b0ab profile image
Albert

hahaha, geometrydash-meltdown you recommended is interesting. I like it!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

Feature flag article image

Create a feature flag in your IDE in 5 minutes with LaunchDarkly’s MCP server ⏰

How to create, evaluate, and modify flags from within your IDE or AI client using natural language with LaunchDarkly's new MCP server. Follow along with this tutorial for step by step instructions.

Read full post

👋 Kindness is contagious

Explore this insightful write-up embraced by the inclusive DEV Community. Tech enthusiasts of all skill levels can contribute insights and expand our shared knowledge.

Spreading a simple "thank you" uplifts creators—let them know your thoughts in the discussion below!

At DEV, collaborative learning fuels growth and forges stronger connections. If this piece resonated with you, a brief note of thanks goes a long way.

Okay