css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <button type="button" class="buttons tile unclickable" id="blueBtn" data-tile="1"></button><button type="button" class="buttons tile unclickable" id="lightBtn" data-tile="2"></button><button type="button" class="buttons tile unclickable" id="purpleBtn" data-tile="3"></button><button type="button" class="buttons tile unclickable" id="redBtn" data-tile="4"></button>

<div class="fluid-container">
  <div class="controlsBox">
    <div class="onoffswitch">
      <input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch">
      <label class="onoffswitch-label" for="myonoffswitch">
        <span class="onoffswitch-inner"></span>
        <span class="onoffswitch-switch"></span>
        <div class="test"></div>
      </label>
    </div>
    <h3 class="text-center" id="score">- -</h3><br>
    <div>
      <button type="button" id="strictButton" class="btn btn-danger">Strict</button>
      <label class="LEDoff" id="LED"></label>
    </div><br>
    <div>
      <button type="button" id="reset" class="btn btn-primary btn-block">Reset</button>
    </div>
  </div>
</div>
<div class="sound"></div>
            
          
!
            
              .buttons {
  width: 25%;
  height: 100vh;
  border: none;
  outline: none;
}

.onoffswitch {
  position: relative;
  width: 90px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}

.onoffswitch-checkbox {
  display: none;
}

.onoffswitch-label {
  display: block;
  overflow: hidden;
  cursor: pointer;
  border-radius: 20px;
}

.onoffswitch-inner {
  display: block;
  width: 200%;
  margin-left: -100%;
  transition: margin 0.3s ease-in 0s;
}

.onoffswitch-inner:before,
.onoffswitch-inner:after {
  display: block;
  float: left;
  width: 50%;
  height: 30px;
  padding: 0;
  line-height: 30px;
  font-size: 14px;
  color: white;
  font-family: Trebuchet, Arial, sans-serif;
  font-weight: bold;
  box-sizing: border-box;
}

.onoffswitch-inner:before {
  content: "ON";
  padding-left: 10px;
  background-color: #34A7C1;
  color: #FFFFFF;
}

.onoffswitch-inner:after {
  content: "OFF";
  padding-right: 10px;
  background-color: #EEEEEE;
  color: #999999;
  text-align: right;
}

.onoffswitch-switch {
  display: block;
  width: 18px;
  margin: 6px;
  background: #FFFFFF;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 56px;
  border: 2px solid #999999;
  border-radius: 20px;
  transition: all 0.3s ease-in 0s;
}

.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
  margin-left: 0;
}

.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
  right: 0px;
}

.controlsBox {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

#redBtn {
  background: #F24B4B;
}

#lightBtn {
  background: #60BFBF;
}

#blueBtn {
  background: #244F75;
}

#purpleBtn {
  background: #8C4B7E;
}

#strictButton {
  min-width: 30px;
  margin-top: -10px;
  /* temp solution to the light not centering problem*/
  outline: none;
}

.LEDoff {
  margin-bottom: 0;
  width: 20px;
  height: 20px;
  background-color: #181B1C;
  border-radius: 50%;
  border: 3px solid grey;
}

.LED-on {
  background-color: #DB0B27;
}

.clickable {
  pointer-events: auto;
  cursor: pointer;
}

.unclickable {
  pointer-events: none;
}

.tile {
  opacity: 1;
  -webkit-transition: opacity 250ms ease;
  -moz-transition: opacity 250ms ease;
  -ms-transition: opacity 250ms ease;
  -o-transition: opacity 250ms ease;
  transition: opacity 250ms ease;
}

.tile.lit {
  opacity: .6;
}

#score {
  min-width: 30px;
  min-height: 30px;
  padding-top: 30px;
  padding-bottom: 30px;
  border-radius: 20px;
  background-color: #A1D490;
  transition: color 50ms ease;
  font-family: "Comic Sans MS", cursive, sans-serif;
}

#score.blink {
  color: transparent;
}

#reset {  
  outline: none;
}
            
          
!
            
              var compSequence = []; 
var userSequence = [];
var tempCompSequence = []; //If user presses wrong tile and is not playing with "Strict" rule
var anime; //Variable to store animate interval ID so that it can be stopped when the reset or off button is pressed

$("#strictButton").on("click", function() {
  $("#LED").toggleClass("LED-on");
});

$("#myonoffswitch").on("click", function() { //When the on switch is checked
  if ($(this).is(":checked")) { //If it's set on 
    computerTurn(); //Computer starts by his turn
    gameOn();
  } else if ($(this).is(":not(:checked)")) { //When the switch is set to off, turn off the entire thing
    gameOff();
  }
});

$("#reset").on("click", function() { //Will set the board up for a new game
  clearInterval(anime); //Stop computer from animating any further if reset is pressed
  initGame();
});

var initGame = function() { //Set a new game in motion
  compSequence = [];
  userSequence = [];
  $('#score').text('- -');
  gameOn();
  computerTurn();
};

