clearInterval is not stopping time consistenly - javascript

I'm creating a simple game of boggle that limits the user to 30 seconds. After that time, the game ends and the results are displayed. The problem is SOMETIMES everything works fine and the "timer" html shows Times Up. Other times, the countdown starts counting backward. My interval id variable is global and initially set to null. I'm not sure what's going on.
function words(x)
{
switch (x)
{
case 1:
var word = new Array("balte","table","hat","tab","belt","lab","eat","tea","ate","tale","bale","let","bet","teal","late","beat");
break;
case 2:
var word = new Array("atwre","water","wet","wear","tear","war","ret","rate","eat","ate","tea","awe","raw","rat","wart","art","tar");
break;
case 3:
var word = new Array("dclaen","can","cane","and","clan","lane","lean","lend","land","den","dean","dance","lance","clean","deal","ale","dale","candle","clad");
break;
case 4:
var word = new Array("aepinlar","air","airplane","plane","plan","lane","lean","pane","ear","near","nap","nape","lair","pen","pan","ape","leap","ale","peal","nap","rap","par", "pare", "pale", "are", "rail", "ail", "pail", "nail", "air", "pair", "ran", "pin", "pine", "line", "nip", "rip", "ripe", "lip", "earn", "learn", "ire");
break;
case 5:
var word = new Array("redykboa","keyboard","key","board","bored","bore","bark","dark","dork","oar","boar","ark","dare","bare","are","red","rod","road","bode","rode","ode","bread", "read", "bead", "bred", "break", "drey", "day", "boy", "broke", "rake", "bake", "ear", "dear", "bear", "dye", "dyer", "doer", "oak", "boa", "doe", "okay","dab", "bade", "ade", "drake", "bard", "yard", "year", "beak", "beard", "bad", "bed", "bay");
break;
case 6:
var word = new Array("evtsaedri","advertise","side","eat","sad","sat","rat","rate","vet","advise","read","rest","vest","serve","served","aside","east","tread","dear","deer","tear","trade","starve","steer","stare","veer","seat","seed","tree","drives","strive");
break;
case 7:
var word = new Array("rcseanbh","branches","bra","she","ran","bran","car","cab","race","ranch","share","bench","bar","char","can","crane","ban","hear","hare");
break;
case 8:
var word = new Array("vradntseue","adventures","vent","dent","stun","dust","rust","vase","sure","ensure","star","vend","dare","tar","starve","trade","sad","eat veer","tear","seat","seed","sand","tree","rest");
break;
case 9:
var word = new Array("wokcnalgede","acknowledge","and","land","wand","wage","ledge","led","lead","lend","leg","gown","know","now","no","lean","wean","week","wed","lack","leak","deal","deck","knew","kneel");
break;
case 10:
var word = new Array("muprith","triumph","hit","hurt","pit","trim","rum","rump","tip","thump","put","rim","him","hum","hip","rut");
break;
}
return word;
}
<html>
<head>
<title>Greg's Gambits | Greg's Game of Boggle</title>
<link href="greg.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="gregBoggle2.js"></script>
<script>
compWords = new Array(); notAword = new Array();
playWords = new Array();
var play = ""; /*var today;*/ var count = 30;
var score = 0; var interval = null;
var quit = false;
function start()
{
/*var start = new Date();
today = start.getTime();*/
timeIt();
boggle();
}
function displayLetters()
{
var num = Math.floor(Math.random()*10) +1;
compWords = words(num);
yourWord = compWords[0];
document.getElementById("letters").innerHTML = yourWord;
}
function timeIt()
{
interval = window.setInterval("countdown()",1000);
}
function countdown()
{
count--;
if (count == 0)
{
window.clearInterval(interval);
interval = null;
document.getElementById("timer").innerHTML = "Time's Up";
var btn =document.getElementById("start");
btn.disabled = true;
quit = true;
checkWin();
return;
}
document.getElementById("timer").innerHTML = count;
}
function boggle()
{
play = document.getElementById("words").value;
if (!quit)
{
playWords.push(play);
displayEntries();
document.getElementById("words").value = "";
document.getElementById("words").focus();
}
else
{
document.getElementById("words").value = "";
document.getElementById("words").focus();
checkWin();
}
}
function displayEntries()
{
document.getElementById("entries").innerHTML = playWords.toString();
}
/*function toMinutesAndSeconds(millis)
{
var minutes = Math.floor(millis/60000);
var seconds = ((millis%60000)/1000).toFixed(0);
return minutes + ":" + ((seconds < 10 ? '0' : "")+ seconds);
}*/
function checkWin()
{
// check winning score and list bad words
var complgth = compWords.length;
var playlgth = (playWords.length);
var flag; var timePlayed;
/*var endTime = new Date().getTime();
var diff = endTime - today;
timePlayed = toMinutesAndSeconds(diff);*/
for (var i = 0; i < playlgth; i++)
{
flag = 0;
for (var k = 0; k < complgth; k++)
{
if (playWords[i] == compWords[k])
{
score= score + 1;
flag = 1;
}
}
if (flag == 0)
notAword.push(playWords[i]);
}
document.getElementById("result").innerHTML = ("Your score is " +
score + ". The following entries " + "are not valid words: <br />" +
notAword.toString());
/*document.getElementById("timer").innerHTML = ("Your time: " + timePlayed);*/
}
</script>
</head>
<body>
<div id="container">
<img src="images/superhero.jpg" width="120" height="120" class="floatleft" />
<h1 align="center"><em>Greg's Game of Boggle</em></h1>
<div style = "clear:both;"></div>
<div id = "nav">
<p>Home
About
Play a Game
Sign In
Contact Us</p>
</div>
<div id="content">
<p>The object of the game is to create as many words as
you can. Please click the Display letters button and your letters will
be shown below. You have 10 possible letter combinations and 30 seconds. When you are ready to begin, enter the word then click the Submit Word button. The timer will start after first entered word.</p>
<p><input type="button" value="Display letters" onclick="displayLetters();" /><br/>
<input type="text" id="words">
<input type="button" id="start" value="Submit Word" onclick="start();" />
</p>
<h2><br /><br />Letters you can use:<br /><div id="letters"> </div><br /></h2>
<h2>Your words so far: <br /><div id="entries"> </div><br /></h2>
<h2>Results:<br /><div id="result"> </div></h2>
<h2>Timer: <br /><div id="timer"> </div></h2>
</div>
<div id="footer">Copyright © 2013 Greg's Gambits<br />
foulksy#gmail.com
</div>
</div>
</body>
</html>

