Can anyone explain why last line results in NaN? 'userScore' is an object of a span element and similar operations work perfectly fine when I don't implement the localStorage part. Many thanks in advance!
var score;
score = 20 - (parseInt(turnNr.innerHTML) - bricks.length / 2) *
1.2;
if (score >= 0.5) {
score = Math.round(score);
} else {
score = 0;
}
if (localStorage.totalScore) {
localStorage.totalScore = parseInt(localStorage.totalScore) +
score;
} else {
localStorage.totalScore = score;
}
userScore.innerHTML = localStorage.totalScore;
Your code cannot recover from errors. Once you have stored "NaN" in localStorage, it never will go away when the code is executed. That's because if (localStorage.totalScore) will run even when there's an invalid value.
You'll want to change your code to
if (parseInt(localStorage.totalScore)) { // NaN is falsy and will be ignored
localStorage.totalScore = parseInt(localStorage.totalScore) + score;
} else {
localStorage.totalScore = score;
}
userScore.innerHTML = localStorage.totalScore;
Related
I have function of "endgame" and here's how the function goes
function endgame() {
setScreen("scorescreen");
ismytimergoing = false;
appendItem(scorelist, score);
for (var i = 0; i < scorelist.length; i++) {
if (scorelist[i] > scorelist[i +1]) {
highestnumber = scorelist[i];
} else if ((scorelist[i] == scorelist[i + 1])) {
highestnumber = scorelist[i];
} else {
highestnumber = scorelist[i + 1];
}
}
setText("scoretext", (scorelist + " ") + namelist);
}
This is a fairly simple click button game and I have a loop which increases the score after each click, different amounts depending on how much the score currently is.
onEvent("clickbutton", "click", function( ) {
setProperty("gamescreen", "background-color", rgb(randomNumber(1, 250), randomNumber(1, 250), randomNumber(1, 250), 0.5));
if (score < 10) {
level = 1;
setText("levelbutton", "level " + level );
score += 1;
setText("scorecounter", "Score = " + score);
changebutton("clickbutton");
changebutton("dontclickbutton");
}
else if ((score >= 10)) {
level = 2;
setText("levelbutton", "level " + level );
score += 2;
setText("scorecounter", "Score = " + score);
changebutton("clickbutton");
changebutton("dontclickbutton");
}
else if ((score >= 50)) {
level = 3;
setText("levelbutton", "level " + level );
score += 3;
setText("scorecounter", "Score = " + score);
changebutton("clickbutton");
changebutton("dontclickbutton");
}
});
The changebutton is a function that changes the background color and text color of whatever "button" is through in the parameter, but that's not the main point here. The function of "Endgame" is what I'm expereincing difficulties with, so here we go. "endgame" is called at least when the wrong button is clicked and when the time runs out, which ever happens during the game. And in my endgame function I have
setText("scoretext", (scorelist + " ") + namelist);
But what is displayed is a whole bunch of numbers, but what I want to be displayed is the list of scores from highest to lowest with the respective names lined up from the namelist. As a side point my start button takes the user input, sets it as a variable called "name" and appends to my namelist. This is an example of the results, I put in meir for name and that displayed ok, but my score was 5 and it showed up as
0,0,0,0,1,2,2,3,3,4,
4,5,5,5 meir
even though the only that should be in my scorelist is 5, so it shouldn't print out all the other stuff. So if I could get any help on to properly sort the scorelist, and have it only print out the scores, and not whole bunch of numbers that would be great, and preferably have it print out the names in order with the scores from highest scoring names to lowest scoring names, that would be great. Thanks in advance.
Someone saw my code and pointed out at least part of the issue. One of the ways the "endgame" function starts is when the time == 0, and I have in my "endgame" function the following.
ismytimergoing = false;
appendItem(scorelist, score);
so I think
ismytimergoing = false;
stops the timer, but that happens when the timer == 0 so the endgame function is keep on happening constantly increasing the scorelist size making it print out a lot of numbers. so I changed the endgame function to be the following.
function endgame() {
setScreen("scorescreen");
ismytimergoing = false;
seconds = 60;
appendItem(scorelist, score);
for (var i = 0; i < scorelist.length; i++) {
if (scorelist[i] > scorelist[i +1]) {
highestnumber = scorelist[i];
} else if ((scorelist[i] == scorelist[i + 1])) {
highestnumber = scorelist[i];
} else {
highestnumber = scorelist[i + 1];
}
}
setText("scoretext", (scorelist + " ") + namelist);
}
I changed the endgame function, so now even if it happens because of the timer turning to zero, the seconds are reset and it's only run once, thus making the scorelist a much easier thing to deal with.
I'm trying to create a button that when pressed has a 1.04% chance to lead to Page A and a 98.96% chance to lead to Page B. That's my overall goal but the specific aspect I'm having trouble on is the randomization of the results. I'm quite new to javascript so I apologize in advance. Any help is appreciated.
--edit--
I'm incorporating this code into a Wix project and here is the total code I have so far. I started with easy whole numbers 40/60 to make sure I could do it but the smaller percent I'm having trouble incorporating. It's important I have a decimal percentage 1.04 and not 1.00.
import wixLocation from 'wix-location';
let random = 0,counter40 = 0,counter60 = 0;
$w.onReady(function () {
for (var i = 0; i < 10000000; i++) {
random = Math.floor((Math.random() * 100) + 1);
if (random <= 40) {
counter40++;
} else {
counter60++;
}
}
console.log("counter40: " + counter40.toString());
console.log("counter60: " + counter60.toString());
});
export function button1_click(event) {
random = Math.floor((Math.random() * 100) + 1);
if (random <= 40) {
wixLocation.to("/pageB");
} else {
wixLocation.to("/pageC");
}
}
https://jsfiddle.net/ys84pu6a/1/
HTML:
<button id="randomRedirect">
Press me
</button>
JS:
let button = document.getElementById('randomRedirect')
button.addEventListener('click', function() {
let d = Math.random();
if (d < 0.9896)
window.location.href = "pageB.html";
else
window.location.href = "pageA.html";
}, false);
Use the Math.random() function. It returns a random number between 0 and 1.
You could use it this way:
x = Math.random()
if(x < 0.0104){//1.04% chance
window.location.href = [Page A]
}
else{
window.location.href = [Page B]
}
The function that provides pseudo-random values is Math.random().
It returns a floating-point number between 0 and 1.
To get a 1.04% chance, you could simply do this:
let pageAChance = Math.random() <= 0.0104;
I'm doing a memory game and I need to don't repeat the same picture more than twice, so I made a random number generator that repeats till the number isn't in an array. Doing that makes so many requests, so, when repeating the code, it doesn't work so I can't make the second half of the game. I know that the problem is in that because, when making it return the result without checking if it isn't in the array, everything works (but the images repeat, obviously). So, how can I make a function that gives a random number between two values that isn't in an array? I hope this is easy to understand.
Here the function:
function thingForTest() {
let forTest = randomBetweenBut(1, 8, 0);
if (array.includes(forTest)) {
return thingForTest();
} else {
return forTest;
}
}
Here the entire code:
var array = [];
function randomBetweenBut(num1, num2, but) {
function ifThing(num1, num2, but) {
let result = parseInt(Math.random() * (num2 - num1 + 1), 10) + num1;
if (result != but) {
return result;
} else {
return ifThing(num1, num2, but);
}
}
return ifThing(num1, num2, but);
}
function pictureRandomizer() {
for (let i = 1; i < 17; i++) {
let r1;
let picture = document.createElement("img");
function thingForTest() {
let forTest = randomBetweenBut(1, 8, 0);
if (array.includes(forTest)) {
return thingForTest();
} else {
return forTest;
}
}
array.push(thingForTest());
picture.src = "img/" + array[i - 1] + ".jpg";
let cuadrado = document.getElementById("cuadrado-" + i);
cuadrado.appendChild(picture);
if(i == 16 && r1 == false) {
i = 1;
r1 = true;
} else {
r1 = false;
}
}
}
pictureRandomizer();
You can use a function like this to return a random number between a min and a max, excluding any number passed in the exclusionArray. No recursion needed! It also includes a clause to stop infinite loops when a complete exclusionArray is passed.
Should be noted that since we're rerolling a random function, this could loop infinitely if you got REALLY unlucky, so this may not be the best function if your min, max and exclusionArray length are in the millions; But for most applications this should get the job done.
const getRandomWithExclusion = (min, max, exclusionArray) => {
// if exculsionArray contains all possible integers, return null to avoid infinite loop
if (exclusionArray.length > max - min) return null;
let output = null;
// if the randomly generated number is in the exclusionArray, reroll
while(output === null || exclusionArray.includes(output)) {
// simple random range function
output = Math.round(Math.random() * (max - min) + min);
}
return output;
}
.....
I'm trying to learn JavaScript and when I started the MDN Tutorial, I tried to do the first exercise alone, which worked okay so far. But there is one really weird situation.
The Game generates a Random number from 1 - 100 and the User has 10 guesses to find out that number.
I simplified the game to 1 - 10 for this purpose.
When the random number is a 9 and i guess 10, the code says my input was too low. I don't understand why that is. In every other situation, it works exactly as expected.
For debugging reasons, the random number will be shown in the dialog after the first guess.
This is my code:
var number = 0;
var turns = 0;
var guess = 0;
var won = false;
playGame();
function playGame() {
won = false;
number = (Math.random() * 10).toFixed(0);
guess = prompt("Guess a number from 1 to 10");
turns = 0;
while(turns < 10) {
console.log(number + " " + guess);
if(guess < number) {
turns++;
guess = prompt("Number is " + number + ".\n\nYou guessed " + turns + " Times already.\n\nYour guess was to low! Guess again:");
won = false;
} else if(guess > number) {
turns++;
guess = prompt("Number is " + number + ".\n\nYou guessed " + turns + " Times already.\n\nYour guess was to high! Guess again:");
won = false;
} else if(guess === number) {
alert("You got it!");
won = true;
break;
}
}
if(confirm("Wanna play again?")){
playGame()
} else {
alert("kkbye!");
}
}
Thanks in advance. If you see something in my code you'd like to comment, I'd love to hear feedback and become better, even if it isn't directly related to this ;)
The problem is, that you are working with Strings, if you compare two strings with < it will only compare as many characters as it has to until it finds a character that is smaller (smaller being it's Integer representation) than another:
console.log("10" < "9");
Here it will only compare "1" to "9", meaning char code 49 to char code 57.
49 is less than 57, meaning the whole expression is true. You can learn more about the ASCII char codes here.
You should use Numbers instead:
console.log(Number("10") < Number("9"));
You are only dealing with Strings, since both prompt() and Number.toFixed() return Strings. If you encapsulate those in Number() calls your game works:
var number = 0;
var turns = 0;
var guess = 0;
var won = false;
playGame();
function playGame() {
won = false;
number = Number((Math.random() * 10).toFixed(0));
guess = Number(prompt("Guess a number from 1 to 10"));
turns = 0;
while(turns < 10) {
console.log(number + " " + guess);
if(guess < number) {
turns++;
guess = prompt("Number is " + number + ".\n\nYou guessed " + turns + " Times already.\n\nYour guess was too low! Guess again:");
won = false;
} else if(guess > number) {
turns++;
guess = prompt("Number is " + number + ".\n\nYou guessed " + turns + " Times already.\n\nYour guess was too high! Guess again:");
won = false;
} else if(guess === number) {
alert("You got it!");
won = true;
break;
}
}
if(confirm("Wanna play again?")){
playGame()
} else {
alert("kkbye!");
}
}
The Javascript Prompt returns a string. In fact, input text box always returns string. So when you enter 10 it returns "10" and toFixed() will also return string.
So you need to correct two lines from your code
number = parseInt((Math.random() * 10).toFixed(0));
guess = prompt("Guess a number from 1 to 10");
guess = parseInt(guess);
Also you need to check for NAN condition to be on safer side.
The game is WAR, or Get Your Neighbour, a traditional game utilising a standard deck of 52 cards, no jokers. Currently the code recognises when a card is above 10 and so the rules of the game are being followed, all that is great, I've designed a timer that takes the value of the card 2-14, subtracts 10, then uses that number for the round of turns the other player has to draw above 10 before you win. Still building the cooperative/multiplayer element but for now, I'd just like to get this bloody button working!
When I click it, it does nothing. Before, it would tell me that "'timerf' is not a function". I'm probably doing something very obvious like problems with the order that things are loaded/data is parsed, but I'm still learning so I'd appreciate any help! Any questions, let me know.
var card = null; // setem 160517
var timer = null; //
window.onload = function() {
function draw(min, max) { // draw a card between 2-14
card = document.getElementById("draw").innerHTML = Math.floor(Math.random()*((max - min)+1) + min); // min 2, max 14
if (card > 10) {
timer = card - 10;
timerf(timer);
} else if (card < 11 && timer > 0) {
timer = timerf(timer-1);
}
} // draw
//draw(2,14);
document.getElementById("clickMe").onclick = draw(2,14);
} // window.onload
function timerf(timer) { // print turns to win
if (timer > 0 && timer < 5 && timer != 1) { // print turns to win
console.log("you have " + timer + " turns to win!");
} else if (timer == 1) {
console.log("you have " + timer + " turn to win!");
}
}
<div id="draw"></div>
<button id="clickMe">WAR!</button>
The return value of the draw function is undefined because it has no return statement.
document.getElementById("clickMe").onclick = draw(2,14);
… so you are assigning undefined to the onclick property.
You have to assign the function you want to call.