Badly stuck with simon game due to settimeout

$(document).ready(function() {
	// body...
	var rsound=new Audio('https://s3.amazonaws.com/freecodecamp/simonSound1.mp3');
	var gsound=new Audio('https://s3.amazonaws.com/freecodecamp/simonSound2.mp3');
	var bsound=new Audio('https://s3.amazonaws.com/freecodecamp/simonSound3.mp3');
	var ysound=new Audio('https://s3.amazonaws.com/freecodecamp/simonSound4.mp3');
	var beep=new Audio('1.mp3');
	var onoff='off';
	var gamestart;
	var error=false;
	var boxnumber; //score
	var patfunc;
	var patfunc1;
	var patfunc2;
	var patfunc3;
	var patfunc4;


	$('#onfbox').click(function(){
		if(onoff==='off'){
			onoff='on';
			$('#onfbtn').css('float','right');
			$('#box p').text('- -');
		    gamestart=setTimeout(start,10);
		}

		else if(onoff=='on'){

			onoff='off';
			$('#onfbtn').css('float','left');
			$('#box p').text('');
			$('#start').off('click');
			$('#strict').off('click');
			$('.slice').off('click');
			clearTimeout(patfunc);
			clearTimeout(patfunc1);
			clearTimeout(patfunc2);
			clearTimeout(patfunc4);
			clearTimeout(patfunc3);
			clearTimeout(gamestart);
		}
	});



	function start(){
		var strict=false;
		var colors=['blue','red','green','yellow'];
		var pattern;
		$('#start').click(function(){
			pattern=[];
			boxnumber=0;
			patfunc=setTimeout(givepattern,0);
		});

		$('#strict').click(function(){
			if(strict==false){
				strict=true;
				$('#strind').css('background-color','red');
			}
			else if(strict==true){
				strict=false;
				$('#strind').css('background-color','grey');
			}

		});



		function givepattern(){
			//if(onoff=='off'){
			//return;
		//} 
			$('.slice').off('click');
			
			if(error===false){
			//console.log(boxnumber);
			boxnumber+=1;
			console.log(boxnumber);
		    var number=Math.floor(Math.random() * 3);
			pattern.push(colors[number]);
			
		}
			$('#box p').text(boxnumber);
			console.log(pattern);

			for(var i=0;i<pattern.length;i++){
					//const j =i;
				patfunc2=setTimeout((function(j) { genersounds(pattern[j]);}).bind(null,i),i*800);

			}
			humanturn();
           		
 		 }

 		 	 function genersounds(clr){

			$('#'+clr).css('background-color','grey');
        	if(clr=='blue'){
          	bsound.play();
       	 	}
        	else if(clr=='green'){
          	gsound.play();
       		 }
        	else if(clr=='red'){
          	rsound.play();
       		 }
        	else if(clr=='yellow'){
          	ysound.play();
       		 }
        	setTimeout(function(){$('#'+clr).css('background-color',clr);},500);
     		 } 


     		 function humanturn(){
     		 		error=false;
     		 		var humanpattern=[];
     		 		var elementschecked=0;
     		 		//var i=0;

     		 		$('.slice').click(function(e){
     		 			genersounds(e.target.id);
     		 			elementschecked+=1;
     		 			humanpattern.push(e.target.id);
     		 			checkmatched(humanpattern,elementschecked);

     		 		});
     		 }


     		 function checkmatched(hmnptrn,elementschecked){
     		 	
     		 	for(var i=0;i<hmnptrn.length;i++){

     		 		if(pattern[i]===hmnptrn[i]){

     		 			if(elementschecked===pattern.length){
     		 			patfunc3=setTimeout(givepattern,1000);
     		 			//setTimeout((function(j) { givepattern();}).bind(null,i),1000);
     		 			//givepattern();
     		 		  }
     		 		}

     		 		else if(pattern[i]!==hmnptrn[i]){
     		 		error=true;
     		 		beep.play();
     		 		patfunc4=setTimeout(givepattern,1000);
     		 		//givepattern();
     		 		break;

     		 						}
     		 					}	
     		 				}
		


		}	

});

Hey guys after days of searching I couldnt found the problem with my code. I am really grinded to death right now. I thought if I could make tic tac toe with unbeatable AI this simon game will be nothing for me. Guess I dont know the settimeout was waiting to prove me wrong
Now I am getting two problems right now. The first one is in check matched function. The logic in that function after every click of coloured buttons i.e (red,yellow,green,blue) this matched function will test that as values in given pattern by computer and clicked user pattern is mathching,if matching and if all values of pattern given by computer are checked call the function with some delay of generpattern() to get a new pattern. Now this is what happening when I console log:
[‘red’]
i pressed red it gives new pattern
[‘red’,‘yellow’]
I pressed both buttons it gives new pattern and here is the problem now.
[‘red’,‘yellow’,‘green’]
[‘red’,‘yellow’,‘green’,‘red’]

What it did is gave me two patterns on console.log. Now I have to click for the latest pattern meaning it just skips the 3rd pattern to check and generated another 4 values pattern. Now after checking 4 values pattern it will generate 8 values pattern directly. If I removed settimeout from the checkmathched function it works fine but I need the delay to get it looked good.

Second problem is if I press the off button everything should be stopped. I used cleartimeout on every settimeout function still its not stopping the running settimeout in givepattern() function. You can confirm it if you press off button in middle of when computer is highliting pattern.

Please help me out with this one. I am really exhausted right now and couldnt think more to get this solve. I can provide the html and css too If anyone wants that …

It’s tough to troubleshoot for me after taking a quick look - if you put it in a pen(codepen.io) I would take a closer look - and be able to see better what is happening.

1 Like

I agree with moT01, having the pen itself to play with would help a lot, so please share it if you can.

Having said that, I think the best think you can do now is divide and conquer a little. Start splitting functions if they are doing too much. For example, I would probably separate givepattern() into at least 2 different functions:

  • playPattern(), only in charge of displaying a pattern on the screen, and;
  • nextPattern(), only in charge of updating the pattern’s state.

This should help your code have fewer undesirable side effects.

Next, instead of looping through the whole pattern each time, you can check only the last index of the human pattern, and see if it matches the same index number of the computer pattern.

Other unrelated tips, instead of var onoff='off';, I’d probably use var on = true;, that will make it easier to check for truthiness. For example, you can then replace if(onoff==='off') with just if (on). Toggling between true and false is also a breeze, you can have a function do:

function toggleStrict() {
 strict = !strict
}

That will make strict false if it was true, and true if it was false.

Sorry if I digress, and I hope you find this a little useful.

3 Likes

Thanx guys. I did troubleshoot my code and it works now :slight_smile: Had to understand closures deeply

1 Like