var disableBoard = function() { //Makes the tiles unclickable for the user
  $(".buttons").removeClass("clickable").addClass("unclickable");
};

var enableBoard = function() { //Makes the tiles clickable for the user
  $(".buttons").removeClass("unclickable").addClass("clickable");
};

var gameOn = function() { //When the on check box has been check, i.e. turn on button
  $("#reset").removeClass("unclickable").addClass("clickable");
  $("#strictButton").removeClass("unclickable").addClass("clickable");
};

var gameOff = function() { //When the off key is pressed. More like when the checkbox is unchecked.
  $("#LED").removeClass("LED-on");
  $('#score').text('- -');
  $(".buttons").addClass("unclickable");
  $("#reset").addClass("unclickable");
  $("#strictButton").addClass("unclickable");
  clearInterval(anime); //Stop computer from animating any further if off button is pressed
  compSequence = [];
  userSequence = [];
};

$(".buttons").on("mousedown", function() {
  var a = parseInt($(this).attr("data-tile"));   //Light up the tile that the user pressed
  lightUp(a);
}).on("mouseup", function() {
  var a = parseInt($(this).attr("data-tile"));  //Check if the user pressed the key in order
  userPress(a);
});

function userPress(bNumber) { //When it's user's turn
  if (compSequence[userSequence.length] === bNumber) {  //Check the last key in the computer array and the last key that the user pressed
    userSequence.push(bNumber); //If it matches, push the tile number onto the user array
    if (compSequence.length === userSequence.length) { //If the user pressed the same amount of keys as in the computer array, move ahead
      if (compSequence.length >= 20) {  //Did the user get it right the winning number of times?
        $("#score").text("You win !"); //Yes he/she did. Reset the game after 2 seconds.
        disableBoard();
        setTimeout(function() {
          initGame();
        }, 2000);
      } else { //The game is still not over. User is done pressing tiles. Now it's computer's turn.
        userSequence = [];
        computerTurn();
      }
    }
  } else { //If the user presses a wrong key, i.e. in wrong order
    if ($("#LED").hasClass("LED-on")) {  //If the strict key is on
      disableBoard();
      var flash = setInterval(function() {  //Indicate the wrong press by blinking the score 
        $("#score").text("!!").toggleClass("blink");
      }, 300);
      setTimeout(function() { //And reset the game
        $("#score").removeClass("blink");
        clearInterval(flash);
        initGame();
      }, 2000);
    }
    else{ //If the strict light is off, let the user continue and keep trying until he/she gets it right.
      $("body").effect("shake"); //Indicate the wrong press by shaking the whole body
      userSequence = [];
      clearInterval(anime); //If the user repeatedly clicks the tiles while the computer is animating, stop the previous animation and restart the same sequence
      setTimeout(function(){
        animate(tempCompSequence); //Repeat the sequence that the user just got wrong after 100ms
      }, 100);      
    }
  }
};

function computerTurn() { //Computer's turn
  disableBoard();
  compSequence.push(Math.floor(Math.random() * (4 - 1) + 1)); //Any tile between 1 and 4
  $("#score").text(compSequence.length); //Round number 
  animate(compSequence); //Animate the current computer sequence
  tempCompSequence = compSequence; //Check line number three from the top
};

function animate(seq) {
  var i = 0;
  disableBoard();//Disable the board so that the user cannot click while computer is taking it's turn
  anime = setInterval(function() { //Lights up tiles after 600 ms
    lightUp(seq[i]); //Light up the current tile
    i++;
    if (i >= seq.length){               
      setTimeout(function(){ //Enable the user to register his clicks after 1/2 second
        enableBoard()
      }, 500);
      clearInterval(anime); //If all the tiles in the sequence have been lit, then stop. 
    }
  }, 600);
};

function lightUp(tile) { //Light up the tiles
  var tileUp = $("[data-tile=" + tile + "]").addClass("lit");
  playSound(tile);
  setTimeout(function() { //Tiles light up for 300 ms
    tileUp.removeClass("lit");
  }, 300);
};

function playSound(tileNumber){ //Play sound according to the tile pressed or animated 
  var audio = $('<audio autoplay></audio>');
  if(tileNumber === 1)
    audio.append('<source src="https://s3.amazonaws.com/freecodecamp/simonSound1.mp3" type="audio/mp3"/>');
  if(tileNumber === 2)
    audio.append('<source src="https://s3.amazonaws.com/freecodecamp/simonSound2.mp3" type="audio/mp3"/>');
  if(tileNumber === 3)
    audio.append('<source src="https://s3.amazonaws.com/freecodecamp/simonSound3.mp3" type="audio/mp3"/>');
  if(tileNumber === 4)
    audio.append('<source src="https://s3.amazonaws.com/freecodecamp/simonSound4.mp3" type="audio/mp3"/>');  
  $('[data-action=sound]').html(audio);
}
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console