0

this is a jquery/ javascript problem. So I have an array that contains button numbers and outputs those buttons onto a button which will result in the button being clicked. The problem is that all the buttons get clicked at once if I run the loop. Instead I want it to output the numbers with a delay so that the buttons will be pressed after a 1 second delay.

Here is the link to the Simon game project: https://codepen.io/roger1891/full/vmYqwx/

The problem is visible after following the 1st button. After that, the computer will press the next 2 buttons at the same time instead of pressing them separately after a 1 sec delay.

The problem is located in this loop which is located in the myloop() function:

sequenceArray.forEach(function(item, index, array){
  //click button by getting the last index of the array
  //$("#btn-"+array[array.length-1]).click();
  $("#btn-"+array[index]).click(); 

  console.log(array);
}); 

This is the full code:

 //associating buttons to sound
  var soundButton = function(buttonId, soundId) {
    $("#" + buttonId).click(function(){
    $("#" + soundId).get(0).play();  
    $("#" + buttonId).css("opacity", "0.5");
    setTimeout( function(){
      $("#" + buttonId).css("opacity", "1");
    },500);
    if(currentPlayerTurn == "human") {
       var $input = $(this);
       var attrString = $input.attr("id");
       //only get number from id attribute
       var strNum = attrString.replace( /^\D+/g, '');
       //convert theNumber from string to number
       var theNum = parseInt(strNum);
       playerArray.push(theNum);
       console.log(theNum);
       console.log(playerArray);
    }
  });  
  };

  function myLoop() { 
    setInterval( function(){
      if(gameWon == false && onGoingGame == true && currentPlayerTurn == "computer" && score < 5) {

        //increment score  
        score++;  
        //append to score id
        $("#score").empty().append(score);
       //create random number
        randomNumber = Math.floor((Math.random()*4) + 1);
        //push random number into array
        sequenceArray.push(randomNumber);
        //loop through array

        sequenceArray.forEach(function(item, index, array){
        //click button by getting the last index of the array
        //$("#btn-"+array[array.length-1]).click();
        $("#btn-"+array[index]).click(); 

        console.log(array);
        });  

        currentRound = sequenceArray.length;
        onGoingGame = false;
        currentPlayerTurn = "human";
      }  

      if(currentPlayerTurn == "human") {
        var is_same = playerArray.length == sequenceArray.length && playerArray.every(function(element, index) {
          return element === sequenceArray[index]; 
        });
        is_same;
        console.log(is_same);
        if(is_same == true) {
          playerArray = [];
          onGoingGame = true;
          currentPlayerTurn = "computer";
        }
      }  
    },1000);

  }

 myLoop(); 

Thank you in advance for your help.

6
  • You are calling forEach in the callback of your interval. What are you existing to happen: Street reach forEach, and during each iteration of setInterval? Commented Apr 14, 2017 at 11:47
  • @Pineda if its the computers turn I want it to iterate through the content in the array. But it should iterate through it with a timely 1 second delay. Commented Apr 14, 2017 at 11:52
  • It would be good if you could edit your question to fully illustrate the problem you are having, check out how to ask a good question Commented Apr 14, 2017 at 11:57
  • Just for the record, you don't need the interval. If you split the myLoop function into two functions, computerTurn and playerTurn, you can just have the computerTurn call the next player turn and vice versa. That will make the code easier. Anyway, which array is being logged in one peice instead of one by one? Since without the html I can't figure out what $("#btn-"+array[index]).click(); triggers. Commented Apr 14, 2017 at 12:05
  • @Pineda Apologies for the vague description. I edited the post and added the project output. I hope its clearer now. Commented Apr 14, 2017 at 12:12

2 Answers 2

1

Since you want to trigger the buttons one by one, your setTimeout() should be inside the loop. Be mindful of the index, since this is async.

sequenceArray.forEach(function(item, index, array) {
    // set a timeout so each second one button gets clicked
    setTimeout( (function( index ) {
        // use a closure here so that our index values stay correct.
        return function() {
            $("#btn-"+array[index]).click(); 
        };
    }( index )), (1000 * index) );
});  

edit: replaced the fixed 1000ms delay to delay * index

Sign up to request clarification or add additional context in comments.

Comments

0

You need to console.log(item) instead of full array in forEach loop

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.