Pen Settings

HTML

CSS

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. You can use the CSS from another Pen by using it's URL and the proper URL extention.

+ add another resource

JavaScript

Babel includes JSX processing.

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

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

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.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                
<!-- <h1>{value}</h1> -->

<!--     <button onClick={onIncrement}>+</button>
    <button onClick={onDecrement}>-</button> -->

<!-- Family feud-buzzer.mp3 -->
<!-- 
  let url = "http://media.petervann.com/webs/fcc/projects/simon-game/sounds/Bing-sound.mp3";
  let audio = new Audio(url);
  audio.play();
-->

<!--
<audio id="bing" autoplay>
  <source src="https://media.petervann.com/webs/fcc/projects/simon-game/sounds/bing.wav" type="audio/wav">
  <source  src="https://media.petervann.com/webs/fcc/projects/simon-game/sounds/bing.ogg" type="audio/ogg">
  <source  src="https://media.petervann.com/webs/fcc/projects/simon-game/sounds/bing.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>

<audio id="bing" autoplay>
  <source src="https://media.petervann.com/webs/fcc/projects/simon-game/sounds/buzzer.wav" type="audio/wav">
  <source  src="https://media.petervann.com/webs/fcc/projects/simon-game/sounds/buzzer.ogg" type="audio/ogg">
  <source  src="https://media.petervann.com/webs/fcc/projects/simon-game/sounds/buzzer.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>

-->

<!--
    <button onClick={onRight}>Correct</button>
    <button onClick={onWrong}>Not</button>
-->
              
            
!

CSS

              
                @import url(https://fonts.googleapis.com/css?family=Bevan);

@import url(https://fonts.googleapis.com/css?family=Black+Han+Sans);

@import url(https://fonts.googleapis.com/css?family=Electrolize);

p {
  font-family: Verdana;
  font-weight: bold;
  font-size: 40px;
}

html, 
body{
  height: 98%;
}

body{
  font: 20px 'Electrolize', sans-serif;
      //background-image: url("https://static.codepen.io/assets/logos/codepen-logo-pattern-725360e4ce5b66f968c7f39c80999bdeaa3cbe2f18eac75d58b01f8cf55c26ab.png");
  background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/autograph-tile.png");
  background-repeat: repeat;
  background-color: #333;
  color: lime;
  display: flex;
  justify-content: center;
  align-items: center;    
}

.game{
  margin-top: 10px;
  background: #fff;
  text-align: center;
  padding: 20px;
  width: 480px;
  height: 480px;
  border-radius: 5px;

  button {
    position: relative;
    left: -50px;
    color: #fff;
    background-color: #00aeef;
    margin: .2em;
    padding: 0.5em;    
    font-size: 120%;
    min-width: 3em;
    border: 0px;
    cursor: pointer;
  }  
}

main {
  width: 100%;
  height: 355px;
  background-color: rgba(3,22,28,255);
  border-radius: 3px;
}

#main-top {
  display: flex;
  flex-wrap: nowrap;
  width: 100%;
  height: 50%;
}

#main-bottom {
  display: flex;
  flex-wrap: nowrap;
  width: 100%;
  height: 50%; 
}

.one {
  flex: 1;
  //border: 1px solid lime;
}

.two {
  flex: 2;
  //border: 1px solid lime;
}

.center {
  display: flex;
  justify-content: center;
}

header{
  margin-top: -25px;
  height: 120px;
}

#top-half {
  margin-top: 30px;
  display: flex;
  height: 50px;
}

#bottom-half {
  height: 65px;
  display: flex;
  border: 1px solid #808080;
  border-radius: 3px;
}

#level {
  margin-top: -3px;
  margin-left: 0px;
  width: 50px;
  height: 25px;
  color: #00aeef;
  background-color: #19191b;
  font: 20px 'Electrolize', sans-serif;
  font-weight: bold;
  border: 1px solid #00aeef;
  border-radius: 7px;
  padding: 7px;
}

#stereo-container {
  display: flex;
  justify-content: space-around;
  width: 330px;
  margin: 10px;
  border-bottom: 1px solid #808080;
  color: black;
  font-size: 16px;
}

#stereo {
  width: 80px;
  height: 30px;
  margin-top: -1px;
  background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/stereo.png");
}

h1 {
  position: absolute;
  top: 10px;
}

.btn-row {
  display: flex;
}

.glow {
  color: #00aeef;
}

#rgt {
  position: relative;
  left: -12px;
}

#off-on-container {
  margin-top: -6px;
}

#off-on-label {
  color: black;
  font-size: 12px;
}

#playCol {
  display: flex;
  flex-direction: column;
}

#play {
  font-family: 'Black Han Sans', sans-serif;
  color: #00aeef;
  margin-top: 5px;
  margin-bottom: 0px;
  padding-left: 10px;
}

#speed {
  display: none;
  font: 14px 'Electrolize', sans-serif;
  margin-left: 10px;
  margin-top: -4px;
  width: 80px;
  height: 20px;
  color: #fff;
  background-color: #333;
  border: 1px solid #00aeef;
  border-radius: 3px;
}

