I don't understand why the "alert" from the if/else conditioning always gets me an error - while its defenetly not!
I tried to change it to "switch" , get the variables inside and out the function , but none of this helped.
const randomNumb = {
x: Math.round((Math.random()) * 10 + 1),
y: Math.round((Math.random()) * 10 + 1)
};
const action1 = document.querySelector("#theAction");
const firstNum = document.querySelectorAll("#numbers")[0];
const secondNum = document.querySelectorAll("#numbers")[1];
firstNum.innerHTML = randomNumb.x;
secondNum.innerHTML = randomNumb.y;
if (firstNum > secondNum) {
action1.innerHTML = "-";
} else {
action1.innerHTML = "+";
}
const answer1 = randomNumb.x - randomNumb.y;
const answer2 = randomNumb.x + randomNumb.y;
const checkButton = document.querySelector("input[type=button][value=Check]");
const checkAnswer = document.querySelector("input[type=text]");
const theValue = checkAnswer.value;
checkButton.onclick = function() {
if (theValue === answer1 || theValue === answer2){
alert("Correct!")
} else {
alert("Error")
}
location.reload();
};
I'm trying to do that when I'm putting the correct answer in the "checkAnswer" it will put correct. if not , Error.
but it keeps giving me "Error" all the time.
Any suggestions ? (maybe I could write the code better in general?)
To verify to yourself check this link and check what type of an object you are trying to compare in your if/else statement.
const action1 = document.querySelector("#theAction");
const firstNum = document.querySelectorAll("#numbers")[0]; // this is a HTML element
const secondNum = document.querySelectorAll("#numbers")[1];
firstNum.innerHTML = randomNumb.x;
secondNum.innerHTML = randomNumb.y;
if (firstNum > secondNum) { // comparision is not possible
action1.innerHTML = "-";
} else {
action1.innerHTML = "+";
}
Let's access the value inside the HTML element and cast it to Number() for example
if (Number(firstNum.innerHTML) > Number(secondNum)) { // comparision is possible
action1.innerHTML = "-";
} else {
action1.innerHTML = "+";
}
this will solve the issue you are currently having, cheers!
I solved it!
checkButton.onclick = function() {
const theValue = checkAnswer.value;
if (theValue === answer1){
alert("correct")
} else if (theValue == answer2){
alert("correct")
} else {
alert("error")
};
};
Related
I have a problem with regex.
In my code I have an input when a player can write his name and then click the 'start' button to start the adventure.
The first condition is working fine. The player gets an error when the name isn't between 4 and 20 characters long.
When it comes to the next condition. The player gets an error no matter what will he write inside the input. When I changed the match() to test() there is an error in console, that the test() is not a function.
Please help me, what did I do wrong?
let actualPlace = 'mainMenu';
let playerName = '';
const playerNameContainer = document.querySelector('.playerName');
const start = document.querySelector('.start');
const regExpression = /^[a-zA-ZżźćńółęąśŻŹĆĄŚĘŁÓŃ0-9]$/;
start.addEventListener('click', function(){
if (actualPlace == 'mainMenu') {
playerNameValue = playerNameContainer.value;
playerNameLength = playerNameValue.length;
if (playerNameLength >= 4 && playerNameLength <= 20) {
if (playerNameValue.match(regExpression)) {
actualPlace = 'adventure';
playerName = playerNameContainer.value;
playerNameContainer.value = '';
} else {
errorMsg.innerHTML = 'error';
}
} else {
errorMsg.innerHTML = 'error';
}
}
})
your regular expression is matching only one single character; you need to add the + quantifier to match more than one character.
I also added different errors so you know what part is failing
Here its a working example:
let actualPlace = 'mainMenu';
let playerName = '';
const playerNameContainer = document.querySelector('.playerName');
const start = document.querySelector('.start');
const regExpression = /^[a-zA-ZżźćńółęąśŻŹĆĄŚĘŁÓŃ0-9]+$/;
const errorMsg = document.querySelector('.error');
start.addEventListener('click', function(){
if (actualPlace == 'mainMenu') {
playerNameValue = playerNameContainer.value;
playerNameLength = playerNameValue.length;
if (playerNameLength >= 4 && playerNameLength <= 20) {
if (playerNameValue.match(regExpression)) {
actualPlace = 'adventure';
playerName = playerNameContainer.value;
playerNameContainer.value = '';
errorMsg.innerHTML = 'Success!';
} else {
errorMsg.innerHTML = 'error: your name must not contain spetial characters';
}
} else {
errorMsg.innerHTML = 'error: your name must be between 4 and 20 characters';
}
}
})
<input class="playerName" /><br />
<button class="start" >Start</button>
<div class="error" ></div>
I'm trying to build some things with pure Javascript, just for learning purposes. So, I have a calculator of some sort that takes 3 numbers and returns the area of a triangle based on those numbers. The behavior can be observed here: https://peaceful-johnson-bd9090.netlify.app/pages/ariaoftriangle/ariaoftriangle
I have the complete code in a sandbox, here https://codesandbox.io/s/gif59 but for some reason is working one out of ten times, that's why I added the Netlify link.
I'm having a problem with the printNumberToPage function, in a sense that after I press the CALCULATE button, the numbered buttons don't work anymore, unless I'm refreshing the page. I am assuming it's a behavior of Javascript that I don't correctly understand? But if so, Googling didn't really help because I have no idea what to search for. Is this normal? Can printNumberToPage only work again after a page refresh?
This is the Javascript code:
const elements = document.querySelectorAll('.side');
const textTarget = document.getElementById('textTarget');
let text = textTarget.innerHTML;
let arrayToPushTo = [];
const changeBgImage = () => {
const triangleImage = document.getElementById('triangle');
let imgUrl = triangleImage.style.backgroundImage;
switch (imgUrl) {
case 'url("../../images/TB.png")':
triangleImage.style.backgroundImage = "url('../../images/TRed.png')";
imgUrl = triangleImage.style.backgroundImage;
break;
case 'url("../../images/TRed.png")':
triangleImage.style.backgroundImage = "url('../../images/TBlue.png')";
imgUrl = triangleImage.style.backgroundImage;
break;
case 'url("../../images/TBlue.png")':
triangleImage.style.backgroundImage = "url('../../images/TOrange.png')";
imgUrl = triangleImage.style.backgroundImage;
break;
case 'url("../../images/TOrange.png")':
triangleImage.style.backgroundImage = "url('../../images/TB.png')";
imgUrl = triangleImage.style.backgroundImage;
break;
default:
break;
}
};
const printNumberToPage = (event) => {
changeBgImage();
arrayToPushTo.length > 1 ? (text += event.target.value + ' ') : (text += event.target.value + ' ' + 'X' + ' ');
arrayToPushTo.push(event.target.value);
textTarget.innerHTML = text;
if (arrayToPushTo.length > 2) {
elements.forEach((element) => {
element.disabled = true;
});
}
};
elements.forEach(function (element) {
element.addEventListener('click', printNumberToPage);
});
const calcButton = document.getElementById('calc');
calcButton.addEventListener('click', () => calculateArea(text));
const calculateArea = (string) => {
changeBgImage();
if (string) {
const stringToArray = string.split('');
const finalArray = stringToArray.filter((char) => char !== ' ' && char !== 'X');
const num1 = finalArray[0];
const num2 = finalArray[1];
const num3 = finalArray[2];
const result = num1 * num2 * num3;
textTarget.innerHTML = result;
text = ' ';
arrayToPushTo = [];
return result;
} else {
console.log('Please select a number');
}
};
At the moment I have an if the condition that checks if any of the string variable lengths is greater than 2 if true check for another condition, else console.log the output.
var previous_data_change = 'last_changed on 10/01/2019 13:56:34';
var current_data_change= "";
var current_data_end = "";
var current_data_profile = "normal";
// check for changes
if (
previous_data_change.length >= 2 ||
current_data_start.length >= 2 ||
current_data_end.length >= 2 ||
current_data_profile.length >= 2
) {
if (previous_data_change.includes("last_changed")) {
console.log(`last change comments: ${previous_data_change}`)
}
} else {
console.log(`no change in previous record`)
}
i have tried refactoring it using some,
var previous_data_change = 'last_changed on 10/01/2019 13:56:34';
var current_data_change= "";
var current_data_end = "";
var current_data_profile = "normal";
var filter_col = [
previous_data_change,
current_data_change,
current_data_end,
current_data_profile
];
change_boolean = filter_col.some((element) => element.length >= 2);
if (change_boolean && previous_data_change.includes("last_changed")) {
console.log(`last change comments: ${previous_data_change}`);
} else {
console.log("no change in previous record");
}
is there any way to shorten it further?
Since you want any of them to be length greater than 2. You can simply merge them instead of writing 4 if conditions.
var previous_data_change = 'last_changed on 10/01/2019 13:56:34';
var current_data_change= "";
var current_data_end = "";
var current_data_profile = "normal";
var string_to_check = previous_data_change + current_data_start + current_data_end + current_data_profile;
// check for changes
if (string_to_check.length < 2) {
console.log(`no change in previous record`)
return false;
}
if (previous_data_change.includes("last_changed")) {
console.log(`last change comments: ${previous_data_change}`)
return true;
}
I am trying to make a game when you have to guess a number that is generated by the Math.random() function in JavaScript. But I realized that when I do that I have to rerun the function if they get the number wrong. Then the number regenerates when it reruns the function. Is there a way that I can make the variable stay until I want to change it. I was going to change it using the const function but I realized it would do the same thing. Here is my full code:
var tries = 5;
var howMany = 0;
var wrong = 0;
var player1 = 0;
var player2 = 0;
var triesmulti = 10;
var turn = 'player 1';
var number;
function start() {
var min = document.getElementById('min').value;
var max = document.getElementById('max').value;
number = Math.floor(Math.random() * (+max - +min)) + +min;
if (tries < 1) {
alert('You \don\'t have any more tries left. The number was \n' + number);
tries = 5;
wrong += 1;
document.getElementById('wrong').innerHTML = 'You have got the number wrong ' + wrong + ' times';
} else {
var guess = prompt();
if (guess == number) {
alert('You got the number right!\n' + number);
howMany += 1;
tries = 5;
document.getElementById('howMany').innerHTML = 'You have guessed the number ' + howMany + ' times';
document.getElementById('tries').innerHTML = 'You have 5 tries left';
} else {
alert('You got the number wrong.');
tries -= 1;
document.getElementById('tries').innerHTML = 'You have ' + tries + ' tries left';
setTimeout(start, 1000);
}
}
}
function multiplayer() {
var min = document.getElementById('minm').value;
var max = document.getElementById('maxm').value;
number = Math.floor(Math.random() * (+max - +min)) + +min;
if (triesmulti < 1) {
alert('You \don\'t have any more tries left\n' + number);
triesmulti = 10;
document.getElementById('triesmulti').innerHTML = 'You have 5 tries for each player';
} else {
var guess = prompt(turn);
if (turn == 'player 1') {
if (guess == number) {
alert('You got the number right!\n' + number);
player1 += 1;
triesmulti = 10;
document.getElementById('triesmulti').innerHTML = 'You have 5 tries for each player';
} else {
alert('You got the number wrong!');
turn = 'player 2';
setTimeout(multiplayer, 1000);
}
} else if (turn == 'player 2') {
if (guess == number) {
alert('You got the number right!\n' + number);
player2 += 1;
triesmulti = 10;
document.getElementById('triesmulti').innerHTML = 'You have 5 tries for each player';
} else {
alert('You got the number wrong!');
turn = 'player1';
setTimeout(multiplayer, 1000);
}
}
}
}
If you see there, in the setTimeout() it reruns the function.
You can create a stateful random number generator quite easily with an object or closure:
const rndRng = (lo, hi) => ~~(Math.random() * (hi - lo) + lo);
const intRng = (lo, hi) => {
let n = rndRng(lo, hi);
return {
next: () => (n = rndRng(lo, hi)),
get: () => n
};
};
const rng = intRng(10, 20);
console.log(rng.get());
console.log(rng.get());
rng.next();
console.log(rng.get());
console.log(rng.get());
But having to do this shouldn't really be necessary for your application. Currently, the application uses non-idempotent functions that rely on global state, repeated/duplicate logic and deeply nested conditionals, so it's become too encumbered to easily work with.
I'd start by storing state in an object. A game like this can be modeled well by a finite state machine.
The below code is a naive implementation of this with plenty of room for improvement, but hopefully demonstrates the idea. It works for any number of players and it's fairly easy to add features to.
However, string messages are baked into business logic so the class is overburdened. A good next step would be creating a separate view class to abstract business logic from display. However, although the message strings are baked into the game logic, the DOM is decoupled. This makes it fairly easy for the caller to use the class in other UIs such as substituting the DOM for alert/prompt.
The below solution is far from the only way to approach this design problem.
class GuessingGame {
constructor(players=1, guesses=5, lo=0, hi=10) {
this.players = Array(players).fill().map(() => ({
guesses: guesses, score: 0
}));
this.guesses = guesses;
this.lowerBound = lo;
this.upperBound = hi;
this.state = this.initialize;
}
initialize() {
const {lowerBound: lo, upperBound: hi} = this;
this.players = this.players.map(({score}) => ({
guesses: this.guesses,
score: score
}));
this.target = ~~(Math.random() * (hi - lo) + lo);
this.currentPlayer = ~~(Math.random() * this.players.length);
this.state = this.guess;
this.message = `guess a number between ${lo} and ${hi - 1} ` +
`(inclusive), player ${this.currentPlayer}:`;
}
handleCorrectGuess() {
this.state = this.initialize;
this.players[this.currentPlayer].score++;
this.message = `player ${this.currentPlayer} guessed ` +
`${this.target} correctly! press 'enter' to continue.`;
}
handleNoGuessesLeft(guess) {
this.state = this.initialize;
this.players[this.currentPlayer].score--;
this.flash = `${guess} was not the number, player ` +
`${this.currentPlayer}.`;
this.message = `player ${this.currentPlayer} ran out of ` +
`guesses. the secret number was ${this.target}. press ` +
`'enter' to continue.`;
}
handleIncorrectGuess(guess) {
this.flash = `${guess} was not the number, player ` +
`${this.currentPlayer}.`;
this.currentPlayer = (this.currentPlayer + 1) % this.players.length;
const {lowerBound: lo, upperBound: hi} = this;
this.message = `guess a number between ${lo} and ${hi - 1} ` +
`(inclusive), player ${this.currentPlayer}:`;
}
guess(guess) {
if (String(+guess) !== String(guess)) {
this.flash = `sorry, ${guess || "that"} ` +
`isn't a valid number. try something else.`;
return;
}
if (this.target === +guess) {
this.handleCorrectGuess();
}
else if (!--this.players[this.currentPlayer].guesses) {
this.handleNoGuessesLeft(+guess);
}
else {
this.handleIncorrectGuess(+guess);
}
}
nextState(...args) {
this.flash = "";
return this.state(...args);
}
scoreBoard() {
return game.players.map((e, i) =>
`player ${i}: {score: ${e.score}, guesses remaining: ` +
`${e.guesses}} ${game.currentPlayer === i ? "<--" : ""}`
).join("\n");
}
}
const msgElem = document.getElementById("message");
const responseElem = document.getElementById("response");
const scoresElem = document.getElementById("scoreboard");
const game = new GuessingGame(3);
game.nextState();
msgElem.innerText = game.message;
scoresElem.innerText = game.scoreBoard();
let timeout;
responseElem.addEventListener("keydown", e => {
if (timeout || e.code !== "Enter") {
return;
}
game.nextState(e.target.value);
e.target.value = "";
e.target.disabled = true;
msgElem.innerText = game.flash;
clearTimeout(timeout);
timeout = setTimeout(() => {
msgElem.innerText = game.message;
scoresElem.innerText = game.scoreBoard();
timeout = null;
e.target.disabled = false;
e.target.focus();
}, game.flash ? 1300 : 0);
});
* {
background: white;
font-family: monospace;
font-size: 1.03em;
}
input {
margin-bottom: 1em;
margin-top: 1em;
}
<div id="message"></div>
<input id="response">
<div id="scoreboard"></div>
Well, your code is not organised, have lot of duplicates, you could devide it into functions anyway, you can add a boolean variable to check against when you should change the number, I don't know about your HTML code or css but I just added those elements according to you selectors, you can change the multiplayer function too.
var tries = 5;
var howMany = 0;
var wrong = 0;
var player1 = 0;
var player2 = 0;
var triesmulti = 10;
var turn = 'player 1';
var number;
var isAlreadyPlaying = false;
function start() {
var min = document.getElementById('min').value;
var max = document.getElementById('max').value;
if(!isAlreadyPlaying) {
isAlreadyPlaying = true;
number = Math.floor(Math.random() * (+max - +min)) + +min;
}
if (tries < 1) {
alert('You \don\'t have any more tries left. The number was \n' + number);
tries = 5;
wrong += 1;
document.getElementById('wrong').innerHTML = 'You have got the number wrong ' + wrong + ' times';
isAlreadyPlaying = false;
} else {
var guess = prompt();
if (guess == number) {
alert('You got the number right!\n' + number);
howMany += 1;
tries = 5;
document.getElementById('howMany').innerHTML = 'You have guessed the number ' + howMany + ' times';
document.getElementById('tries').innerHTML = 'You have 5 tries left';
isAlreadyPlaying = false;
} else {
alert('You got the number wrong.');
tries -= 1;
document.getElementById('tries').innerHTML = 'You have ' + tries + ' tries left';
setTimeout(start, 1000);
}
}
}
Min <input type="number" id="min" value="1"><br>
Max<input type="number" id="max" value="10"><br>
<button onclick="start()">Play</button>
<p id="wrong"></p>
<p id="howMany"></p>
<p id="tries"></p>
I'm making a quiz
I came up with help options:
call friend
help from public
fifty-fifty
I have a problem with the option fifty-fifty!
How to create an option fifty-fifty, activated with a click: it will leave 2 offered answers out of 4 available and of course one answer of the remaining 2 must be correct.
https://jsfiddle.net/e94vqfw2/
generateQuestion = (id_x) => {
pitanje.innerHTML = "";
answers.innerHTML = "";
scoremessage.innerHTML = "";
if (id_x === questions.length) {
pitanje.innerHTML = "Vas rezultat je:" + score;
document.getElementById('help1').style.display = "none";
document.getElementById('help2').style.display = "none";
document.getElementById('help3').style.display = "none";
document.getElementById('error1').style.display = "block";
document.getElementById('error2').style.display = "block";
document.getElementById('error3').style.display = "block";
return;
}
var pitanja = questions[id_x];
pitanje.innerHTML = pitanja.question;
var correctAnswer = pitanja.answer;
for (var i = 0; i < pitanja.answers.length; i++) {
var answer = pitanja.answers[i];
var odgovaranje = document.createElement('div');
odgovaranje.setAttribute("class", "coluum");
odgovaranje.innerHTML = answer;
odgovaranje.style.cursor = 'pointer';
if (answer === correctAnswer) {
odgovaranje.addEventListener('click', nextQuestion);
} else {
odgovaranje.addEventListener('click', wrongAnswer);
}
answers.appendChild(odgovaranje);
}
}
halfandhalf = () => {
if (document.getElementById('help2').onclick) {
}
document.getElementById('help2').style.display = "none";
document.getElementById('error2').style.display = "block";
}
I think I have done what you pretend, here is the code that I changed:
halfandhalf = () => {
if (document.getElementById('help2').onclick) {
let answersToExclude = 2;
while (answersToExclude > 0) {
let indexOfAnswerToExclude = parseInt(getRandomArbitrary(0, answers.childNodes.length));
if(answers.childNodes[indexOfAnswerToExclude].innerHTML !== questions[currentQuestion].answer) {
answers.childNodes[indexOfAnswerToExclude].remove();
answersToExclude--;
}
}
}
document.getElementById('help2').style.display = "none";
document.getElementById('error2').style.display = "block";
}
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
Basically I get a random number between 0 and the number of answers and if it isn't the correct one I remove it. I do this two times to exclude two answers. I get a random number to exclude always random answers, and not by order.
Here is the working fiddle:
https://jsfiddle.net/kh6nd5mc/1/