Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs 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 its URL and the proper URL extension.

+ 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

Auto Save

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

              
                .simon
  .controls
    .game-label Simon
    #count
    #start.button
    #start-label.label Start
    #strict.button
    #strict-label.label Strict
    #strict-indicator
    #endless.button
    #endless-label.label Endless
    #endless-indicator
    #power
    #power-on.label ON
    #power-off.label OFF

  .buttons
    svg(viewBox="0 0 100 100" data-color='green').game-button.green
      path(d="M 0 100 A 105.17 105.17 0 0 1 100 0 L 100 50 A 55.17 55.17 0 0 0 50 100 Z"
        fill="green"
        stroke="transparent").green
    svg(viewBox="0 0 100 100" data-color='red').game-button.red
      path(d="M 0 100 A 105.17 105.17 0 0 1 100 0 L 100 50 A 55.17 55.17 0 0 0 50 100 Z"
        fill="green"
        stroke="transparent").red
    svg(viewBox="0 0 100 100" data-color='yellow').game-button.yellow
      path(d="M 0 100 A 105.17 105.17 0 0 1 100 0 L 100 50 A 55.17 55.17 0 0 0 50 100 Z"
        fill="green"
        stroke="transparent").yellow
    svg(viewBox="0 0 100 100" data-color='blue').game-button.blue
      path(d="M 0 100 A 105.17 105.17 0 0 1 100 0 L 100 50 A 55.17 55.17 0 0 0 50 100 Z"
        fill="green"
        stroke="transparent").blue

              
            
!

CSS

              
                @import url(https://fonts.googleapis.com/css?family=Roboto+Slab:400,700|Ubuntu+Mono)

$green: hsl(120, 70%, 20%)
$red: hsl(0, 70%, 25%)
$yellow: hsl(60, 80%, 25%)
$blue: hsl(240, 60%, 30%)

body
  margin: 0
  font-family: 'Roboto Slab', serif
  font-weight: 400
  color: #333
  background-color: #444
  background-image: url(https://s3.amazonaws.com/djones-imghost/f9SUFAuS/simon-wood-bg.jpg)
  background-repeat: repeat

.simon
  user-select: none
  position: relative
  margin: 64px auto
  width: 512px
  height: 512px
  border-radius: 50%
  background-color: #222
  box-shadow: 3px 8px 15px rgba(black, .6), inset 2px 4px 4px rgba(white, .1), inset -2px -4px 4px rgba(black, 0.5)

.controls
  position: absolute
  width: 232px
  height: 232px
  top: 50%
  left: 50%
  transform: translate(-50%, -50%)
  z-index: 1
  border-radius: 50%
  background-color: #ddd
  .button
    box-sizing: border-box
    width: 32px
    height: 32px
    border-radius: 50%
    border: 3px solid #555

.game-label
  position: absolute
  top: 24px
  left: 116px
  font-size: 40px
  font-weight: 700
  transform: translateX(-50%)

.label
  font-size: 12px
  font-weight: 700

#count
  position: absolute
  top: 116px
  left: 46px
  transform: translate(-50%, -50%)
  width: 2ch
  height: 1em
  padding: 8px
  border-radius: 7px
  font-family: 'Ubuntu Mono', monospace
  font-size: 18px
  line-height: 1
  background-color: #633
  color: #f22
  box-shadow: inset 0 0 5px rgba(black, 0.8)

#start
  position: absolute
  top: 116px
  left: 93px
  transform: translate(-50%, -50%)
  background-color: #d44

#start-label
  position: absolute
  top: 132px
  left: 93px
  transform: translateX(-50%)

#strict
  position: absolute
  top: 116px
  left: 139px
  transform: translate(-50%, -50%)
  background-color: #dd4

#strict-label
  position: absolute
  top: 132px
  left: 139px
  transform: translateX(-50%)

#strict-indicator
  position: absolute
  top: 85px
  left: 139px
  width: 8px
  height: 8px
  transform: translateX(-50%)
  border-radius: 50%
  background-color: #422

#strict-indicator.on
  background-color: #f22
  box-shadow: 0 0 3px rgba(red, 0.8)

#endless
  position: absolute
  top: 116px
  left: 186px
  transform: translate(-50%, -50%)
  background-color: hsl(240, 50%, 80%)

#endless-label
  position: absolute
  top: 132px
  left: 186px
  transform: translateX(-50%)

#endless-indicator
  position: absolute
  top: 85px
  left: 186px
  width: 8px
  height: 8px
  transform: translateX(-50%)
  border-radius: 50%
  background-color: #224

#endless-indicator.on
  background-color: #66f
  box-shadow: 0 0 5px #66f

#power
  position: absolute
  top: 180px
  left: 92px
  box-sizing: border-box
  width: 48px
  height: 24px
  border-radius: 12px
  background-color: #666
  box-shadow: inset 0 0 5px rgba(black, 0.5)
  &::before
    content: " "
    position: absolute
    top: 0
    left: 0
    box-sizing: border-box
    width: 24px
    height: 24px
    border-radius: 50%
    background-color: white
    box-shadow: 0 1px 3px black

#power.on
  background-color: green
  &::before
    left: 24px

#power-off
  position: absolute
  top: 192px
  right: 148px
  transform: translateY(-50%)

#power-on
  position: absolute
  top: 192px
  left: 148px
  transform: translateY(-50%)

.buttons
  position: relative
  display: flex
  flex-wrap: wrap

.game-button
  border: 0
  margin: 12px
  width: 232px
  height: 232px

path.green
  fill: $green
path.red
  fill: $red
path.yellow
  fill: $yellow
path.blue
  fill: $blue
path.green-light
  fill: lighten($green, 40%)
path.red-light
  fill: lighten($red, 40%)
path.yellow-light
  fill: lighten($yellow, 40%)
path.blue-light
  fill: lighten($blue, 40%)

svg.red
  transform: rotate(90deg)
svg.yellow
  transform: rotate(270deg)
svg.blue
  transform: rotate(180deg)

              
            
!

JS

              
                var COLORS = [
  'green',
  'red',
  'yellow',
  'blue'
];

var NOTES = {
  green: 164.814,
  yellow: 277.183,
  red: 220,
  blue: 329.628
};

var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var gainNode = audioCtx.createGain();
var filterNode = audioCtx.createBiquadFilter();
filterNode.type = 'lowpass';
filterNode.frequency.value = 660;
gainNode.gain.value = 0.5;
gainNode.connect(filterNode);
filterNode.connect(audioCtx.destination);

function GameState() {
  // Is the game switched on?
  this.on = false;
  // Is strict mode enabled?
  this.strict = false;
  // Is endless mode enabled?
  this.endless = false;
  // Are we waiting for player input?
  this.waiting_for_input = false;
  // Computer generated sequence. One element is added each turn.
  this.challenge_seq = [];
  // Player input. This is blanked each turn before player starts entering the sequence.
  this.input_seq = [];
}

var game_state = new GameState();

function lightOn(color) {
  $('path.' + color).addClass(color + '-light');
}

function lightOff(color) {
  $('path.' + color).removeClass(color + '-light');
}

function playNote(color, start, stop) {
  var currentTime = audioCtx.currentTime;
  var oscillator = audioCtx.createOscillator();
  oscillator.type = 'sine';
  oscillator.frequency.value = NOTES[color];
  oscillator.connect(gainNode);
  oscillator.start(currentTime + start);
  oscillator.stop(currentTime + stop);
}

function playChord(start, stop, chord) {
  var currentTime = audioCtx.currentTime;
  chord = chord || [
    330,
    110,
    55
  ];
  var oscillators = chord.map(function(freq) {
    var oscillator = audioCtx.createOscillator();
    oscillator.type = 'sine';
    oscillator.frequency.value = freq;
    oscillator.connect(gainNode);
    return oscillator;
  });
  oscillators.forEach(function(oscillator) {
    oscillator.start(currentTime + start);
    oscillator.stop(currentTime + stop);
  });
}

function flashAll() {
  var num_flashes = 3;
  var period = 150;
  for (var i = 0; i < num_flashes; i++) {
    var start = (i * period) + (period / 2);
    var stop = (i * period) + period;
    playChord(start / 1000, stop / 1000);
    for (var color=0; color<COLORS.length; color++){
      setTimeout(lightOn, start, COLORS[color]);
      setTimeout(lightOff, stop, COLORS[color]);
    }
  }
  // Return time to finish flashes.
  return ((num_flashes - 1) * period) + period;
}

function playWin() {
  var period = 150;
  COLORS.forEach(function(color, i) {
    var startTime = i * period;
    var stopTime = i * period + Math.floor(period * 0.8);
    setTimeout(lightOn, startTime, color);
    setTimeout(lightOff, stopTime, color);
    playNote(color, startTime / 1000, stopTime / 1000);
  });
  var startTime = period * (COLORS.length + 1);
  var stopTime = startTime + (period / 2);
  COLORS.forEach(function(color) {
    setTimeout(lightOn, startTime, color);
    setTimeout(lightOff, stopTime, color);
    setTimeout(lightOn, startTime + period, color);
    setTimeout(lightOff, stopTime + period, color);
  });
  var chord = [220, 277.183];
  playChord(startTime / 1000, stopTime / 1000, chord);
  playChord((startTime + period) / 1000, (stopTime + period) / 1000, chord);
  return period * 7;
}

function playSeq(seq) {
  var period = Math.max(150, -25 * seq.length + 800);
  for (var i = 0; i < seq.length; i++) {
    var color = COLORS[seq[i]];
    var startTime = (i * period) + (period / 2);
    var stopTime = (i * period) + period;
    setTimeout(lightOn, startTime, color);
    setTimeout(lightOff, stopTime, color);
    playNote(
      color,
      startTime / 1000,
      stopTime / 1000
    );
  }
  // Return time to finish playback.
  return ((seq.length - 1) * period) + period;
}

function genChallengeSeq() {
  game_state.challenge_seq.push(Math.floor(Math.random() * 4));
  var count_display = game_state.challenge_seq.length.toString();
  if (count_display.length < 2) {
    count_display = '0' + count_display;
  }
  $('#count').text(count_display);
}

function checkSequence(input_seq, challenge_seq) {
  return challenge_seq
    .slice(0, input_seq.length)
    .reduce(function(prev, curr, i) {
      return prev && (curr === input_seq[i]);
    }, true);
}

function updateStrictIndicator() {
  if (game_state.strict) {
    $('#strict-indicator').addClass('on');
  } else {
    $('#strict-indicator').removeClass('on');
  }
}

function updateEndlessIndicator() {
  if (game_state.endless) {
    $('#endless-indicator').addClass('on');
  } else {
    $('#endless-indicator').removeClass('on');
  }
}

$('#power').click(function() {
  if (game_state.on) {
    $(this).removeClass('on');
    $('#count').text('');
    game_state = new GameState();
    updateStrictIndicator();
    updateEndlessIndicator();
  } else {
    $(this).addClass('on');
    game_state = new GameState();
    $('#count').text('--');
    setTimeout(function() {
      game_state.on = true;
    }, playWin());
    updateStrictIndicator();
    updateEndlessIndicator();
  }
});

$('#start').click(function() {
  if (game_state.on) {
    game_state.input_seq = [];
    game_state.challenge_seq = [];
    genChallengeSeq();
    playSeq(game_state.challenge_seq);
    game_state.waiting_for_input = true;
  }
});

$('#strict').click(function() {
  if (game_state.on) {
    game_state.strict = !game_state.strict;
  }
  updateStrictIndicator();
});

$('#endless').click(function() {
  if (game_state.on) {
    game_state.endless = !game_state.endless;
  }
  updateEndlessIndicator();
});

$('.game-button').click(function() {
  if (game_state.waiting_for_input) {
    game_state.waiting_for_input = false;
    lightOn($(this).data('color'));
    setTimeout(function(color) {
      lightOff(color);
    }, 300, $(this).data('color'));
    playNote($(this).data('color'), 0, 0.3);
    game_state.input_seq.push(COLORS.indexOf($(this).data('color')));
    if (checkSequence(game_state.input_seq, game_state.challenge_seq)) {
      if (game_state.input_seq.length >= game_state.challenge_seq.length) {
        game_state.input_seq = [];
        if (game_state.challenge_seq.length >= 20 && !game_state.endless) {
          setTimeout(function() {
            setTimeout(function() {
              game_state.challenge_seq = [];
              genChallengeSeq();
              setTimeout(function() {
                game_state.waiting_for_input = true;
              }, playSeq(game_state.challenge_seq));
            }, playWin());
          }, 500);
        } else {
          genChallengeSeq();
          setTimeout(function() {
            setTimeout(function() {
              game_state.waiting_for_input = true;
            }, playSeq(game_state.challenge_seq));
          }, 500);
        }
      } else {
        game_state.waiting_for_input = true;
      }
    } else {
      setTimeout(function() {
        setTimeout(function() {
          if (game_state.strict) {
            game_state.input_seq = [];
            game_state.challenge_seq = [];
            genChallengeSeq();
            setTimeout(function() {
              game_state.waiting_for_input = true;
            }, playSeq(game_state.challenge_seq));
          } else {
            setTimeout(function() {
              game_state.input_seq = [];
              game_state.waiting_for_input = true;
            }, playSeq(game_state.challenge_seq));
          }
        }, flashAll());
      }, 500);
    }
  }
});

              
            
!
999px

Console