#logo {
  width: 270px;
  height: 56px;
  //background-color: lime;
  margin: 5px 20px;
  background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/logo.png");
}

#autograph {
  width: 61px;
  height: 60px;
  margin-top: 3px;
  margin-left: 14px;
  background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/autograph.png");
}

.tile {
  //background-color: rgba(70, 70, 20, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  width: 135px;
  height: 175px;
}

.gameTile {
  //background-color: rgba(70, 70, 20, 0.5);
  border-radius: 45px;
  cursor: pointer;
}

#result {
  //background-color: rgba(70, 70, 20, 0.5);
  width: 135px;
  height: 175px;
}

.CLEAR {
  //background-image: url("");
  //background-repeat: no-repeat;
  //background-position: center;
}

.RIGHT {
   background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/green-check-100.png");
  background-repeat: no-repeat;
  background-position: center;
}

.WRONG {
   background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/x-100.png");
  background-repeat: no-repeat;
  background-position: center;
}

.TIME {
   background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/times-up.png");
  background-repeat: no-repeat;
  background-position: center;
}

#logos {
  position: relative;
  top: 5px;
  left: 3px;
}

#ai {
  width: 60px;
  height: 40px;
  background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/american-idol-logo.png");
}

#xf {
  width: 60px;
  height: 47px;
  background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/xf-ai-blue.png");
}

#cartoon {
  position: relative;
  top: 7px;
  margin-left: -34px;
  width: 119px;
  height: 170px;
  background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/cartoon-simon.png");
  cursor: pointer;
}



/* ======= SWITCH ======== */
$light-grey: #cccccc;
$dark-grey: #333333;
$light-blue: #80ddff;
$dark-blue: #00aeef;

@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.switch {
  position: relative;
  display: inline-block;
  width: 64px;
  height: 30px;
  
  input {
    display: none;
  }
}

.slider, .slider::before {
  position: absolute;
  left: -1px;
}

.slider {
  cursor: pointer;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: $light-grey;
  -webkit-transition: .1s;
  transition: .1s;

  &::before {
    content: "";
    height: 29px;
    width: 29px;
    bottom: 0px;
    background-color: $dark-grey;
    -webkit-transition: .1s;
    transition: .1s;
  }
}

.slider.circular {
  border-radius: 15px;
  &::before {
    border-radius: 50%;
  }
}

input {
  &:checked + .slider {
    background-color: $light-blue;
  }
// CAUSES A GENERAL ERROR  
  // &:focus + .slider {
  //   box-shadow: 0 0 1px $light-blue;
  // }
}

input:checked + .slider:before {
  background-color: $dark-blue;
  -webkit-transform: translateX(35px);
  -ms-transform: translateX(35px);
  transform: translateX(35px)
}


/* ========  Buttons  ======== */
.round {
  position: relative;
  top: -3px;
  left: 5px;
}

.round label {
  background-color: #19191b;
  border: 2px solid #00aeef;
  border-radius: 50%;
  cursor: pointer;
  height: 20px;
  left: 0;
  position: absolute;
  top: 0;
  width: 20px;
  .OFF {
    border: 2px solid #333333 !important;
  }
}

.round label:after {
  border: 2px solid #fff;
  border-top: none;
  border-right: none;
  content: "";
  height: 3px;
  left: 4px;
  opacity: 0;
  position: absolute;
  top: 7px;
  transform: rotate(-45deg);
  width: 10px;
}

.btn-row > .round label:after {
  border: 2px solid #fff;
  border-top: none;
  border-right: none;
  content: "";
  height: 3px;
  left: 4px;
  opacity: 0;
  position: absolute;
  top: 7px;
  transform: rotate(-45deg);
  width: 10px;
}

.round input[type="checkbox"] {
  visibility: hidden;
}

.round input[type="checkbox"]:checked + label {
  background-color: #00aaef;
  border-color: #333333;
}

.round input[type="checkbox"]:checked + label:after {
  opacity: 1;
}


/********** MEDIA QUERIES **********/

@media (max-width: 800px) {

  .game{
    margin-top: 10px;
    padding: 10px;
    width: 280px;
    height: 400px; 
  }
  
  main {
    height: 275px;
  }

  #main-top {
    display: flex;
    flex-wrap: nowrap;
    width: 100%;
    height: 50%;
  }

  #main-bottom {
    display: flex;
    flex-wrap: nowrap;
    width: 100%;
    height: 50%; 
  }
  
  #bottom-half {
    height: 65px;
    display: flex;
    border: none;
    border-radius: 3px;
  }
  
  .tile {
    //background-color: rgba(70, 70, 20, 0.5);
    display: flex;
    justify-content: center;
    align-items: center;
    width: 92px;
    height: 130px;
    img {
      width: 80px;
    }
    img#randy {
      width: 92px;
    }
  }
  
  #result {
    //background-color: rgba(70, 70, 20, 0.5);
    margin-left: -50px;
    width: 120px;
    height: 130px;
  }
  
  #logo {
    max-width: 280px;
    height: 53px;
    //background-color: lime;
    margin: 5px;
    background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/logo.png");
  }
  
  #stereo,
  #playCol,
  #autograph,
  #logos {
    display: none;
    position: absolute;
    top: 0px;
    left: 0px;
  }
  
  #lft {
    position: relative;
    left: -8px;
  }
  
  #rgt {
    position: relative;
    left: -2px;
  }
  
  #cartoon {
    display: none;
    position: relative;
    top: 7px;
    margin-left: -34px;
    width: 119px;
    height: 170px;
    background-image: url("https://media.petervann.com/webs/fcc/projects/simon-game/img/cartoon-simon.png");
    cursor: pointer;
  }
  
  
} // END 800px MQ





              
            
