Simon Game: FreeCodeCamp

Attempt # ∞

I have been attempting to do the Simon Game project on Freecodecamp for a few weeks now and I am annoyed. This problem wasn’t about it being difficult, it was all mental. I was trying to do too much at once. I took some time off and then cut the process into bite size chunks. You know… the kind you can eat with chopsticks.

I simplified to code to the basics:

  1. Initialize simon with a number from 0–3

2)Get a value from 0–3 from the user and append it to an array.

3) Check the simon value from the user against.

var simonArray = [];
var x = Math.floor(Math.random() * 4);
var playerArray = [];
simonArray.push(x);
var simonArrayNum = [];

$(document).ready(function(){
 console.log(simonArray) });

function humanSong(val){
 playerArray.push(val); 
 console.log(playerArray);
 for (var i= 1; i< playerArray.length;){ 
 if (val == simonArray[i]){
 console.log(val)
 simonSong()}
 else{
 alert(‘you suck! Try again!’)
 break;}}

 
return playerArray}
function simonSong(){
var y = Math.floor(Math.random() * 4);
simonArray.push(y);
console.log(simonArray);}

function enter(){
 console.log(playerArray);}

I assigned each of the colors in my html the humanSong() function with onclick and then I input a unique value, 0–3, inside the humanSong() function.

Needless to say, the above function is not working. Instead of using sound, I print out the simon array and the human values to check what the code is doing.

The console log in my simon array was not triggering to I asked Mr.Google.

Then I had a problem with my loops being ∞. I even had to force quit google chrome on more that one occasion. I fixed this by moving around the logic and making what is the “else” statement in the above code, the “if” statement.

After that, I had a problem with the break in the else statement not actually breaking the loop. I fixed this one by exchanging the “break” with a “return”.

My next problem was having the program equate the val input from the player with the entire simon array. I fixed this by adding another if statement to only check if the length of the input array is equal to the length of simon array.

Then, the program didn’t check as the human put in the values. That, again was a matter of moving around the logic and testing things out.

Once I got that working, I realized that the comparison I was making, after level 3 was not working. For some reason, my player array was iterating as ‘undefined’. For some reason, the variable i was using to iterate was skipping intermediate values. Turns out I had the wrong index. lol. I had to use < instead of ≤ or subtract 1 from the value I am iterating through.

Now I put in a function that will play the corresponding sound when the player clicks the board.

It worked! Now, I just have to add whether or not you have the “strict” button toggled. This means that I have to get the value from the user some how and use it to vary the responses when the player loses.

I got that done after a few hours of trail and error.

Now I need to make the board responsive when the player presses the button. I used the toggleClass feature in jquery with the setTimeout() function and boom!

At this point, I notice that Google Chrome was not updating the css! So I downloaded an extension called CSS Reloader. Right click on the page, select the reloader, and boom! updated css. I didn’t want to have to empty out the cache.

Now, I need to initiate the simon sequence; the sequence that plays to let the player know which buttons to press.

So I agonized for hours because I thought that I couldn’t use a for loop with the setTimeout() function. Then I found this not only does it give an example code, but it also explains what is happening when the code freaks out. If you didn’t do it the way the author has you iterating, the playback from Simon becomes a mess if not, an infinite loop that will crash chrome.

So, in the end, my files look like this:

index.htlm

<!DOCTYPE html>

<html lang=”en-us”>

<head>
<meta charset=”utf-8">
<title>Simon</title>

<script type=”text/javascript” src=”https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src=”https://npmcdn.com/tether@1.2.4/dist/js/tether.min.js"></script>
<script type=”text/javascript” src=”https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/js/bootstrap.js"></script>
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.css" type=”text/css” />
<link rel=”stylesheet” href=”stylesheet.css” type=”text/css” />
<script type=”text/javascript” src=”simon.js”></script>
</head>

<body>
 <div id=’userOptions’>
<form class=”form”>

 
<div id=options>
 <h1>Choose Parameters</h1> 
<div class=”radio”>
 <label>
 <input type=”radio” id=’stict’ name=”optionsRadios” id=”optionsRadios1" value=”checked” checked>
 Play Strict: Game will start over if you mess up
 </label>
</div>
<div class=”radio”>
 <label>
 <input type=”radio” name=”optionsRadios” id=”optionsRadios2" value=”unchecked”>
 Play Regular: Game will continue if you mess up
 </label>
 </div>
</div>
<div id=”console”style=”display: none”>
 <h1>Level is:</h1> <h1 id=’level’>0</h1>
</div>

<label class=”form-check-label”>
 <button class=”btn btn-primary inital” onclick=’Ty(); return false;’>Play Game!</button>
 <button onclick= ‘init()’ class=”btn btn-primary”>Reset Game!</button>
 </label>
 </div>

 
</form>

<div id=”gameBoard”>
 <h1>Simon</h1>
