Simple Snake Game with Score and Restart

Answered using OpenAI o1 mini by OpenAI o1

Question:

Generate a code for a snake game. Use HTML, CSS, and JavaScript. Incorporate a score and high score feature. Include a restart button. Additionally, combine all files into the HTML file.

Answer:

Certainly! Below is a complete implementation of a simple Snake game using HTML, CSS, and JavaScript, all combined into a single HTML file. This version includes a score display, a high score feature, and a restart button.

<!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>
    <style>
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
        }
        canvas {
            border: 1px solid #000;
            background-color: #fff;
        }
        #scoreboard {
            margin: 20px;
            font-size: 24px;
        }
        #restart {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
        }
    </style>
</head>
<body>

    <div id="scoreboard">
        Score: <span id="score">0</span> | High Score: <span id="highScore">0</span>
    </div>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
    <button id="restart">Restart</button>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const box = 20;
        let snake = [{ x: 9 * box, y: 9 * box }];
        let direction = '';
        let food = { x: Math.floor(Math.random() * 20) * box, y: Math.floor(Math.random() * 20) * box };
        let score = 0;
        let highScore = localStorage.getItem('highScore') ? parseInt(localStorage.getItem('highScore')) : 0;

        document.getElementById('highScore').innerText = highScore;

        document.addEventListener('keydown', changeDirection);
        document.getElementById('restart').addEventListener('click', restartGame);

        function changeDirection(event) {
            if (event.keyCode === 37 && direction !== 'RIGHT') {
                direction = 'LEFT';
            } else if (event.keyCode === 38 && direction !== 'DOWN') {
                direction = 'UP';
            } else if (event.keyCode === 39 && direction !== 'LEFT') {
                direction = 'RIGHT';
            } else if (event.keyCode === 40 && direction !== 'UP') {
                direction = 'DOWN';
            }
        }

        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            for (let i = 0; i < snake.length; i++) {
                ctx.fillStyle = (i === 0) ? 'green' : 'lightgreen';
                ctx.fillRect(snake[i].x, snake[i].y, box, box);
                ctx.strokeStyle = 'darkgreen';
                ctx.strokeRect(snake[i].x, snake[i].y, box, box);
            }

            ctx.fillStyle = 'red';
            ctx.fillRect(food.x, food.y, box, box);

            let snakeX = snake[0].x;
            let snakeY = snake[0].y;

            if (direction === 'LEFT') snakeX -= box;
            if (direction === 'UP') snakeY -= box;
            if (direction === 'RIGHT') snakeX += box;
            if (direction === 'DOWN') snakeY += box;

            if (snakeX === food.x && snakeY === food.y) {
                score++;
                document.getElementById('score').innerText = score;
                food = { x: Math.floor(Math.random() * 20) * box, y: Math.floor(Math.random() * 20) * box };
            } else {
                snake.pop();
            }

            const newHead = { x: snakeX, y: snakeY };

            if (snakeX < 0 || snakeY < 0 || snakeX >= canvas.width || snakeY >= canvas.height || collision(newHead, snake)) {
                clearInterval(game);
                if (score > highScore) {
                    highScore = score;
                    localStorage.setItem('highScore', highScore);
                    document.getElementById('highScore').innerText = highScore;
                }
                alert('Game Over! Press Restart to play again.');
            }

            snake.unshift(newHead);
        }

        function collision(head, array) {
            for (let i = 0; i < array.length; i++) {
                if (head.x === array[i].x && head.y === array[i].y) {
                    return true;
                }
            }
            return false;
        }

        function restartGame() {
            snake = [{ x: 9 * box, y: 9 * box }];
            direction = '';
            food = { x: Math.floor(Math.random() * 20) * box, y: Math.floor(Math.random() * 20) * box };
            score = 0;
            document.getElementById('score').innerText = score;
            clearInterval(game);
            game = setInterval(draw, 100);
        }

        let game = setInterval(draw, 100);
    </script>

</body>
</html>

How to Use:

  1. Copy the above code into a text editor.
  2. Save the file with a .html extension (e.g., snake_game.html).
  3. Open the file in a web browser to play the game.

Game Controls:

  • Use the arrow keys to control the direction of the snake.
  • Click the "Restart" button to restart the game after a game over.

Features:

  • The game keeps track of the current score and the high score.
  • The high score is saved in the browser's local storage, so it persists even after refreshing the