!

JS

              
                // CONSTANTS 
const UNDEFINED = 'UNDEFINED';
const NADA = '';
const YES = 'YES';
const NO = 'NO';
const ON = 'ON';
const OFF = 'OFF';
const SPEED = 'SPEED';
const SLOW = '1000';
const MED = '750';
const FAST = '500';
const TIME_LIMIT = 4500;
const TIME_OUT_LOOP_MAX = 8;
const KILL = 'KILL';
const SIMON = 'simon';
const PLAYER = 'PLAYER';
const MOVE = 'MOVE';
const LOG = 'LOG';
const LEVEL = 'LEVEL';
const RESET = 'RESET';
const TIMED_OUT = 'TIMED_OUT';
const BLACKED_OUT = 'BLACKED_OUT';
const RESET_OUTCOME = 'RESET_OUTCOME';
const PAULA = 'paula';
const RANDY = 'randy';
const J_LO = 'j-lo';
const RYAN = 'ryan';
const PANEL = [
  PAULA,
  RANDY,
  J_LO,
  RYAN
];
const POWER = 'POWER';
const GLOW = 'glow';
const START = 'START';
const STRICT = 'STRICT';
const CLEAR = 'CLEAR';
const END_REPEAT = 'END_REPEAT';
const RIGHT = 'RIGHT';
const WRONG = 'WRONG';
const TIME = 'TIME';
const TIMER = 'TIMER';
const SOUNDS = {
    paula: new Audio("https://s3.amazonaws.com/freecodecamp/simonSound1.mp3"),
    randy: new Audio("https://s3.amazonaws.com/freecodecamp/simonSound4.mp3"),
    j_lo: new Audio("https://s3.amazonaws.com/freecodecamp/simonSound2.mp3"),
    ryan: new Audio ("https://s3.amazonaws.com/freecodecamp/simonSound3.mp3"),
    bing: new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/bing.mp3"),
    buzzer: new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/buzzer.mp3"),
    timer: new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/times-up.mp3"),
    click_on: new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/click-on.mp3"),
    click_off: new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/click-off.mp3"),
    ai_intro: new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/american-idol-intro.mp3"),
    simon_stop: new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-bored.mp3"),
    simon_intro: new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-intro.mp3"),
    simon: [
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-who.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-good.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-hello.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-chance.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-moments.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-problem.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-whatdat.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-fabulously.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-mediocre.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-thankyou.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-cher.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-deluded.mp3"),
        new Audio ("https://media.petervann.com/webs/fcc/projects/simon-game/sounds/simon-horrific.mp3")
  ] // SIMON ARRAY
};

// ACTIONS

// REDUCER
const advanceLevel = (level) => {
  return (level === '--') ? 1 : ++level;  
}

