Skip to content
Advertisement

Javascript sorting function causes game to quit

I have a game in Javascript. It plays clues with buttons and the user needs to remember which buttons to click after the button is lit up and the clue plays.

I have a variable called pattern that holds an array to represent the different buttons to play in different order. Instead of having this fixed pattern I created a function that sorts the array and then I call it in the startGame function, which initiates the game. However, this time with this sorting function, although I click the correct button that is played and lit up, the game automatically quits and says “you lose” which is what happens when you press the incorrect button.

What do I do? I am guessing it has something to do with the guess function but how do I fix it?

//Global Contants
 
const cluePauseTime = 333; //how long to pause in between clues
const nextClueWaitTime = 1000; //how long to wait before starting playback of the clue sequence

//Global variables
var clueHoldTime = 500; //how long to hold each clue's light/sound
var pattern = [2, 3, 1, 4, 6, 1, 2, 4, 3, 5];
var progress = 0;
var gamePlaying = false;
var tonePlaying = false;
var volume = 0.5;
var guessCounter = 0;

function randNum() {
  pattern.sort(() => Math.random() - Math.random() )

}
function startGame() {
  
  progress = 0;
  gamePlaying = true;

  document.getElementById("startBtn").classList.add("hidden");
  document.getElementById("stopBtn").classList.remove("hidden");

  playClueSequence();
  
  randNum();
  
}

function stopGame() {
  gamePlaying = false;

  document.getElementById("startBtn").classList.remove("hidden");
  document.getElementById("stopBtn").classList.add("hidden");
}

function lightButton(btn){
  document.getElementById("button"+btn).classList.add("lit")
}
function clearButton(btn){
  document.getElementById("button"+btn).classList.remove("lit")
}

function playSingleClue(btn){
  if(gamePlaying){
    lightButton(btn);
    playTone(btn,clueHoldTime);
    setTimeout(clearButton,clueHoldTime,btn);
  }
}

function playClueSequence(){
  guessCounter = 0;
  let delay = nextClueWaitTime; //set delay to initial wait time
  for(let i=0;i<=progress;i++){ // for each clue that is revealed so far
    console.log("play single clue: " + pattern[i] + " in " + delay + "ms")
    setTimeout(playSingleClue,delay,pattern[i]) // set a timeout to play that clue
    delay += clueHoldTime;
    delay += cluePauseTime;
  }
}

function loseGame() {
  stopGame();
  alert("Game Over. You lost.");
}
function winGame() {
  stopGame();
  alert("Yayyyyy, you win!!");
}

function guess(btn) {
  console.log("user guessed: " + btn);
  if (!gamePlaying) {
    return;
  }
  if (pattern[guessCounter] == btn) {
    if (guessCounter == progress) {
      if (progress == pattern.length - 1) {
        winGame();
      } else {
        progress++;
        playClueSequence();
      }
    } else {
      guessCounter++;
    }
  } else {
    loseGame();
  }
}
// Sound Synthesis Functions
const freqMap = {
  1: 261.6,
  2: 329.6,
  3: 392,
  4: 466.2,
  5: 432.8,
  6: 336.2
};
function playTone(btn, len) {
  o.frequency.value = freqMap[btn];
  g.gain.setTargetAtTime(volume, context.currentTime + 0.05, 0.025);
  tonePlaying = true;
  setTimeout(function() {
    stopTone();
  }, len);
}
function startTone(btn) {
  if (!tonePlaying) {
    o.frequency.value = freqMap[btn];
    g.gain.setTargetAtTime(volume, context.currentTime + 0.05, 0.025);
    tonePlaying = true;
  }
}
function stopTone() {
  g.gain.setTargetAtTime(0, context.currentTime + 0.05, 0.025);
  tonePlaying = false;
}

//Page Initialization
// Init Sound Synthesizer
var context = new AudioContext();
var o = context.createOscillator();
var g = context.createGain();
g.connect(context.destination);
g.gain.setValueAtTime(0, context.currentTime);
o.connect(g);
o.start(0);

HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Hello!</title>

    <!-- import the webpage's stylesheet -->
    <link rel="stylesheet" href="/style.css" />

    <!-- import the webpage's javascript file -->
    <script src="/script.js" defer></script>
  </head>
  <body>
    <h1>Shah's Memory Game</h1>

    <p>
      Welcome to the game that will test your memory!
    </p>

    <button id="startBtn" onclick="startGame()">
      Start
    </button>
    <button id="stopBtn" class="hidden" onclick="stopGame()">
      Stop
    </button>

    <div id="gameButtonArea">
      <button
        id="button1"
        onclick="guess(1)"
        onmousedown="startTone(1)"
        onmouseup="stopTone()"
      ></button>
      <button
        id="button2"
        onclick="guess(2)"
        onmousedown="startTone(2)"
        onmouseup="stopTone()"
      ></button>
      <button
        id="button3"
        onclick="guess(3)"
        onmousedown="startTone(3)"
        onmouseup="stopTone()"
      ></button>
      <button
        id="button4"
        onclick="guess(4)"
        onmousedown="startTone(4)"
        onmouseup="stopTone()"
      ></button>
      <button
        id="button5"
        onclick="guess(5)"
        onmousedown="startTone(5)"
        onmouseup="stopTone()"
      ></button>
      <button
        id="button6"
        onclick="guess(6)"
        onmousedown="startTone(6)"
        onmouseup="stopTone()"
      ></button>
    </div>
  </body>
