Open In App

Create a Simon Game using HTML CSS & JavaScript

Last Updated : 02 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will see how to create a Simon Game using HTML, CSS, and JavaScript. In a Simon game, if the player succeeds, the series becomes progressively longer and more complex. Once the user is unable to repeat the designated order of the series at any point, the game is over.

Prerequisites

Approach

  • Create the different HTML elements that will make up the markup of the game, like <div> for making the base structure of the game, <button> to display the word Start, which means the game can be switched on and subsequently played, and <input> for strict mode which means that the game can be played in strict mode and if there is one wrong answer, the user has to start from scratch as opposed to non-strict mode which means that the user can start from where they left off.
  • Add the different styling properties to the game using classes and elements that will define the padding, margin, font sizes to text, alignments, colors, etc to the specific elements.
  • Attack onclick events to each light button which refers to a handleClick() function in JavaScript which agains invokes the this object to refer to the current object for that HTML element. Also, create a data attribute data-color for each light button via a single digit such as 1 for the first color, 2 for the second color etc. The start button simply starts the game and also resets everything to default if there was a previous game that was played.
  • Moreover, create the functions nextRound() which simply lets you play the following round with an increment in the level counter, the checkSequence() function which at every round check whether the whole sequence has been repeated correctly or not, and also helper functions to enable/disable strict mode and for enabling/disabling the light buttons as well.
  • Furthermore, the two arrays of sequence and userSequence are used to determine whether the randomized order by the computer is followed step by step by the user. This is done repeatedly until the user fails to follow the pattern.

Example: This example describes the basic implementation of the Simon Game using HTML, CSS, and Javascript.

HTML




<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href=
    <link rel="preconnect" href=
    <link href=
          rel="stylesheet">
    <title>Simon Game</title>
    <!-- CSS -->
    <style>
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: rgb(206, 201, 201);
            font-family: 'Balsamiq Sans', sans-serif;
        }
 
        #controls {
            margin: 20px 0 20px 0;
        }
 
        #strict-mode {
            margin-right: 20px;
        }
 
        #simon-board {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 20px;
            max-width: 300px;
            text-align: center;
            margin-bottom: 1rem;
        }
 
        .simon-btn {
            width: 100px;
            height: 100px;
            border: none;
            outline: none;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            background-color: #3498db;
            color: #fff;
            transition: background-color 0.3s;
        }
 
        .top-left {
            background-color: darkgreen;
        }
 
        .top-right {
            background-color: darkred;
        }
 
        .bottom-left {
            background-color: goldenrod;
        }
 
        .bottom-right {
            background-color: darkblue;
        }
 
        .level-count {
            color: red;
            background-color: rgb(81, 0, 0);
            padding: 0.25rem 1rem;
        }
 
        #start-btn,
        #power-btn {
            font-family: 'Balsamiq Sans', sans-serif;
            margin-top: 30px;
            padding: 10px;
            font-size: 16px;
            cursor: pointer;
            background-color: #2ecc71;
            color: #fff;
            border: none;
            outline: none;
            border-radius: 5px;
            transition: background-color 0.3s;
        }
 
        #start-btn:hover,
        #power-btn:hover {
            background-color: #27ae60;
        }
 
        #start-btn:disabled,
        #power-btn:disabled {
            background-color: #484a4b;
            cursor: not-allowed;
        }
    </style>
</head>
 