const gameReducer = (
  state = {
    player: SIMON,
    speed: SLOW,
    moves: 0,
    moveHistory: [],
    beats: 0,
    echos: 0,
    echoHistory: [],
    outcome: 0,
    reset: false,
    timers: [],
    repeat: false,
    paula: NADA,
    randy: NADA,
    j_lo: NADA,
    ryan: NADA,
    power: OFF,
    level: NADA,
    lastLevel: 0,
    start: NO,
    strict: NO,
    startChecked: false,
    strictChecked: false,
    startDisabled: true,
    strictDisabled: true,
    speedDisabled: true,
    glow: NADA
  }, action) => {
  
  var {
    player, speed, reset,
    level, lastLevel,
    moves, moveHistory,
    echos, echoHistory,
    beats, outcome, repeat, timers,
    paula, randy, j_lo, ryan,  
    power, glow,
    startDisabled, strictDisabled, speedDisabled,
    start, strict, startChecked, strictChecked
  } = state;
  
  console.log("Action: " + action.type);
  if (action.payload) {
    console.log("Payload: " + action.payload);
  }
  //console.log("Player: " + player);

  var echoMove = (actType) => {
    if (player === PLAYER) {
      console.log('');
      console.log('START echoMove');
      console.log('Player in move: ' + player);
      console.log('Moves: ' + moves);
      console.log('Echos: ' + echos);
      console.log('Echo: ' + actType);
      // if (moveHistory.length === echoHistory.length) {
      //   return;  // ###### BAIL #####
      // }
      
      //outcome = 0;
      
      console.log('MHL: ' + moveHistory.length);
      console.log('EHL: ' + echoHistory.length);

      // if (moveHistory.length !== echoHistory.length) {
        ++beats;
        console.log('Beats: ' + beats);
        if (beats-1 === echoHistory.length) {
          echoHistory = [...echoHistory, actType];
          ++echos;
        }
      // }
      console.log('MoveHistory: ' + moveHistory);
      console.log('EchoHistory: ' + echoHistory);
      outcome = 0;
      for(let i = 0; i < echoHistory.length; i++) {  // GO THROUGH SMALLER ARRAY
        if (echoHistory[i] !== moveHistory[i]) {
         outcome = -1;
        }
      }

      if (echoHistory.length === moveHistory.length  && outcome === 0) {
       outcome = 1;
      }
      console.log('Outcome: ' + outcome);
    }
    
    console.log('START echoMove');
    console.log('');
    
  } // END ECHOMOVE
  
//====================================================  
//==================  LOG STATE ======================
//====================================================  
  const logState = (state, actionType = false) => {
    if (actionType) {
      console.log('');
      console.log(`${actionType}_STATE:`);
      console.log('============');
      Object.keys(state).map((key, index) => {
        console.log(`${index}) ${key}:${state[key]}`);
      });
      console.log('============');
      console.log(''); 
    }

    return {
      ...state
    }
  }
//====================================================
//==================================================== 
//====================================================   
  
 
  switch (action.type) {
    case PLAYER:
      //console.log('Player is: ' + player);
      player = (player === PLAYER) ? SIMON : PLAYER;
      //console.log('Player is: ' + player);
      beats = 0;
      return logState({
        ...state,
        player: player,
        beats: beats
      });
      
    case SPEED:
      const NEW_SPEED = action.payload;
      console.log(`NEW_SPEED:${NEW_SPEED}`);
      if (NEW_SPEED === 'SLOW') {
        speed = SLOW;
        console.log(`SLOW:${speed}`);
      }
      if (NEW_SPEED === 'MED') {
        speed = MED;
        console.log(`MED:${speed}`);
      }
      if (NEW_SPEED === 'FAST') {
        speed = FAST;
        console.log(`FAST:${speed}`);
      }
      return logState({
        ...state,
        speed: speed
      }, action.type);
      
    case MOVE:
      return logState({
        ...state,
        moves: ++moves
      });
      
    case LOG:
      reset: false;
      moveHistory = [...moveHistory, action.payload];
      echoHistory = [];
      console.log('New logged hist: ' + moveHistory);
      console.log('Old echoed hist: ' + echoHistory);
      return logState({
        ...state,
        moveHistory: moveHistory,
        echoHistory: echoHistory,
        reset: reset
      });
     
    case END_REPEAT:
      repeat = false;
      return logState( {
       ...state,
       repeat: repeat
      });
     
      case RESET:
        reset = true,
        player = SIMON;
        beats = 0;
        echoHistory = [];
        console.log('Strict: ' + strict);
        console.log('Reset: ' + reset);
        if (strict === YES) {
          echos = 0;
          level = '--';
          lastLevel = 0;
          moves = 0;
          moveHistory = [];
          repeat = false;
        } else {
          console.log('Echos: ' + echos);
          console.log('MHL: ' + moveHistory.length);
          console.log('Level: ' + level);
          console.log('LastLevel: ' + lastLevel);
          if (level = '! !') {
            level = (lastLevel !== 0) ? lastLevel : '--' ;
          }
          console.log('Level: ' + level);
          console.log('LastLevel: ' + lastLevel);
          // --moves;
          // console.log('Moves in RESET: ' + moves);
          repeat = true;
        }
        return logState({
          ...state,
          player: player,
          moves: moves,
          echos: echos,
          beats: beats,
          level: level,
          lastLevel: lastLevel,
          repeat: repeat,
          echoHistory: echoHistory,
          moveHistory: moveHistory,
          reset: reset
        });
      
    case RESET_OUTCOME:
      outcome = 0;
      return logState({
        ...state,
        outcome: outcome
      });
     
      case TIMED_OUT:
        //console.log('Timed out!');
        level = '! !';
        return logState({
          ...state,
          level: level
        });
     
      case BLACKED_OUT:
        //console.log('Blacked out!');
        level = NADA;
        return logState({
          ...state,
          level: level
        }); 
     
      case PAULA:
        paula = (paula === PAULA) ? SIMON : PAULA;
        //console.log('Paula: ' + paula);
        if (paula === SIMON){
          SOUNDS.paula.play();
        } else {
          echoMove(PAULA);
        }
        return logState({
          ...state,
          paula: paula,
          beats: beats,
          echos: echos,
          echoHistory: echoHistory,
          outcome: outcome 
        });
         
      case RANDY:
        randy = (randy === RANDY) ? SIMON : RANDY;
        //console.log('Randy: ' + randy);
        if (randy === SIMON){
          SOUNDS.j_lo.volume = 0.9;
          SOUNDS.randy.play();
        } else {
          echoMove(RANDY);
        }
        return logState({
          ...state,
          randy: randy,
          beats: beats,
          echos: echos,
          echoHistory: echoHistory,
          outcome: outcome
        });
      
      case J_LO:
        j_lo = (j_lo === J_LO) ? SIMON : J_LO;
        //console.log('J-Lo: ' + j_lo);
        if (j_lo === SIMON){
          //SOUNDS.j_lo.volume = 0.5;
          SOUNDS.j_lo.play();
        } else {
          echoMove(J_LO);
        }
        return logState({
          ...state,
          j_lo: j_lo,
          beats: beats,
          echos: echos,
          echoHistory: echoHistory,
          outcome: outcome
        }, action.type);
      
      case RYAN:
        ryan = (ryan === RYAN) ? SIMON : RYAN;
        //console.log('Ryan: ' + ryan);
        if (ryan === SIMON){
          SOUNDS.ryan.volume = 0.5;
          SOUNDS.ryan.play();
        } else {
          echoMove(RYAN);
        }
        return logState({
          ...state,
          ryan: ryan,
          beats: beats,
          echos: echos,
          echoHistory: echoHistory,
          outcome: outcome
        });
      
      case POWER:
        power = (power === ON) ? OFF : ON;
        level = (level === NADA) ? '--' : NADA;
        startDisabled = !startDisabled; // BOOLEAN
        strictDisabled = !strictDisabled; // BOOLEAN
        speedDisabled = !speedDisabled; // BOOLEAN
        glow = (glow === GLOW) ? NADA : GLOW;
        repeat = false;
        //const SOUND = SOUNDS.simon[Math.floor(Math.random() * 7)];
        if (power === ON) {
          //SOUND.play();
          SOUNDS.ai_intro.play();
          player = SIMON;
          paula = PAULA;
          randy = RANDY;
          j_lo = J_LO;
          ryan = RYAN;
        } else {
          paula = NADA;
          randy = NADA;
          j_lo = NADA;
          ryan = NADA;
          start = NO;
          strict = NO;
          startChecked = false;
          strictChecked = false;
          moves = 0;
          echos = 0;
          moveHistory = [];
          echoHistory = [];
          level = NADA;
          lastLevel = 0;
          SOUNDS.simon_stop.play();
        }
        return logState({
          ...state,
          paula: paula,
          randy: randy,
          j_lo: j_lo,
          ryan: ryan,
          power: power,
          level: level,
          start: start,
          strict: strict,
          startChecked: startChecked,
          strictChecked: strictChecked,
          startDisabled: startDisabled,
          strictDisabled: strictDisabled,
          speedDisabled: speedDisabled,
          glow: glow,
          moves: moves,
          echos: echos,
          moveHistory: moveHistory,
          echoHistory: echoHistory,
          level: level,
          lastLevel: lastLevel,
          repeat: repeat
        });
      
      case START:
        start = (start === YES) ? NO : YES;
        startChecked = !startChecked;
        if (start === YES) {
          SOUNDS.click_on.play();
          player = SIMON;
        } else {
          SOUNDS.click_off.play();
          repeat = true;
          console.log('#####');
          console.log('####');
          console.log('###');
          console.log(level);
          console.log(moveHistory);
          console.log('###');
          console.log('####');
          console.log('#####');
          // if (level === moveHistory.length) {
          //   --level;
          // }
        }
        return logState({
          ...state,
          start: start,
          startChecked: startChecked,
          level: level,
          player: player,
          repeat: repeat
        });
      
      case STRICT:
        strict = (strict === YES) ? NO : YES;
        strictChecked = !strictChecked //BOOLEAN
        if (strict === YES) {
          SOUNDS.click_on.play();
        } else {
          SOUNDS.click_off.play();
        }
        return logState({
          ...state,
          strict: strict,
          strictChecked: strictChecked
        });
      
      case TIMER:
        if (action.payload !== KILL) {
          console.log(`PAYLOAD: ${action.payload}`);
          timers = [ ...timers, action.payload];
          console.log(`Timers in reducer: ${timers}`);
        } else {
          for (timer in timers){
            console.log('CLEARING TIMER...');
            clearTimeout(timer);
          }
          timers = [];
        }
        return {
          ...state,
          timers: timers
        }
      
      case CLEAR:
        return logState({
          ...state,
          result: CLEAR
        });
      case RIGHT:
        console.log('Moves: ' + moves);
        console.log('Echos: ' + echos);
        console.log('Level: ' + level);
        console.log('MHL: ' + moveHistory.length);
        SOUNDS.bing.play();
        lastLevel = (level !== level + '') ? level + 1 : 1;    
        level = advanceLevel(level);
        console.log('LAA: ' + level);
        outcome = 1;
        return logState({
          ...state,
          result: RIGHT,
          level: level,
          lastLevel
        });
      case WRONG:
        SOUNDS.buzzer.play();
        outcome = -1;
        return logState({
          ...state,
          result: WRONG
        });
     case TIME:
        SOUNDS.timer.play();
        outcome = -1;
        return logState({
          ...state,
          result: TIME
        });
      default:
        return logState(state);
      
  }
  
};