</html>

Advertisement

Answer

You need to increment the guessCounter every time there’s a successful guess. You cannot reset guessCounter = 0 every time you invoke the playClueSequence() function, rather clear it when you startGame(). Find the comments in the code for better clarification.

//Global Contants
 
const cluePauseTime = 333; //how long to pause in between clues
const nextClueWaitTime = 1000; //how long to wait before starting playback of the clue sequence

//Global variables
var clueHoldTime = 500; //how long to hold each clue's light/sound
var pattern = [2, 3, 1, 4, 6, 1, 2, 4, 3, 5];
var progress = 0;
var gamePlaying = false;
var tonePlaying = false;
var volume = 0.5;
var guessCounter = 0;

function randNum() {
  pattern.sort(() => Math.random() - Math.random() )

}
function startGame() {
  
  progress = 0;
  // You can reset the guessCounter here every time you start the game
  guessCounter = 0;
  gamePlaying = true;

  document.getElementById("startBtn").classList.add("hidden");
  document.getElementById("stopBtn").classList.remove("hidden");

  playClueSequence();
  
  randNum();
  console.log(pattern.toString())
}

function stopGame() {
  gamePlaying = false;

  document.getElementById("startBtn").classList.remove("hidden");
  document.getElementById("stopBtn").classList.add("hidden");
}

function lightButton(btn){
  document.getElementById("button"+btn).classList.add("lit")
}
function clearButton(btn){
  document.getElementById("button"+btn).classList.remove("lit")
}

function playSingleClue(btn){
  if(gamePlaying){
    lightButton(btn);
    playTone(btn,clueHoldTime);
    setTimeout(clearButton,clueHoldTime,btn);
  }
}

function playClueSequence(){
  // You cannot reset the guessCounter here every time otherwise, the game will not progress
  //guessCounter = 0;
  let delay = nextClueWaitTime; //set delay to initial wait time
  for(let i=0;i<=progress;i++){ // for each clue that is revealed so far
    console.log("play single clue: " + pattern[i] + " in " + delay + "ms")
    setTimeout(playSingleClue,delay,pattern[i]) // set a timeout to play that clue
    delay += clueHoldTime;
    delay += cluePauseTime;
  }
}

function loseGame() {
  stopGame();
  alert("Game Over. You lost.");
}
function winGame() {
  stopGame();
  alert("Yayyyyy, you win!!");
}

function guess(btn) {
  console.log("user guessed: " + btn);
  if (!gamePlaying) {
    return;
  }
  if (pattern[guessCounter] == btn) {
    if (guessCounter == progress) {
      if (progress == pattern.length - 1) {
        winGame();
      } else {
        progress++;
        playClueSequence();
      }
    } else {
      //guessCounter++;
    }
    // You need to increment the guessCounter every time it's a successful guess to move forward to the next pattern element
    guessCounter++;
  } else {
    loseGame();
  }
}
// Sound Synthesis Functions
const freqMap = {
  1: 261.6,
  2: 329.6,
  3: 392,
  4: 466.2,
  5: 432.8,
  6: 336.2
};
function playTone(btn, len) {
  o.frequency.value = freqMap[btn];
  g.gain.setTargetAtTime(volume, context.currentTime + 0.05, 0.025);
  tonePlaying = true;
  setTimeout(function() {
    stopTone();
  }, len);
}
function startTone(btn) {
  if (!tonePlaying) {
    o.frequency.value = freqMap[btn];
    g.gain.setTargetAtTime(volume, context.currentTime + 0.05, 0.025);
    tonePlaying = true;
  }
}
function stopTone() {
  g.gain.setTargetAtTime(0, context.currentTime + 0.05, 0.025);
  tonePlaying = false;
}

//Page Initialization
// Init Sound Synthesizer
var context = new AudioContext();
var o = context.createOscillator();
var g = context.createGain();
g.connect(context.destination);
g.gain.setValueAtTime(0, context.currentTime);
o.connect(g);
o.start(0);
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Hello!</title>

    <!-- import the webpage's stylesheet -->
    <link rel="stylesheet" href="/style.css" />

    <!-- import the webpage's javascript file -->
    <script src="/script.js" defer></script>
  </head>
  <body>
    <h1>Shah's Memory Game</h1>

    <p>
      Welcome to the game that will test your memory!
    </p>

    <button id="startBtn" onclick="startGame()">
      Start
    </button>
    <button id="stopBtn" class="hidden" onclick="stopGame()">
      Stop
    </button>

    <div id="gameButtonArea">
      <button
        id="button1"
        onclick="guess(1)"
        onmousedown="startTone(1)"
        onmouseup="stopTone()"
      >1</button>
      <button
        id="button2"
        onclick="guess(2)"
        onmousedown="startTone(2)"
        onmouseup="stopTone()"
      >2</button>
      <button
        id="button3"
        onclick="guess(3)"
        onmousedown="startTone(3)"
        onmouseup="stopTone()"
      >3</button>
      <button
        id="button4"
        onclick="guess(4)"
        onmousedown="startTone(4)"
        onmouseup="stopTone()"
      >4</button>
      <button
        id="button5"
        onclick="guess(5)"
        onmousedown="startTone(5)"
        onmouseup="stopTone()"
      >5</button>
      <button
        id="button6"
        onclick="guess(6)"
        onmousedown="startTone(6)"
        onmouseup="stopTone()"
      >6</button>
    </div>
  </body>
</html>
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement