<div class='game'>
  <div class='game-container'>
    <div class='game-row top-row'>
      <div class='touch-box' id='box1'>
        <!--<audio id="music" loop src="https://s3.amazonaws.com/freecodecamp/simonSound1.mp3" autoplay> </audio>-->
      </div>
      <div class='touch-box' id='box2'></div>
    </div>
    <div class='game-row middle-row'>
      <div id='control-box'>
        <div id='center-control'>
          <button id='start-text'>START</button>
          <div id='count-box'>0</div>
          <button id='strict-button'>STRICT</button>
        </div>
      </div>
    </div>
    <div class='game-row bottom-row'>
      <div class='touch-box' id='box3'></div>
      <div class='touch-box' id='box4'></div>
    </div>
  </div>
  <div id='bottom-container'>
    <div id='external-controls'></div>
  </div>
</div>
body{
  background: black;
  color: white;
  font-family: 'Verdana', sans-serif;
}
button{
  background: #D3D3D3;
  padding: 2px 4px;
  width: 70px;
  border-radius: 8px;
  border: 2px #454545 solid;
}
button:active{
  border: 2px black solid;
}
.game{
  width: 320px;
  margin: auto;
}
.game-container{
  border: 2px white solid;
  border-radius: 50%;
  margin-top: 20px;
  position: fixed;
}
.game-row{
  display: flex;
}
.touch-box{
  height: 150px;
  width: 150px;
  border: 4px black solid;
}
#control-box{
  background: black;
  height: 148px;
  width: 148px;
  left: 83px;
  top: 83px;
  position: absolute;
  z-index: 1;
  border-radius: 50%;
  border: 1px black solid;
}
#center-control{
  position: absolute;
  width: 120px;
  height: 120px;
  left: 14px;
  top: 14px;
  text-align: center;
  margin-top: 0px;
  font-size: 1.6em;
}
#start-text{
  margin-top: 0px;
  font-size: 0.5em;
  margin-bottom: 0px;
}
#count-box{
  width: 50px;
  margin: auto;
  margin-top: 15px;
  color: red;
  border-radius: 5px;
  background: #2d2d2d;
  box-shadow: 0px 0px 5px red;
}
#strict-button{
  font-size: 0.5em;
  margin-top: 15px;
}
#box1{
  border-top-left-radius: 100%;
  background: green;
}
#box2{
  border-top-right-radius: 100%;
  background: #CC0000;
}
#box3{
  border-bottom-left-radius: 100%;
  background: #DDDD00;
}
#box4{
  border-bottom-right-radius: 100%;
  background: #0000AA;
}