// COMBINE REDUCERS
// const { combineReducers } = Redux;
// const rootReducer = combineReducers({
//   gameReducer
// });

const { createStore } = Redux;
const store = createStore(gameReducer);

// COMPONENTS
const Level = (props) => {
  return (
    <div id="level">{props.level}</div>
  )
}


class SpeedSelector extends React.Component {
  
  handleSelectChange = (event) => {
    store.dispatch({
      type: SPEED,
      payload: event.target.value
    });
  }
  
  render() {
    
    const BOOL = this.props.disabled;
    const SLOW_TEXT = (BOOL === false) ? 'Slow' : NADA;
    //console.log(`SLOW_TEXT: ${SLOW_TEXT}`);
    
    return (
      <select
        id="speed"
        onChange={() => this.handleSelectChange(event)}
        disabled={this.props.disabled}
      >
        <option value="SLOW" selected="selected">{SLOW_TEXT}</option>
        <option value="MED">Medium</option>
        <option value="FAST">Fast</option>
      </select>
    )
  }

}


const ControlButton = (props) => {
  return (
    <div id={props.divId} className="btn-row">
      <span className={props.glow}>{props.name}</span>
      <div className="round">
        <input
          type="checkbox"
          id={props.id}
          onChange={() => props.toggle()}
          disabled={props.disabled}
          checked={props.checked}
        />
        <label htmlFor={props.id}></label>
      </div>
    </div>
  )
};

const Stereo = () => {
  return(
    <div id="stereo"></div>
  )
};

const Power = (props) => {
  return (
    <div id="off-on-container">
        <label className="switch">
          <input
            type="checkbox"
            onChange={() => props.toggle()}
          />
          <span className="slider circular"></span>
        </label>
        <div id="off-on-label">
          Off / <span className={props.glow}>On</span> 
        </div>
    </div>
  )
};

const LogoRow = (props) => {
  return (
     <div id="bottom-half">
       <div id="playCol">
         <h2 id="play">PLAY</h2>
         <SpeedSelector
           disabled={props.disabled}
           speedSelector={() => onSelectSpeed()}
         />
       </div>
       <div id="logo"></div>
       <div id="autograph"></div>
    </div>
  )
};

const Tile = (props) => {
  let { name, toggle, player } = props;
  //console.log('Name prop in Tile: ' + name);
  if (name === undefined) {
    name = UNDEFINED;
  };
  
 let src = "https://media.petervann.com/webs/fcc/projects/simon-game/img/" + name + ".png";

  if (name === '') {
    //console.log('Gone!');
    return (
      <div className="tile" >
      </div>
    )
  } else {
    if (props.player === PLAYER) {
       return (
        <div className="tile" >
          <img
            id={name}
            className="gameTile"
            src={src}
            alt={name}
            onClick={() => toggle()}
          />
        </div>
      )
    }
      return (
        <div className="tile" >
          <img
            id={name}
            src={src}
            alt={name}
          />
        </div>
      )
  }
};

const Logos = () => {
  return (
    <div id="logos">
      <div id="ai"></div>
      <div id="xf"></div>
    </div>
  )
}

const Cartoon = (props) => {
  const { click } = props;
  return (
    <div
      id="cartoon"
      onClick={() => click()}
    ></div>
  )
}

const Result = (props) => {
  return (
    <div id="result" className={props.result}></div>
  )
};

const Game = ({
  state,
  onToggleStart,
  onToggleStrict,
  onTogglePower,
  onTogglePaula,
  onToggleRandy,
  onToggleJ_LO,
  onToggleRyan,
  onClear,
  onRight,
  onWrong,
  onTime,
  onSimon
}) => {
  
  console.log("STATE: ", state);  
  
  return (
    <div className='game'>
      <header>
        <div id="top-half">
          <Level level={state.level} />
          <div id="stereo-container">
              <ControlButton
                divId="lft"
                name="Start"
                glow={state.glow}
                id="checkbox1"
                toggle={() => onToggleStart()}
                disabled={state.startDisabled}
                checked={state.startChecked}
              />
              <Stereo />
              <ControlButton
                divId="rgt"
                name="Strict"
                glow={state.glow}
                id="checkbox2"
                toggle={() => onToggleStrict()}
                disabled={state.strictDisabled}
                checked={state.strictChecked}
             />
          </div>
          <Power
            glow={state.glow}
            toggle={() => onTogglePower()}
          />
        </div>
        <LogoRow
          disabled={state.speedDisabled}
        />
      </header>

      <main>
        <div id="main-top">
          <div className="two center">
            <Tile
              name={state.paula}
              toggle={onTogglePaula}
              player={state.player}
            />
          </div>
          <div className="two center">
            <Tile
              name={state.randy}
              toggle={onToggleRandy}
              player={state.player}
            />
          </div>
          <div className="two center">
            <Tile
              name={state.j_lo}
              toggle={onToggleJ_LO}
              player={state.player}
            />
          </div>
          <div className="one">
            <Logos />
          </div>
        </div>
        <div id="main-bottom">
          <div className="one">
            <Cartoon click={onSimon} />
          </div>
          <div className="two center">
            <Result result={state.result} />
          </div>
          <div className="two center">
            <Tile
              name={state.ryan}
              toggle={onToggleRyan}
              player={state.player}
            />
          </div>
        </div>

      </main>

    </div>  
  ); // END RETURN IN GAME
};

const simonSays = () => {
  const SOUND = SOUNDS.simon[Math.floor(Math.random() * 13)];
  SOUND.play();
}

const randPick = () => {
  return PANEL[Math.floor(Math.random() * 4)];
};

const showSimon = (NAME_CONST, speed = 500) => {
  const { player, moveHistory, echoHistory } = store.getState();
  console.log('');
  console.log('');
  console.log('');
  console.log(`PLAYER: ${player}`);
  console.log(`MHL in showSimon: ${moveHistory.length}`);
  console.log(`EHL in showSimon: ${echoHistory.length}`);
  console.log('');
  console.log('');
  console.log('');
  if (player === PLAYER) {
    store.dispatch({
      type: TIMER,
      payload: KILL
    });  // STOP TIMER 
  }

  const { timers } = store.getState();
  console.log(`TIMERS: ${timers}`);
  
  store.dispatch({type: NAME_CONST});// SHOW SIMON
  setTimeout(() => {
    store.dispatch({type: NAME_CONST});// REVERT BACK
    const { outcome, strict } = store.getState();
    if (outcome !== 0) { // RIGHT OR WRONG
      
      setTimeout(() => {
        // SHOW GREEN CHECK OR RED X
        showResult( (outcome === 1) ? RIGHT : WRONG );
        if (outcome === -1) { // WRONG ANSWER
          store.dispatch({type: RESET});
          console.log('*****  RESET  *****');
          console.log('');
        }
        store.dispatch({type: RESET_OUTCOME});
        
        
        // AUTO START =======================================
    console.log(`********************`);
    console.log(`* AUTO AFTER WRONG *`);
    console.log(`********************`);        
        setTimeout(() => {
         autoPlaySimon(false);
        }, speed * 1.5);
        
    console.log(`********************`);
    console.log(`* AUTO AFTER WRONG *`);
    console.log(`********************`);
        // AUTO END =========================================
        
      }, 100);
      
    } else { // NEITHER RIGHT NOR WRONG
      const { echoHistory, player } = store.getState();
      const EHL = echoHistory.length;
      console.log('');
      console.log(`EHL before TIMER: ${EHL}`);
      console.log(`Player before TIMER: ${player}`);
      console.log('');
      if (player === PLAYER) {
        runTimer(EHL);
      }
    }
    
  }, speed);
};

const showResult = (RESULT_CONST, speed = 1000) => {
  store.dispatch({type: RESULT_CONST});
  setTimeout(() => {
    store.dispatch({type: CLEAR});
  }, speed);
};

const runTimer = (max) => {
  const { player } = store.getState();
  console.log(`The player in the timer is ${player}...`);
  
  console.log(`*********************`);
  console.log(`*** TIMER STARTING **`);
  console.log(`*********************`);
  
  const NEW_TIMER = setTimeout(() => {
    console.log(`********************`);
    console.log(`* CHECKING MHL/EHL *`);
    console.log(`********************`);

    const { moveHistory, echoHistory, reset, timers } = store.getState();
    const MHL = moveHistory.length;
    const EHL = echoHistory.length;
    
    console.log('');
    console.log(`MAX: ${max}`);
    console.log(`EHL: ${EHL}`);
    console.log(`MHL: ${MHL}`);
    console.log(`PLAYER: ${player}...`);
    console.log(`RESET: ${reset}...`);
    console.log('');
    
    console.log(`NEW_TIMER: ${NEW_TIMER}`);
    console.log(`TIMERS: ${timers}`);
    console.log('');
    
    if (
            timers.length > 0 && timers.includes(NEW_TIMER)
          // (player === SIMON && EHL === max && reset === false) || 
          // (player === SIMON && EHL !== MHL && reset === false) ||
          // (player === SIMON && EHL === max &&
          //  EHL !== MHL && reset === true) ||
          // (player === PLAYER && EHL === max && EHL !== MHL)
        ) { 

      showResult(TIME, 1200);
      //const SOUND = SOUNDS.simon.timer[Math.floor(Math.random() * 7)];
      // setTimeout(() => {
      //     SOUND.play();
      // }, 1200);
      const loopsMax = TIME_OUT_LOOP_MAX;
      for(let i = 1; i <= loopsMax; i++) {

        setTimeout(() => {
         if (i !== loopsMax) {
           if (i % 2 !== 0) { // ODD
             store.dispatch({ type: TIMED_OUT });
           } else { // EVEN
             store.dispatch({ type: BLACKED_OUT });
           }
         } else { // LAST LOOP
           store.dispatch({ type: RESET });
             store.dispatch({ type: PLAYER });
             setTimeout(() => {
                autoPlaySimon(true);
             }, (250 * (i/5)) );
         }
       }, (250 * i)); // INNER TIMER

      } // END For

    } // END if      
      
  }, TIME_LIMIT); // OUTER TIMER
  
  store.dispatch({
    type: TIMER,
    payload: NEW_TIMER
  });  //
  console.log(`********************`);
  console.log(`*** TIMER STARTED **`);
  console.log(`********************`);
  const { timers } = store.getState();
  console.log(`TIMERS: ${timers}`);

}