<body>
    <h1>Simon Game</h1>
    <div id="controls">
        <label for="strict-mode">Strict Mode</label>
        <input type="checkbox" id="strict-mode"
               onchange="toggleStrictMode()">
    </div>
 
    <div id="simon-board">
        <button class="simon-btn top-left"
                onclick="handleClick(this)"
        data-color="1" disabled></button>
        <button class="simon-btn top-right"
                onclick="handleClick(this)"
        data-color="2" disabled></button>
        <button class="simon-btn bottom-left"
                onclick="handleClick(this)"
        data-color="3" disabled></button>
        <button class="simon-btn bottom-right"
                onclick="handleClick(this)"
        data-color="4" disabled></button>
    </div>
 
    <div id="level">
        <span>Level:
              <span class="level-count">-</span>
          </span>
    </div>
    <button id="power-btn"
            onclick="togglePower()">Start</button>
    <!-- JavaScript -->
    <script>
        let strictMode = false;
        let powerOn = false;
        const sequence = [];
        let userSequence = [];
        let level = 1;
 
        const levelCount = document.querySelector('.level-count');
 
        function startGame() {
            sequence.length = 0;
            userSequence.length = 0;
            level = 1;
            levelCount.textContent = level;
            nextRound();
            document.getElementById("start-btn").disabled = true;
            document.getElementById("power-btn").disabled = false;
        }
 
        function nextRound() {
            addToSequence();
            playSequence();
        }
 
        function addToSequence() {
            const randomColor = Math.floor(Math.random() * 4) + 1;
            sequence.push(randomColor);
        }
 
        function playSequence() {
            let i = 0;
            const intervalId = setInterval(() => {
                highlightButton(sequence[i]);
                i++;
                if (i >= sequence.length) {
                    clearInterval(intervalId);
                    enableButtons();
                }
            }, 1000);
        }
 
        function handleClick(button) {
            if (powerOn) {
                const userColor = button.getAttribute("data-color");
                userSequence.push(Number(userColor));
                highlightButton(userColor);
                if (!checkSequence()) {
                    if (strictMode) {
                        alert(`Game over! Press Start to retry
                        from level 1.\nFINAL SCORE: ${level}`);
                        togglePower();
                        startGame();
                    } else {
                        alert(`Wrong sequence! Press Start to try again
                         from current level.\nFINAL SCORE: ${level}`);
                        userSequence = [];
                        document.getElementById('power-btn')
                        .addEventListener('click', () => {
                            playSequence();
                        })
                    }
                } else if (userSequence.length === sequence.length) {
                    userSequence = [];
                    level++;
                    levelCount.textContent = level;
                    /*Can change level as per convenience or if we want the game to
                    continue indefinitely, can omit if-else condition */
                    if (level <= 20) {
                        setTimeout(() => nextRound(), 1000);
                    } else {
                        alert("Congratulations! You won!");
                        startGame();
                    }
                }
            }
        }
 
        function checkSequence() {
            for (let i = 0; i < userSequence.length; i++) {
                if (userSequence[i] !== sequence[i]) {
                    return false;
                }
            }
            return true;
        }
 
        function highlightButton(color) {
            const button = document
            .querySelector(`[data-color="${color}"]`);
            if (Number(color) == 1) {
                button.style.backgroundColor = 'lightgreen'
            }
            else if (Number(color) == 2) {
                button.style.backgroundColor = 'tomato'
            }
            else if (Number(color) == 3) {
                button.style.backgroundColor = 'yellow'
            }
            else if (Number(color) == 4) {
                button.style.backgroundColor = 'lightskyblue'
            }
            setTimeout(() => {
                button.attributes.removeNamedItem('style');
            }, 300);
        }
 
        function enableButtons() {
            const buttons = document
            .querySelectorAll('.simon-btn');
            buttons.forEach(button =>
            button.removeAttribute('disabled'));
        }
 
        function disableButtons() {
            const buttons = document
            .querySelectorAll('.simon-btn');
            buttons.forEach(button =>
            button.setAttribute('disabled', 'true'));
        }
 
        function toggleStrictMode() {
            strictMode = !strictMode;
        }
 
        function togglePower() {
            powerOn = !powerOn;
            if (powerOn) {
                startGame();
                enableButtons();
                document.getElementById("start-btn")
                .disabled = false;
            } else {
                userSequence = [];
                disableButtons();
                document.getElementById("start-btn")
                .disabled = true;
            }
        }
    </script>
</body>
 
</html>


Output:

Final-Animation



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads