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>