Simon Game: stuck in a rut

Hi all. I’d appreciate some guidance here as after a good start I’m now struggling to make progress with my Simon Game implementation. My project is here: http://codepen.io/iskye81/pen/bqGRwN

There’s a lot that hasn’t been implemented yet, but my main struggle at the minute is the AI behaviour. As far as I can tell by examining them in the console the sequence arrays (I’ve called them “steps” and “userSteps”) are getting the correct elements for making a comparison, but the game does not correctly stop in a game over situation, and the game over alert appears regardless after the first sequence step even if the user has entered the correct sequence.

Basically I can’t see the wood for the trees right now and some pointers would be great. If I can get a very basic implementation going I’m sure I can kick on from there.

I feel like passing an entire function/object in an array might be a bad idea. You wanna pass something like a name attribute. It would work better and easier to keep track of.

I narrowed the console logging to just userSteps and saw that if you pressed the same button for the second time, as in the next round, it was passing as a ‘circular object’ and that the userSteps array hadn’t been cleared. userSteps should be cleared each time startGame() is used since you start a new round of comparing it with steps.

I also noticed in your for loop the variable i isn’t actually initialized, which is why it appears yellow instead of the usual blue color that codepen uses for variables.

Typically you also want everything inside a $(document).ready function.

You’ve got too much going in in your tones array. And I wouldn’t keep userSteps as its own array, but as a simple number, starting at 0.
Say you have an array var steps = ["Green", "Blue", /*... */]
So then you could check like so if(guessColor === steps[userSteps]){ userSteps++; /*More stuff*/}

Might make it easier. Also a Constructor function for button would reduce repetition. I recently finished this challenge myself and thoroughly commented my JavaScript if you’d like to take a look.

Thanks for your replies. I haven’t had a chance to get back to the project since I posted this, but I’ll take a look at your suggestions and hopefully get going with it again today.

OK, I decided to re-write my code based off a few ideas, but I’m now getting the following TypeError:

Cannot set property 'currentTime' of undefined

…but that’s not even the half of it. I disabled the properties within the playSound() function to temporarily bypass this error, but this reveals further problems as it looks like a random sequence is not being correctly generated. I honestly feel like giving up now. :disappointed:

(http://codepen.io/iskye81/pen/bqGRwN)

Oh no! I’m sorry to hear that. The formatting and code comments are very solid though! I’ll try to fork this and debug if I have time. The designs for your other FCC projects are really nice, so don’t doubt yourself :heart:

It may be easier to fork the pen and start over with the JS, slowly adding one facet at a time. Animating the sequence is the most difficult part of this challenge.

Okay here are some things I’ve noticed:

1.) In game.padListener() you define pad as var pad = parseInt($(this).data('pad'), 10); BUT in your HTML the data-pad attribute isn’t on the .pad element, but its child <audio> element so it’s coming back undefined. (Basically just add a data-pad attribute to your buttons and that’s solved. Also you could just define var pad = $(this).data('pad'); but whatevs.)

There are some more things I’ve noticed. I’ll edit this as I find time to make notes. Here’s the forked version I’m working on:

Currently, the sequence doesn’t play but I am able compare a user’s guess and push more into the array if it’s correct so there’s baby steps there :smiley:

Okay so it’s done to a decent point (The pen is the same - CodePen: “FORKED from Iain : Simon Game” )

There’s a lot of room for improvement that I’ll leave up to you. You can use this to generate a diff between code to see the changes http://www.quickdiff.com/

You were really close, you’ll see I didn’t change much.

I did get rid of game.square, game.userSeq and game.logPlayerSeq().
I added game.userIndex to keep track of the user’s position within the sequence and game.sequenceIndex to keep track of the index while playing the sequence.

The two major methods I changed were game.displaySequence() and game.checkSeq()

/*--------------------------------------------------------------
# game.displaySequence()
--------------------------------------------------------------*/  
  displaySequence: function() { // display the generated sequence to the user
    var that = this;
      var val = that.aiSeq[that.sequenceIndex]; // Grab the value (1-4) from the sequence at the current play position
      that.sequenceIndex++; // Increment play position
      setTimeout(function() {
        that.lightUp($(".square" + val), 1, 300, val); //Light it up
        if (that.sequenceIndex < that.count){ // Have we not played the whole sequence?
          that.displaySequence(); // Then play it again (recursive)
        } else {
          that.sequenceIndex = 0; // Reset play index (playing stops)
        }
      }, 500);
  },
/*--------------------------------------------------------------
# game.checkSeq()
--------------------------------------------------------------*/  
  checkSeq: function(pad) { // check to determine if the pad the user pressed was the correct next one in the sequence
    var that = this;
    if (pad !== this.aiSeq[this.userIndex]) {
      this.userIndex = 0; // Start Over
      if (this.strict === true) {
        this.gameOver(); // strict mode is on, end the game
      } else if (this.strict === false) {
        this.displaySequence(); // strict mode is off, display the sequence again to the user
      }
    } else { // they guessed correctly
      this.userIndex++; //Increment the user's position within the sequence
      if(this.userIndex === this.aiSeq.length){ // If the user has correctly guessed the entire current sequence
        this.userIndex = 0; // Start at the beginning of the sequence
        
        //this.active = false;  This is making it so we can't guess past the first round!!
        if(this.count >= 20){ // Have they completed all 20 rounds?
          // If so, they won!
          setTimeout(function(){ // Using set timeout to avoid 'play() interrupeted' error
            alert("You Win! \n Restarting Game...");
            that.newGame();
          }, 150);  
        } else { // Otherwise, they haven't won but they did beat the round
          this.keepCount(); // if correct keep going and increment the count
          this.randomPad();
          this.displaySequence();
        }
     }
    }
  },

Lemme know if you have any questions! :smile:

Hi Stephie. Thanks so much for your help on this, I think I’ve finally got to grips with it. :relaxed:

Also sorry for the delay in replying - I’m only able to work on coding part time, which means I often end up forgetting what I was trying to achieve with the code I’d written in the first place!

1 Like