<table id=simongame>
 <tr>
 <td class=’makeClear’ id =”green” onclick=’humanSong(0);return false’></td>
 <td class=’makeClear’ id =”red” onclick=’humanSong(1)’></td>
 </tr>
 <tr>
 <td class=’makeClear’ id =”yellow” onclick=’humanSong(2) ;return false’></td>
 <td class=’makeClear’ id =”blue” onclick=’humanSong(3) ;return false’></td>
 </tr>
</table></div>
</body>
</html>

simon.js

var simonArray = [];
var playerArray = [];
var simonPlaylist = [];
var simon;
var human;
var level = 1;

var gamePlay = ‘regular’;
var numtocolor = {0:”#green”, 1:”#red”,2:”#yellow”, 3:”#blue” };
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(“/simonSound4.mp3”);

var playlist = {
 0: audio1,
 1: audio2,
 2: audio3,
 3: audio4}
;

function Ty(){
 document.getElementById(‘options’).style.display = ‘none’;
 document.getElementById(‘console’).style.display = ‘block’;
 playGame();
 simonSong();
}

function humanSong(val){
 // makeOpaque(numtocolor[val]);
 resetBoard(val)
 playerArray.push(val);
 playSound(val);
 if (playerArray.length <= level){
 check(); }
 if (playerArray.length == simonArray.length){
 nextLevel()}}

function simonSong(){
 var y = Math.floor(Math.random() * 4);
 simonArray.push(y);
 simonPlaylist.push(playlist[y]);
 var i=0;
 theLoop(i);}

function check(){
 for (i=0; i<= playerArray.length-1;i++){
 human = playerArray[i];
 simon = simonArray[i];
 if (human !== simon){
 strictFunt();}}
 
}
function nextLevel(){
 if (level==20){
 window.confirm(“You Won!! Predd OK to Play Again!”)
 init();
 }
 simonSong();
 level ++;
 document.getElementById(“level”).innerHTML= (level -1)
 playerArray = [];
}

`function playSound(num){
 var audio = playlist[num];
 audio.play();
}

function playGame(){
 if ($(‘#stict’).prop(‘checked’) == true){
 gamePlay = “strict”;}
 return gamePlay;}

function strictFunt(){
 if (gamePlay == “strict”){
 window.confirm(“Strict Mode: Game Will Restart… Loser!”);
 init();
 return;
 }
 window.confirm(“Regular Mode: Wimp… Game Will Continue”);
 playerArray=[]
 theLoop(0)
}

function resetBoard(val){
 $(numtocolor[val]).toggleClass(‘makeClear’);
 setTimeout(function (){$(numtocolor[val]).toggleClass(‘makeClear’)}, 300)}

function setSimonsong(z) {
 playSound(z);
 resetBoard(z);
 z++;
}

function theLoop (i) {
 setTimeout(function () {
 sound = simonArray[i];
 setSimonsong(sound);
 i++;
 if (i < simonArray.length) { // If i > 0, keep going
 theLoop(i); // Call the loop again, and pass it the current value of i
 }
 }, 1000);
}

simon.css

#red{
 border: solid 5vh red;
 width: 40vh;
 height: 40vh;
 border-radius: 70% 0% 70% 0% ;
 background-color: red;
 margin: 10vh;
 box-shadow: 0 4vh 8vh 0 rgba(0, 0, 0, 0.2), 0 8vh 20vh 0 rgba(0, 0, 0, 1.5);}

#green{
 border: solid 5vh green;
 width: 40vh;
 height: 40vh;
 border-radius: 0% 70% 0% 70% ;
 background-color: green;
 margin: 10vh;
 box-shadow: 0 4vh 8vh 0 rgba(0, 0, 0, 0.2), 0 8vh 20vh 0 rgba(0, 0, 0, 1.9);}

#yellow{
 border: solid 5vh yellow;
 width: 40vh;
 height: 40vh;
 border-radius: 70% 0% 70% 0% ;
 background-color: yellow;
 margin: 10vh;
 box-shadow: 0 4vh 8vh 0 rgba(0, 0, 0, 0.2), 0 8vh 20vh 0 rgba(0, 0, 0, 1.9);
}
#blue{
 border-radius: 0% 70% 0% 70% ;
 border: solid 5vh blue;
 width: 40vh;
 height: 40vh;
 background-color: blue;
 margin: 10vh;
 box-shadow: 0 4vh 8vh 0 rgba(0, 0, 0, 0.2), 0 8vh 20vh 0 rgba(0, 0, 0, 1.9);
}
body{
 background-color: black;
 padding-left: 20vh;
}

table{
 background-color: white;
}

.form{
 border: white 1vh solid;
 color: white;
 padding: 10vh;
 display: inline-table;
 margin: 10vh;
}

tr:hover td{
 background-color: purple;
}

.makeOpaqueClass{
 opacity: 1;
}
.makeClear{
 opacity: 0.5
}
#userOptions{
 float: right;
 width: 80vh;
 height: 30%;
 overflow: scroll;
}
#gameBoard{

 
}
.radio{
 margin: 2;
}

If you want to see it in an IDE, this is the link to C9 and here is the link to Codepen. From here it is just styling with css. I had a lot of trouble with this one so if you need any help just message me.