Chingu FCC Speedrun Challenge: Simon Game

Amir Fakheraldeen
Chingu FCC Speedrun
3 min readMay 27, 2017

This marks my 9th project in the speedrun challenge, and with this project I’ve essentially completed all the front end projects in the FCC curriculum. I must say, I wasn’t expecting to complete this many projects during the challenge, much less finish the entire first FreeCodeCamp certificate in less than 3 weeks (I’ve actually been studying for over 6 months though). I’m proud to be writing about this project, and I hope I can inspire others on the same path as well. :)

Okay, so let’s talk a bit about the project. First of all, it was really fun to build, it’s the project I’ve had the most fun building, even more than the Pomodoro clock. The biggest reason I’m so excited about this project is that I got to use ES6 generators for the first time! I basically created a class (called Simon) to handle all the game mechanics and data, and one of its methods is the generator I’m talking about. Instances of the class have an array containing the current pattern in the game, and the way the generator works is it keeps yielding the next item in the pattern array until it gets to the end of the array. This is how the generator is defined in code, inside the Simon class:

*playPattern() {
var current = 0;
while (current < this.pattern.length) {
yield this.pattern[current++];
}
}

It’s pretty simple, but to me it was very exciting to use this feature for the first time.

Each item in the pattern is an object with two properties; color, which is the color of the button in the pattern (a string, either “green,” “red,” “yellow,” or “blue”), and sound, which is the path to the sound file associated with the button. The objects are picked randomly from an array I’ve already defined (called buttons) inside the constructor of the Simon class, and pushed into the pattern array. In the main file of my application, I get the generator started by calling playPattern, and I use the next method to get the next object in the pattern array. From there, I use the yielded object’s properties to figure out which button to light up and which sound file to play. Actually, since I used Howler.js for the sounds, the sound property is technically a Howl object, so all I do is call sound.play() and it plays the sound file defined in the src property of that Howl object.

This is how all of this looks in code, defined in a method called play inside my main app file (which is a Vue file):

play() {
var pattern = this.simon.playPattern();
this.playing = true; var interval = setInterval(() => {
var current = pattern.next();
if (current.done) {
this.playing = false;
clearInterval(interval);
}
else {
let currentBtn = document.querySelector(
`.${current.value.color}`
);
current.value.sound.play();
this.lighten(currentBtn, this.speed / 2);
}
}, this.speed);
}

Of course this is all for when the game itself is playing the current pattern to the user. Things are handled a bit differently for when the user clicks a button. I have a separate method inside the Simon class for handling these cases:

playSoundByColor(color) {
for (let button of this[buttons]) {
if (color == button.color) {
button.sound.play();
return;
}
}
}

Provided a color string, it looks inside the private buttons array mentioned earlier (privacy achieved using Symbols) for the button matching the provided color, and it plays the sound associated with the button. The color is passed as a string to the button click handler.

Overall, working on this project has been really fun and rewarding.

Links:

Previous projects:

--

--