@keyframes box1-light{
  0% { background: #CEFFCE; }
  1% { background: #00FF00; }
  98% { background: #00FF00; }
  100% { background: #008000; }
}
@keygrames box1-glare{
  0% { box-shadow: -5px -5px 10px #00FF00; }
  100% { box-shadow: -5px -5px 10px #00FF00; }
}
@keyframes box2-light{
  0% { background: #FF9999; }
  1% { background: #FF0000; }
  98% { background: #FF0000; }
  100% { background: #CC0000; }
}
@keygrames box2-glare{
  0% { box-shadow: 5px -5px 10px red; }
  100% { box-shadow: 5px -5px 10px red; }
}
@keyframes box3-light{
  0% { background: #FFFFAA; }
  1% { background: #FFFF00; }
  98% { background: #FFFF00; }
  100% { background: #DDDD00; }
}
@keygrames box3-glare{
  0% { box-shadow: -5px 5px 10px #FFFF00; }
  100% { box-shadow: -5px 5px 10px #FFFF00; }
}
@keyframes box4-light{
  0% { background: #CCE2FF; }
  1% { background: #0000FF; }
  98% { background: #0000FF; }
  100% { background: #0000AA; }
}
@keygrames box4-glare{
  0% { box-shadow: 5px 5px 10px #0000FF; }
  100% { box-shadow: 5px 5px 10px #0000FF; }
}
// LOAD SOUND FILES
var audio1 = new Audio('https://s3.amazonaws.com/freecodecamp/simonSound1.mp3');
var audio2 = new Audio('https://s3.amazonaws.com/freecodecamp/simonSound2.mp3');
var audio3 = new Audio('https://s3.amazonaws.com/freecodecamp/simonSound3.mp3');
var audio4 = new Audio('https://s3.amazonaws.com/freecodecamp/simonSound4.mp3');
// GLOBALS FOR START, STOP AND TIMING OF GAME
var strictButtonAtStart = false;
var gameList = [];
var game = null;
var counter = 0;
var playID = null;
var playing = false;
var buttonCounter = 0;
var gameState = false;

// MAKE SOUND FUNCTIONS NOW TO CUT DOWN ON TIMING CODE
function playSound1(){
    audio1.play();
}
function playSound2(){
    audio2.play();
}
function playSound3(){
    audio3.play();
}
function playSound4(){
    audio4.play();
}

// STRICT BUTTON FUNCTION
function strictButton(){
    strictButtonAtStart = !strictButtonAtStart;
    console.log('STRICT BUTTON: ', strictButtonAtStart);
    if (strictButtonAtStart){
        this.style.background = 'yellow';
    } else { this.style.background = '#D3D3D3';}
}

// START BUTTON FUNCTION; BECOMES A STOP BUTTON FOR STOPPING AND RESETTING GAME
function startNewGame(){
    if (!gameState){
        gameState=true;
        gameList.unshift(new SimonGame);
        game = gameList[0];
        if (gameList.length>1){
            gameList.pop();
        }
        this.innerHTML = 'STOP';
        game.init();
    } else {
        gameState=false;
        this.innerHTML = 'START';
        document.getElementById('strict-button').addEventListener('click', strictButton);
    }
}
// TIME CODE FOR PLAYING A SINGLE BUTTON
function playThisButton(){
    if (counter<game.aiSequence.length){
        if (!gameState){
            clearInterval(playID);
        }
        game.lightSoundAnimate(game.aiSequence[counter]);
        counter++;
        game.progressCount();
    } else {
        clearInterval(playID);
        playing = false;
        game.setButtons();
        game.aiWaitClick();
    }
}
// INITIALIZATION CODE FOR PLAYING BUTTON SEQUENCE
function playAllButtons(){
    if (!playing && gameState){
        playing = true;
        game.stopButtons();
        window.setTimeout(function(){

            counter = 0;
            playID = setInterval(playThisButton, 900);
        }, 500);

    }

}
// PENALIZE PLAYER FOR TAKING TOO LONG
function timeOutPenalty(){
    game.stopButtons();
    console.log('TIME EXPIRED');
    game.uxSequence.splice(0);
    game.failNotify();
    if (game.strict){
        game.aiSequence.splice(0);
        game.aiAddButton();
    }
    playAllButtons();
}
// ORDER OF CHECKS FOR SELECTED BUTTON; DON'T ALLOW BUTTON SELECTION WHILE PLAYING THE SEQUENCE
function playerTurnPress(){
    if (!playing && gameState){
        window.clearTimeout(game.clickClock);
        game.lightSoundAnimate(this.id);
        if (this.id != game.aiSequence[game.uxSequence.length]){
            game.failNotify();
            game.uxSequence.splice(0);
            if (!game.strict){
                playAllButtons();
            } else {
                game.aiSequence.splice(0);
                game.aiAddButton();
                playAllButtons();
            }
        } else {
            game.uxSequence.push(this.id);
            if (game.uxSequence.length == game.aiSequence.length){
                if (game.aiSequence.length === 20){
                    game.winNotify();
                    document.getElementById('start-text').click();
                }
                game.aiAddButton();
                playAllButtons();
                game.uxSequence.splice(0);
            } else {
                game.aiWaitClick();
            }
        }
    }
}

// CLASS FOR GAME; CONTAINS GAME VARIABLES AND FUNCTIONS
class SimonGame{
    constructor(){
      // MAKE A LIBRARY/ OBJECT CONTAINING ATTRIBUTES UNIQUE FOR EACH BUTTON
        this.quadLib = {
            'box1': ['#00FF00', '#008000', '-3px -3px 10px #00FF00', audio1],
            'box2': ['#FF0000', '#CC0000', '3px -3px 10px #FF0000', audio2],
            'box3': ['#FFFF00', '#DDDD00', '-3px 3px 10px #FFFF00', audio3],
            'box4': ['#0000FF', '#0000AA', '3px 3px 10px #0000FF', audio4]
        };
      // SET UP GAME VARIABLES
        this.quadrants = null;
        this.strict = null;
        this.clickClock = null;
        this.allowMouseClick = null;
        this.aiSequence = [];
        this.uxSequence = [];
        this.t=-1;
    }
// EVENTS FOR EACH BUTTON ANIMATION
    lightSoundAnimate(quadrant){
        document.getElementById(quadrant).style.background = this.quadLib[quadrant][0];
        document.getElementById('control-box').style.boxShadow = this.quadLib[quadrant][2];
        this.quadLib[quadrant][3].play();
        var shadow = this.quadLib[quadrant][1];
        window.setTimeout(function(){
            document.getElementById(quadrant).style.background = shadow;
            document.getElementById('control-box').style.boxShadow = 'none';
        }, 750);
    }
  // START LISTENING FOR CLICKS
    setButtons(){
        this.quadrants.forEach(function(e){
            e.addEventListener('click', playerTurnPress);
        });
    }
  // STOP LISTENING FOR CLICKS
    stopButtons(){
        this.quadrants.forEach(function(e){
            e.removeEventListener('click', playerTurnPress, false);
        });
    }
  // TIME LIMIT FOR PLAYER BUTTON CHOICE
    aiWaitClick(){
        if (gameState){
            this.clickClock = window.setTimeout(timeOutPenalty, 5000);
        }
    }
  // ADD A BUTTON TO SEQUENCE
    aiAddButton(){
        this.aiSequence.push(this.quadrants[Math.floor(Math.random()*4)].id);
    }
  // ADVANCE THE COUNTER
    progressCount(){
        document.getElementById('count-box').innerHTML = this.aiSequence.length;
    }
  // NOTIFY THE PLAYER OF A WIN
    winNotify(){
        document.getElementById('count-box').innerHTML = ": D";
        window.setTimeout(playSound3, 200);
        window.setTimeout(playSound2, 350);
        window.setTimeout(playSound1, 700);
    }
  // NOTIFY THE PLAYER OF INCORRECT BUTTON CHOICE
    failNotify(){
        document.getElementById('count-box').innerHTML = ": (";
        window.setTimeout(playSound4, 200)
        window.setTimeout(playSound3, 450);
    }
// INITIALIZE GAME 
    init(){
        this.strict = strictButtonAtStart;
        document.getElementById('strict-button').removeEventListener('click', strictButton, false);
        this.quadrants = [
            document.getElementById('box1'),
            document.getElementById('box2'),
            document.getElementById('box3'),
            document.getElementById('box4')
        ];
        this.aiAddButton();
        playAllButtons();
        this.allowMouseClick = true;
        this.setButtons();
    }
}

// SET UP GAME AFTER DOM LOADED
document.addEventListener('DOMContentLoaded', function(){
    document.getElementById('strict-button').addEventListener('click', strictButton);
    document.getElementById('start-text').addEventListener('click', startNewGame);
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.