const autoPlaySimon = (timedOut) => {
  console.log('');
  console.log('Simon\'s next turn!?!');
  const { moveHistory, echoHistory, player, outcome, reset, result, strict } = store.getState();
  const MHL = moveHistory.length;
  const EHL = echoHistory.length;

  console.log('');
  console.log('SHOW SIMON/PANEL');
  console.log(`Player: ${player}`);
  console.log(`EHL: ${EHL}`);
  console.log(`MHL: ${MHL}`);
  console.log(`Outcome: ${outcome}`);
  console.log(`TimedOut: ${timedOut}`);  // ARGUMENT PASSED IN
  console.log(`Reset: ${reset}`);
  console.log(`Result: ${result}`);
  
  console.log(`***********************`);
  console.log(`* Decide SIMON'S TURN *`);
  console.log(`***********************`);
  
  if (
    
        (outcome === 0 && player === PLAYER) &&
        (EHL === MHL && timedOut === false) ||
        (EHL !== MHL && timedOut === true)
    ||
        (outcome === 0 && player === SIMON &&
         EHL !== MHL && reset === true && result === WRONG)
    ||
        (outcome === 0 && player === SIMON && strict === YES &&
         EHL === MHL && reset === true && result === WRONG)

      ) {
    //const { player } = store.getState();
    const { player } = store.getState();
    if (player !== SIMON) {
       store.dispatch({ type: PLAYER });
    }
    console.log('AutoPlayer:' + player);
    console.log('STARTING SIMON\'S TURN');
    simonsTurn();
  }
  console.log('Outcome after IF/AUTO-SIMON: ' + outcome);
  console.log('');
};


const simonsTurn = () => {
  const { repeat } = store.getState();
  // if (repeat === false) {
  store.dispatch({type: MOVE}); // ADD A NEW MOVE
  // }
  speed = 750;
  const {
    moves,
    moveHistory,
    result,
    reset
  } = store.getState();
  var moveCount = moveHistory.length + 1;
  console.log('MH: ' + moveHistory);
  console.log('MoveCount: ' + moveCount);
  setTimeout(() => {
    for(let i = 0; i < moveCount; i++) {

      console.log('i: ' + i);
      let interval = i * speed;
      setTimeout(() => {
         if (i !== moveCount-1) {
          //if (moveHistory[i] !== undefined) {
             console.log('Moves: ' + moves);
             console.log('i: ' + i);
             console.log('MHofI: ' + moveHistory[i]);
             console.log('MHL: ' + moveHistory.length);
             showSimon(moveHistory[i]);  
           //}
         } else {   // LAST MOVE
           console.log('LAST MOVE ##########');
           console.log('Reset: ' + reset);
           console.log('Result: ' + result);
           if (
                (result !== WRONG && repeat !== true) ||
                (result === WRONG && reset === true && repeat !== true) 
              ) {
             console.log('LAST MOVE!?!');
             let move = randPick();
             showSimon(move);
             store.dispatch({
               type: LOG,
               payload: move
             });
             // SET A TIME LIMIT ON THE SIMONS TURN
             const {player} = store.getState();
             console.log(`PLAYER is ${player}`);
              runTimer(0);
           }// if block

          // console.log('Switching Players!');
           setTimeout(() => {
             store.dispatch({type: PLAYER});
             // console.log('Players Switched!'); 
           }, 500);

           if (repeat === true) {
             store.dispatch({ type: END_REPEAT });
           }
         } // else block
      }, interval);
    }// END For
  }, speed);   // WAS * 1.5 at one point
}

const startGame = () => {
  store.dispatch({type: START});
  const { start } = store.getState();
  
  if (start === YES) {
    console.log('Simon\'s turn!');
    simonsTurn();
  } else {
    killAllSetTimeouts();
    const { paula, randy, j_lo, ryan, moveHistory } = store.getState();
    console.log(`MH: ${moveHistory}`);
    if (paula ===  SIMON) {
      store.dispatch({type: PAULA});
      return;
    }
    if (randy ===  SIMON) {
      store.dispatch({type: RANDY});
      return;
    }
    if (j_lo ===  SIMON) {
      store.dispatch({type: J_LO});
      return;
    }
    if (ryan ===  SIMON) {
      store.dispatch({type: RYAN});
      return;
    }
  }
};

const killAllSetTimeouts = () => {
  var id = setTimeout(null,0);
  while (id--) 
  {
      clearTimeout(id);
  }
}

const switchPower = () => {
  store.dispatch({type: POWER});
  killAllSetTimeouts();
}

const App = () => {
  
  ReactDOM.render(
    <Game 
       state={store.getState()}
       onToggleStart={()=> startGame()}
       onToggleStrict={()=> store.dispatch({type: STRICT})}
       onTogglePower={()=> switchPower()}
       onTogglePaula={()=> showSimon(PAULA)}
       onToggleRandy={()=> showSimon(RANDY)}
       onToggleJ_LO={()=> showSimon(J_LO)}
       onToggleRyan={()=> showSimon(RYAN)}
       onClear={()=> store.dispatch({type: CLEAR})}
       onRight={()=> showResult(RIGHT)}
       onWrong={()=> showResult(WRONG)}
       onTime={()=> showResult(TIME)}
       onSimon={()=> simonSays()}
    />,
    document.querySelector('body')
  );
};

store.subscribe(App);
App();
              
            
!
999px

Console