Every time you submit a word, you call your start() function which calls timeIt(). Your solution works if you only submit one word, but if you submit multiple, you'll run into the issue where you see a negative timer.
I believe you have to clear the previous setInterval before creating a new one and storing it on your interval variable:
function timeIt()
{
window.clearInterval(interval);
interval = window.setInterval(countdown, 1000);
}

You should replace this line
interval = window.setInterval("countdown()",1000);
with the following
interval = window.setInterval(countdown, 1000);
You need to pass a function as the first parameter which can be called by the timer. You pass a string, which can't be called.
More information here.

Not sure if this is why it's failing, but setInterval takes a function as its first argument, not a string. It should be setInterval(countdown, 1000) not setInterval("countdown()", 1000).

Related

How to correct my wpm formula in JavaScript?

I am a learning student, Currently I am working on a typing website. I am using codingartist code as base. I have done some modification in this code. At the time variable I am taking value from user with the help of select option menu, so this is my time variable :
let time = parseInt(document.getElementById("time-select").value);
This is my html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Typing Test</title>
<!-- Google Fonts -->
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght#400;600&display=swap"
rel="stylesheet"
/>
<!-- Stylesheet -->
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="select">
<label for="time-select">Select time:</label>
<select id="time-select">
<option value="60">1 minute</option>
<option value="90" selected>1.5 minutes</option>
<option value="120">2 minutes</option>
<option value="300">5 minutes</option>
<option value="480">8 minutes</option>
<option value="600" >10 minutes</option>
</select>
</div>
<div class="stats">
<p>Time: <span id="timer">0s</span></p>
<p>Mistakes: <span id="mistakes">0</span></p>
</div>
<div
id="quote"
onmousedown="return false"
onselectstart="return false"
></div>
<textarea
rows="3"
id="quote-input"
placeholder="Type here when the test starts.."
></textarea>
<button id="start-test" onclick="startTest()">Start Test</button>
<button id="stop-test" onclick="displayResult()">Stop Test</button>
<div class="result">
<h3>Result</h3>
<div class="wrapper">
<p>Accuracy: <span id="accuracy"></span></p>
<p>Speed: <span id="wpm"></span></p>
</div>
</div>
</div>
<!-- Script -->
<script src="script.js"></script>
</body>
</html>
This is my index.js
//Random Quotes Api URL
const quoteApiUrl = "https://api.quotable.io/random?minLength=80&maxLength=100";
const quoteSection = document.getElementById("quote");
const userInput = document.getElementById("quote-input");
let quote = "";
let time = parseInt(document.getElementById("time-select").value);
let timer = "";
let mistakes = 0;
function updateTime() {
// Get the new time value from the dropdown menu
let time = parseInt(document.getElementById("time-select").value);
// Update the timer display
document.getElementById("timer").innerText = time + "s";
}
// Add an event listener to the dropdown menu to call the updateTime function when the value changes
document.getElementById("time-select").addEventListener("change", updateTime);
//Display random quotes
const renderNewQuote = async () => {
//Fetch contents from url
const response = await fetch(quoteApiUrl);
//Store response
let data = await response.json();
//Access quote
quote = data.content;
//Array of characters in the quote
let arr = quote.split("").map((value) => {
//wrap the characters in a span tag
return "<span class='quote-chars'>" + value + "</span>";
});
//join array for displaying
quoteSection.innerHTML += arr.join("");
};
//Logic for comparing input words with quote
userInput.addEventListener("input", () => {
let quoteChars = document.querySelectorAll(".quote-chars");
//Create an arrat from received span tags
quoteChars = Array.from(quoteChars);
//array of user input characters
let userInputChars = userInput.value.split("");
//loop through each character in quote
quoteChars.forEach((char, index) => {
//Check if char(quote character) = userInputChars[index](input character)
if (char.innerText == userInputChars[index]) {
char.classList.add("success");
}
//If user hasn't entered anything or backspaced
else if (userInputChars[index] == null) {
//Remove class if any
if (char.classList.contains("success")) {
char.classList.remove("success");
} else {
char.classList.remove("fail");
}
}
//If user enter wrong character
else {
//Checks if we alreasy have added fail class
if (!char.classList.contains("fail")) {
//increment and display mistakes
mistakes += 1;
char.classList.add("fail");
}
document.getElementById("mistakes").innerText = mistakes;
}
//Returns true if all the characters are entered correctly
let check = quoteChars.every((element) => {
return element.classList.contains("success");
});
//End test if all characters are correct
if (check) {
displayResult();
}
});
});
//Update Timer on screen
function updateTimer() {
if (time == 0) {
//End test if timer reaches 0
displayResult();
} else {
document.getElementById("timer").innerText = --time + "s";
}
}
//Sets timer
const timeReduce = () => {
time = parseInt(time);
timer = setInterval(updateTimer, 1000);
};
//End Test
const displayResult = () => {
//display result div
document.querySelector(".result").style.display = "block";
clearInterval(timer);
document.getElementById("stop-test").style.display = "none";
userInput.disabled = true;
let timeTaken = 1;
if (time != 0) {
timeTaken = (60 - time) / 60;
}
document.getElementById("wpm").innerText =
(userInput.value.length / 5 / timeTaken).toFixed(2) + " wpm";
document.getElementById("accuracy").innerText =
Math.round(
((userInput.value.length - mistakes) / userInput.value.length) * 100
) + " %";
};
//Start Test
const startTest = () => {
mistakes = 0;
timer = "";
userInput.disabled = false;
timeReduce();
document.getElementById("start-test").style.display = "none";
document.getElementById("stop-test").style.display = "block";
};
window.onload = () => {
userInput.value = "";
document.getElementById("start-test").style.display = "block";
document.getElementById("stop-test").style.display = "none";
userInput.disabled = true;
renderNewQuote();
};
I am trying to create a typing test that measures the words per minute (WPM) of the user's input. However, the WPM calculation is not giving the correct results. When I test the code, the WPM value is always much higher or as same as word typed (even if i take 2min. for typing) than expected.
let timeTaken = 1;
if (time != 0) {
timeTaken = (60 - time) / 60;
}
document.getElementById("wpm").innerText =
(userInput.value.length / 5 / timeTaken).toFixed(2) + " wpm";
I know given code is wrong with 60 default value. so i tried this:
let remainTime = time - parseInt(timer);
let timeTaken = time - remainTime;
but it also gives doesn't give correct wpm value.
Try this I am sure that it will work as per my research:
let timerLengthInput = document.getElementById("time-select");
const timerLength = timerLengthInput.value;
let time = timerLength;
and write the in your displayResult-
let timeTaken = 1;
if (time !== 0) {
timeTaken = (timerLength - time) / 60;
}
document.getElementById("wpm").innerText =
(userInput.value.length / 5 / timeTaken).toFixed(2) + " wpm";
timeReduce function-
const timeReduce = () => {
timer = setInterval(updateTimer, 1000);
};

My JS timer clock is not stopping when clicked twice on start button [duplicate]

This question already has an answer here:
JavaScript countdown timer with on key press to reset the timer
(1 answer)
Closed 11 months ago.
I have a simple HTML stopwatch logic where I can start and stop the clock with the button click. By clicking on the start button, one can start the timer (shows current time) and update every second. One can stop it by clicking stop button. But if one clicks on start button twice, there is nothing I can do to stop the timer. Below is my code:
var hour = document.getElementById("hoursOut");
var minute = document.getElementById("minsOut");
var second = document.getElementById("secsOut");
var btnStart = document.getElementById("btnStart");
var btnStop = document.getElementById("btnStop");
var waitTimer;
function displayTime() {
var currentTime = new Date();
var currentHour = currentTime.getHours();
var currentMinute = currentTime.getMinutes();
var currentSeconds = currentTime.getSeconds();
hour.innerHTML = twoDigit(currentHour) + ":";
minute.innerHTML = twoDigit(currentMinute) + ":";
second.innerHTML = twoDigit(currentSeconds);
}
function twoDigit(digit) {
if (digit < 10) {
digit = "0" + digit;
}
return digit;
}
function startClock() {
waitTimer = setInterval(displayTime, 1000);
}
function stopClock() {
clearInterval(waitTimer);
}
btnStart.onclick = startClock;
btnStop.onclick = stopClock;
<h1>JavaScript Clock</h1>
<div id="calendarBox">
<!-- OUTPUT TIME VALUES -->
<p class="timeDisplay">
<span id="hoursOut">00:</span>
<span id="minsOut">00:</span>
<span id="secsOut">00</span>
</p>
<!-- BUTTON SET -->
<input id="btnStart" type="button" value="START" />
<input id="btnStop" type="button" value="STOP" />
</div>
I have checked some answers in stackoverflow but most solutions uses a for-loop from 0 to 1000 until it finds the interval id and stop all of them using loop. I am confident there should be an elegant solution than that.
// some stackoverflow suggested answer
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
A possible solution is to prevent the problem before it happens. You can place a check on the running timer (Is there a way to check if a var is using setInterval()?).
In this case you could just have a global timer variable var timer = false the with add a check to the start function. Then the stop function will set the timer variable back to false.
function startClock() {
if(!timer){
timer = true
waitTimer = setInterval(displayTime, 1000);
}
else return
}
function stopClock() {
clearInterval(waitTimer);
timer = false
}
when you double click you start a new setInterval(). So you now have two set intervals running. Only problem is you can't access the first one cause you named the second one the same name. Check if waitTimer exists and if it does stop it. see code:
UPDATE: actually you don't even need an if statement. just call stopClock() before you set waitTimer -- code snippet adjusted
var hour = document.getElementById("hoursOut");
var minute = document.getElementById("minsOut");
var second = document.getElementById("secsOut");
var btnStart = document.getElementById("btnStart");
var btnStop = document.getElementById("btnStop");
var waitTimer;
function displayTime() {
var currentTime = new Date();
var currentHour = currentTime.getHours();
var currentMinute = currentTime.getMinutes();
var currentSeconds = currentTime.getSeconds();
hour.innerHTML = twoDigit(currentHour) + ":";
minute.innerHTML = twoDigit(currentMinute) + ":";
second.innerHTML = twoDigit(currentSeconds);
}
function twoDigit(digit) {
if (digit < 10) {
digit = "0" + digit;
}
return digit;
}
function startClock() {
stopClock();
waitTimer = setInterval(displayTime, 1000);
}
function stopClock() {
clearInterval(waitTimer);
}
btnStart.onclick = startClock;
btnStop.onclick = stopClock;
<h1>JavaScript Clock</h1>
<div id="calendarBox">
<!-- OUTPUT TIME VALUES -->
<p class="timeDisplay">
<span id="hoursOut">00:</span>
<span id="minsOut">00:</span>
<span id="secsOut">00</span>
</p>
<!-- BUTTON SET -->
<input id="btnStart" type="button" value="START" />
<input id="btnStop" type="button" value="STOP" />
</div>

Why am I getting 1 number short of my inputted number e.g 10 outputs 9

Building a countdown Timer with rounds, working and resting for training.
Issue: My timer seems to start fine (with the user inputted values) after the first round, once rest is done, my working timer doesn't start at the inputted value like it should. It's always one number short.
E.g If you input 5: 10: 10. When it comes back around, it will appear one number shorter than it should 4: 09: 00
From the left the Timer is rounds, working, rest.
Please help.
let rnd = '00';
let wrk = 00; // this will act as my seconds
let rst = '00';
let prepare =3;
let interval;
let rstInterval;
let startTimer = '00';
// store the working set in an array
let prepIn = document.getElementById('prep');
prepIn.innerHTML = prepare;
// buttons
document.getElementById('start').addEventListener('click', initTimer);
document.getElementById('pause').addEventListener('click', pauseTimer);
document.getElementById('reset').addEventListener('click', finishTimer);
let span= document.getElementById('app').getElementsByTagName('span');
function initTimer(){
clearInterval(interval)
let rounds = document.querySelector('.rounds').value;
rnd = rounds;
span[0].innerHTML = rnd
let work = document.querySelector('.work').value;
wrk = work;
startTimer = work;
span[1].innerHTML =wrk
let rest = document.querySelector('.rest').value;
rst = rest;
span[2].innerHTML = rst
console.log(startTimer)
interval= setInterval(countDown, 1000);
}
// Pause the timer
function pauseTimer(){
clearInterval(interval);
console.log("pauseTimer")
}
// reset timer
function finishTimer(){
clearInterval(interval);
span[0].innerHTML = '00'
span[1].innerHTML = '00'
span[2].innerHTML = '00'
rnd = '00';
wrk = '00';
rst = '00';
document.querySelector('.timeNum').style.display = "flex"
}
function countDown(){
prepare--
if(prepare < 10){
prepIn.innerHTML = '0' + prepare;
}
if(prepare >=9){
prepIn.innerHTML = prepare;
}
if(prepare <= 3){
prepIn.style.color = 'green';
}
if(prepare < 1){
clearInterval(interval)
prepare = 00
prepIn.style.display = 'none'
clearInterval(startTimer)
startTimer= setInterval(timerActive, 1000);
let work = document.querySelector('.work').value;
wrk = work;
console.log(wrk)
}
document.querySelector('.timeNum').style.display = "none";
}
function timerActive(){
wrk--
if(wrk <=9){
span[1].innerHTML = '0' + wrk;
}
if(wrk >=10){
span[1].innerHTML = wrk;
}
if(wrk <= 0){
clearInterval(startTimer)
let rest = document.querySelector('.rest').value;
rst = rest
let rstInterval = setInterval(() => {
rst--
if(rst<=9){
span[2].innerHTML = '0' + rst;
}
if(rst >=10){
span[2].innerHTML = rst;
}
if(rst < 1){
clearInterval(rstInterval)
rstcount();
}
},1000)
rnd--
if(rnd <10){
span[0].innerHTML = '0'+ rnd;
}
else{
span[0].innerHTML = rnd;
}
}
};
function rstcount(){
clearInterval(rstInterval);
countDown();
}
<div class="timer">
<div class="numb">
<h2 id="prep"></h2>
<h2 id="app"><span>00</span>:<span>00</span>:<span>00</span></h2>
<h1 class="timeNum"><input type='number' min="00" max="99" class="rounds" value='00'>:<input type='number' min="00" max="99" class="work" value="00">:<input type='number' min="00" max="99" class="rest" value="00"></h1>
<div class="buttons">
<input type="button" id="start" value="Start">
<input type="button" id="pause" value="Pause">
<input type="button" id="reset" value="Reset">
</div>
</div>
</div>

How to decrement each click of the animation

I am trying to create animation game. Animation game must consits of One image alternating with another every half a second. I am intended to count++ on each click of the happy-face fish and count-- on each sad-face fish clicked. But, my code is only incrementing, whatever the image is clicked. Also,my code shows me two different images while It must have to be only one.
I have to count a click while my animation is running ( animation: images should be alternating every half a second. It will look like fish is smiling for half second and then crying for another half second then repeats). If i click on happy face, I will score 1 and if click on sad-face I will lose 1. In the end it must show you win if i achieve 10 and resets again on clicking Start Animation.
[Output should be like this:][1]
var image = "happy";
var totalscore = 0;
var counter = 0;
var Schedule;
function happyFish() {
totalscore++;
var happyclickSpan = document.getElementById("score");
happyclickSpan.innerHTML = totalscore;
counter = counter + 1;
if (counter == 10) {
clearInterval(Schedule);
var finalwords = document.getElementById("d");
finalwords.innerHTML = "Your Score:" + counter + " Game Over. You Win!";
}
}
function sadFish() {
totalscore--;
var sadclickSpan = document.getElementById("score");
sadclickSpan.innerHTML = totalscore;
counter = counter - 1;
if (counter == -10) {
clearInterval(Schedule);
var finalwords = document.getElementById("d");
finalwords.innerHTML = "Your Score:" + counter + " Game Over. You Lose!";
}
}
function StartAnimation() {
counter = 0;
totalscore = 0;
fish_img = document.getElementById("happy_fish");
f_img = document.getElementById("happy_fish");
fish_img.classList.add('on');
Schedule = setInterval(animationfunction, 500);
}
function animationfunction() {
if (image == "happy") {
image = "sad";
fish_img.src = "https://www.uow.edu.au/~dong/w3/assignment/a5/sad_fish.png";
} else {
image = "happy";
fish_img.src =
"https://www.uow.edu.au/~dong/w3/assignment/a5/happy_fish.png";
}
}
<img src="https://www.uow.edu.au/~dong/w3/assignment/a5/happy_fish.png" alt="" id="happy_fish" onClick="happyFish()">
<img src="https://www.uow.edu.au/~dong/w3/assignment/a5/sad_fish.png" alt="" id="sad_fish" onClick="sadFish()">
<br>
<h1 id="d">
Your Score: <span id="score">0</span>
</h1>
I modified your StartAnimation and animationfunction methods to make the fish dissapear with a toggle instead of trying to modify the source of the image.
I made it with a css class off which will make a fish dissapear with display: none;
var totalscore = 0;
var counter = 0;
var Schedule;
function happyFish() {
totalscore++;
var happyclickSpan = document.getElementById("score");
happyclickSpan.innerHTML = totalscore;
counter = counter + 1;
if (counter == 10) {
clearInterval(Schedule);
var finalwords = document.getElementById("d");
finalwords.innerHTML = "Your Score:" + counter + " Game Over. You Win!";
}
}
function sadFish() {
totalscore--;
var sadclickSpan = document.getElementById("score");
sadclickSpan.innerHTML = totalscore;
counter = counter - 1;
if (counter == -10) {
clearInterval(Schedule);
var finalwords = document.getElementById("d");
finalwords.innerHTML = "Your Score:" + counter + " Game Over. You Lose!";
}
}
function StartAnimation() {
counter = 0;
totalscore = 0;
var initialWords = document.getElementById("d");
initialWords.innerHTML = "Your Score: <span id=\"score\">0</span>";
Schedule = setInterval(animationfunction, 500);
}
function animationfunction() {
var fish_img = document.getElementById("happy_fish");
var f_img = document.getElementById("sad_fish");
fish_img.classList.toggle('off');
f_img.classList.toggle('off');
}
.off {
display: none;
}
<button onClick="StartAnimation()">Start Animation</button>
<br>
<img src="https://www.uow.edu.au/~dong/w3/assignment/a5/happy_fish.png" alt="happy" id="happy_fish" onClick="happyFish()">
<img src="https://www.uow.edu.au/~dong/w3/assignment/a5/sad_fish.png" alt="sad" id="sad_fish" class="off" onClick="sadFish()">
<br>
<h1 id="d">
Your Score: <span id="score">0</span>
</h1>
You can make things a lot simpler by having one img element and one click handler.
In the snippet I merged the two click handlers into one and added a check for the state of the fish (being represented now by the boolean isHappy).
I attached this handler to a single img element in your HTML and in the animation function I alternate its src attribute between the happy and sad fish according to the isHappy state.
Additionally, Since the counter and the total score are the same, I use only the total score variable.
var isHappy = true;
var totalscore;
var Schedule;
function clickFish() {
if (isHappy) {
totalscore++;
} else {
totalscore--;
}
var scoreSpan = document.getElementById("score");
scoreSpan.innerHTML = totalscore;
if (totalscore === 10) {
clearInterval(Schedule);
var finalwords = document.getElementById("d");
finalwords.innerHTML = "Your Score:" + totalscore + " Game Over. You Win!";
}
}
function StartAnimation() {
isHappy = true
totalscore = 0;
clearInterval(Schedule);
Schedule = setInterval(animationfunction, 500);
}
function animationfunction() {
fish_img = document.getElementById("fish");
isHappy = !isHappy;
if (isHappy) {
fish_img.src = "https://www.uow.edu.au/~dong/w3/assignment/a5/happy_fish.png";
} else {
fish_img.src = "https://www.uow.edu.au/~dong/w3/assignment/a5/sad_fish.png";
}
}
<button onclick="StartAnimation()">Start animation</button><br />
<img src="https://www.uow.edu.au/~dong/w3/assignment/a5/happy_fish.png" alt="" id="fish" onClick="clickFish()">
<br>
<h1 id="d">
Your Score:
<span id="score">0</span>
</h1>

How to reset variables to original, vanilla Javascript?

I'm making a simple hangman game in vanilla javascript and would like the game to reset after a player losses. Specifically, I'd like to:
1. reset the "guessRemain" variable
2. clear out the "guess" id, so none of the guessed letters are shown
3. choose another random word from the array.
Thanks in advance for your help!
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Hangman Game</title>
<link rel="stylesheet" type="text/css" href="assets\css\reset.css"/>
<link rel="stylesheet" type="text/css" href="assets\css\style.css">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<script src="https://use.fontawesome.com/ca6de464ee.js"></script>
</head>
<body>
<div id="white">
<img src="assets\images\turkey.png" alt="turkey" class="turkeyImage">
</div>
<div id="orangebox">
<h4>thanksgiving</h4>
<h4 class="hangman">hangman</h4>
</div>
<div class="instructions">
<h1>Instructions:</h1>
<br/>
<h2>1. Guess a Thanksgiving dish!</h2>
<br/>
<h3>2. Press any key to begin.</h3>
</div>
<div class="display">
<p class="greywords">Current Word:</p>
<br/>
<p id="current"></p>
<br/>
<br/>
<p class ="greywords">Number of Guesses Remaining:</p>
<br/>
<p id="remain"></p>
<br>
<br/>
<p class="greywords">Letters Already Guessed:</p>
<p id="guess"></p>
<br>
<br/>
<p class="greywords">Wins:</p>
<p id="win"></p>
<br>
<br/>
<p class="greywords">Losses:</p>
<p id="loss"></p>
</div>
<!-- End of HTML -->
<script type="text/javascript">
// Step 2: create variable of the food words
var wins = 1;
var losses = 1;
var guessRemain = 10;
var foodWords = [
"pie",
"turkey",
"bacon",
"bread"
];
// Step 1: display remaining gueses
document.getElementById("remain").innerHTML = guessRemain;
// Step 3: create a variable to pick a random word from that array
var randomWord = foodWords[Math.floor(Math.random() * foodWords.length)];
console.log(randomWord);
//Step 4: make it count the number of letters in that word that you just picked
var count = [];
for (var i = 0; i < randomWord.length; i++) {
count[i] = "_ ";
}
//Step 5: write the var on the screen
document.getElementById("current").innerHTML = count;
//Step 6: have it recognize that there are remaining letters
var remainingLetters = randomWord.length;
console.log("I HAVE " + remainingLetters + " left");
//Step 7: function for when they click a key
document.onkeyup=function(event) {
var userGuess = event.key;
document.getElementById("guess").innerHTML += userGuess + " ";
// console.log(randomWord.length);
if (randomWord.includes(userGuess)) {
// console.log("test");
// Step 7: if this statment is true, then modify the count variable, replace the dash in count with letter, and it has the correct position, and display the letter
var guessIndex = randomWord.indexOf(userGuess);
//console.log(randomWord.indexOf(userGuess));
count[guessIndex] = userGuess
//console.log(count);
document.getElementById("current").innerHTML = count;
remainingLetters--;
console.log("I HAVE " + remainingLetters + " left");
if (remainingLetters === 0) {
document.getElementById("win").innerHTML = wins++;
console.log("I have won");}
}
// Step 8: if not true, then subtract a guess
else {
document.getElementById("remain").innerHTML = guessRemain--;
document.getElementById("remain").innerHTML = guessRemain;
if (guessRemain === 0) {
document.getElementById("loss").innerHTML = losses++;
console.log("I have lost");
}
}
}
// Step 10: if there are no letters remaining in count, then add "1" to the win id and reset the page
// if (remainingLetters === 0) {
// document.getElementById("#win").innerHTML = winSs++;
// console.log("I have won");
//console.log("i win");
// function reset() {
// document.getElementById("display").reset();
// }
// }
// Step 11: if there are no guesses remaining, add a "1" to the loss id and reset the page
// if (remainingGuess < 0) {
// document.getElementById("#loss").innerHTML = ++1;
// function reset() {
// document.getElementById("display").reset();
// }
// }
</script>
</body>
<div class="footer">
</div>
</html>
Simply set the variable, so to "reset" guessRemain you'd just type
guessRemain = 10;
inside your reset function, The same would go for any other variables.
As for the Guesses already displayed on the web page, you'd do something similar to this
document.getElementById("guess").innerHTML = "";
Hope that helps :)
First off, clear the guess element somewhere in steps 1-6 by setting its innerHTML to an empty string. Take your steps 1-6 and put them in a function called initialize like so:
Edit: declare your variables wins, losses, guessRemain, foodWords, randomWords, count, remainingLetters outside of the function below so that you'll have access to them in your onkeyup handler
var wins, losses, guessRemain, foodWords, randomWords, count, remainingLetters;
function initialize() {
// Step 1: create variable of the food words
wins = 1;
losses = 1;
guessRemain = 10;
foodWords = [
"pie",
"turkey",
"bacon",
"bread"
];
// Clear the guess
document.getElementById("guess").innerHTML = "";
// Step 2: display remaining gueses
document.getElementById("remain").innerHTML = guessRemain;
// Step 3: create a variable to pick a random word from that array
randomWord = foodWords[Math.floor(Math.random() * foodWords.length)];
console.log(randomWord);
//Step 4: make it count the number of letters in that word that you just picked
count = [];
for (var i = 0; i < randomWord.length; i++) {
count[i] = "_ ";
}
//Step 5: write the var on the screen
document.getElementById("current").innerHTML = count;
//Step 6: have it recognize that there are remaining letters
remainingLetters = randomWord.length;
console.log("I HAVE " + remainingLetters + " left");
}
Call the function initialize() somewhere in your code (outside of the onkeyup handler) to initialize your game for the first time.
Now, you can reuse the initialize function whenever you want to reset your game. For example, you can do something like this when the game is over (place this code inside your onkeyup handler towards the bottom):
if (remainingLetters === 0 || remainingGuess === 0) {
inititalize();
}

Categories

Resources