I'm a Digital Arts student, I'm in my first year and recently we've been given the task to make a basic E-Learning website for maths. Basically you're asked what (for example) 7 times 7 is, you enter the answer and click a button, an alert window comes up. If you're correct it's supposed to say "correct" or "yay" or "well done" and if you're wrong it says "No" or "try again" or something else.
My problem is that it's supposed to show one random message in the window alert, not all of them at once or one after the other, just one randomly. I've looked but I wasn't able to find anything that helps.
Here's the part of the code I'm having trouble with:
<script type="text/javascript">
var x, y;
var answer;
function aNumber() {
return Math.floor(1 + (Math.random() * 12));
}
function genQuestion() {
x = aNumber();
y = aNumber();
din = document.getElementById("inputVal");
din.value = x + " times " + y;
answer = x * y;
}
function ClickAnswer() {
if (answer == document.getElementById("outputVal").value) {
window.alert("Correct");
window.alert("Yes!");
window.alert("Well done");
location.reload();
} else {
window.alert("No, try again.");
window.alert("try again");
window.alert("wrong");
}
}
function displayArea() {
din = document.getElementById("inputVal");
dout = document.getElementById("outputVal");
dout.value = circleArea(din.value);
}
</script>
Put the messages in an array and alert a random entry of it.
let successMsg = ['Correct', 'Cool'];
let errorMsg = ['Wrong', 'false'];
alert(successMsg[Math.floor(Math.random() * successMsg.length)]);
function ClickAnswer() {
if (answer == document.getElementById("outputVal").value) {
alert(successMsg[Math.floor(Math.random() * successMsg.length)]);
location.reload();
} else {
alert(errorMsg[Math.floor(Math.random() * successMsg.length)]);
}
The issue is that you are writing all the message at the same time like this :
window.alert("Correct");
window.alert("Yes!");
window.alert("Well done");
Instead you may store the messages into and array, pick up a random number and select a message from this array. You may try something like this :
var message = ["Correct","Yes!","Well done"];
var a = Math.floor(Math.random() * message.length);
window.alert(message[a]);
What you're looking to do is make use of Math.random() just like you did for the number selection. Assign each of the correct answers to one array, and each of the incorrect answers to another array. Then you can retrieve them with:
correct_answers[Math.floor(Math.random()*correct_answers.length)];
imcorrect_answers[Math.floor(Math.random()*incorrect_answers.length)];
I've created a stripped-down version of your original code showcasing this here:
var correct_answers = ["Correct", "Yes!", "Well done"];
var incorrecty_answers = ["No, try again.", "try again", "wrong"];
correct_answers[Math.floor(Math.random()*correct_answers.length)];
function ClickAnswer() {
if (true) {
window.alert(correct_answers[Math.floor(Math.random()*correct_answers.length)]);
} else {
window.alert(incorrect_answers[Math.floor(Math.random()*incorrect_answers.length)]);
}
}
ClickAnswer();
Hope this helps! :)
One way that you could go is to store the String values that you want to randomize in an array and randomly choose and return a specific index from that. Take a look here.
In your case it could be
var positiveAnswers= ['Correct!', 'Yes!', 'Well done!'];
var randomAnswer = positiveAnswers[Math.floor(Math.random() * positiveAnswers.length)];
window.alert(randomAswer);
Related
This is my code so far. It's basically a randomizer based on images. I got the random pictures to change, but I realized that the images repeat if the generated number is repeated again from the button clicked. Is there a way I can display that message? Like the number has been repeated again. Sorry, I'm still a javascript newbie.
btnRandom.addEventListener('click', function () {
const numRandom = Math.trunc(Math.random() * 9);
console.log(numRandom);
characterEl.src = `img/genshin_characters/card-${numRandom}.webp`;
if (numRandom) {
console.log('you got the same character again!');
}
});
I assume you don't want to random same number twice in a row. So use a variable to remember the last one.
var last
btnRandom.addEventListener('click', function() {
var numRandom
while ((numRandom = Math.trunc(Math.random() * 9)) === last) {
console.log("will randomize again");
}
console.log(numRandom)
// characterEl.src = `img/genshin_characters/card-${numRandom}.webp`;
last = numRandom
});
<button id="btnRandom">btnRandom</button>
Full code looks like this, ideally we have 4 div boxes that need to be randomly filled with random numbers ansValue, one of them (rightAnsValue with its rightAnsId) is already done and works fine, I've managed to make it unique in comparison to others (code without commented section). But met a problem with making others unique, I keep having some identical values in my boxes. In comments is one way I tried to solve this, but pretty sure there is a much simpler and smarter solution that actually works. I would appreciate if you could help to find an understandable solution to this problem.
(P.S. I've seen similar questions but they are either too dificult or done without JS.)
function createAnswers(){
for(ansId=1; ansId<5; ansId++){
if(ansId!=rightAnsId){
for(i=1; i<10; i++){
digitArray[i-1] = i;
}
genNewRandNum();
// ansArray.length = 3;
// ansArray.push(ansValue);
// for(k=0; k<3; k++){
// if(ansArray[k] == ansArray[k+1] || ansArray[k] == ansArray[k+2]){
// genNewRandNum();
// ansArray[k] = ansValue;
// }else if(ansArray[k+1] == ansArray[k+2]){
// genNewRandNum();
// ansArray[k+1] = ansValue;
// }else{
// break;
// }
// }
if(ansValue!=rightAnsValue){
document.getElementById("box" + ansId).innerHTML = ansValue;
}else{
genNewRandNum();
document.getElementById("box" + ansId).innerHTML = ansValue;
}
}
}
}
The way I generate new numbers:
function genNewRandNum(){
rand1 = digitArray[Math.floor(Math.random() * digitArray.length)];
rand2 = digitArray[Math.floor(Math.random() * digitArray.length)];
ansValue = rand1 * rand2;
}
Replace your genNewRandNum() with below code. I have used IIFE to create a closure variable alreadyGeneratedNumbers thats available inside the function generateRandomNumber() thats returned.
So everytime genNewRandNum() is executed, it checks against alreadyGeneratedNumbers to make sure it always returns a unique between 1 and 9.
var genNewRandNum = (function(){
var alreadyGeneratedNumbers = {};
return function generateRandomNumber() {
var min = Math.ceil(1),
max = Math.floor(9);
randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
if(alreadyGeneratedNumbers[randomNumber]) {
return generateRandomNumber();
} else {
alreadyGeneratedNumbers[randomNumber] = randomNumber;
return randomNumber;
}
}
})();
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
Note: If you call genNewRandNum() for the 10th time it will throw error. So if you have a use case where you would need to reset it after all numbers from 1 to 9 are returned, then you need to add code to handle that
The easiest way to brute-force this is to use accept/reject sampling. You can do something like so:
uniqueRandomNumbers = function(n, nextRandom)
{
var nums = {}; var m = 0;
while(m < n)
{
var r = nextRandom();
if(! nums.hasOwnProperty(r))
{
nums[r] = true; m++;
}
}
return Object.keys(nums);
}
Here I'm using the fact that js objects are implemented as hashmaps to get a hashset. (This has the downside of converting the numbers to strings, but if you're not planning on imediately doing arithmetic with them this is not a problem.)
In order to get four unique integers between 0 and 9 you can then do something like:
uniqueRandomNumbers(4, function() { return Math.floor(Math.random() * 10); })
If you want something a little better than brute force (which probably isn't relevant to your use case but could help someone googling this), one option is to go through each element and either take or leave it with an appropriate probability. This approach is outlined in the answers to this question.
I am trying to make a simple quiz where two terms are displayed in different languages (I have used numbers here to avoid confusion). 50% of the time the terms will match. The user has the option of choosing yes or no for whether the terms match or not. The questions are displayed in random order and it doesnt matter if they repeat.
The idea is that this should be repeated multiple times.
I can't seem to get the loop to work, at the moment it runs through and prints all the questions out at the start. I would like it to print out a new question when the user clicks.
Here is a link to jsfiddle: http://jsfiddle.net/sX8Rz/1/
Here is the code:
$(document).ready(function () {
var score = 0;
var hiraganaWords1 = [
["1", "one"],
["2", "two"],
["3", "three"],
["4", "four"],
["5", "five"],
["6", "six"],
["7", "seven"],
["8", "eight"],
["9", "nine"],
["10", "ten"]
];
function askQuestion() {
var questionNumber = Math.floor((Math.random() * hiraganaWords1.length));
var trueFalse = Math.round(Math.random());
var wrongAnswer = Math.floor((Math.random() * hiraganaWords1.length));
var correct = hiraganaWords1[questionNumber][0];
var trueAnswer = hiraganaWords1[questionNumber][1];
var incorrectAnswer = hiraganaWords1[wrongAnswer][1];
if (trueFalse === 0) {
$("#japanese").append(correct);
$("#english").append(trueAnswer);
var answer = "yes";
$("#yes").click(function () {
var guess = "yes";
if (guess === answer) {
score++;
alert("well done your score is: " + score);
} else {
score = 0;
alert("try again");
}
});
$("#no").click(function () {
var guess = "no";
if (guess == answer) {
score++;
alert("well done your score is: " + score);
$("#japanese").html(" ");
$("#english").html(" ");
} else {
score = 0;
alert("try again" );
}
})
} else {
$("#japanese").append(correct);
$("#english").append(incorrectAnswer);
var answer = "no";
$("#yes").click(function () {
var guess = "yes";
if (guess == answer) {
score++;
alert("well done" + score);
} else {
score = 0;
alert("try again" + score);
}
});
$("#no").click(function () {
var guess = "no"
if (guess == answer) {
score++;
alert("well done" + score);
} else {
score = 0;
alert("try again" + score);
}
})
}
}
for(i=0;i<5;i++){
askQuestion();
}
});
Thanks in advance and I am sorry for the noob question, I am just learning and would appreciate the help.
Cheers
Andy
You can't wait in JavaScript (and if you could, the browser would block and clicking anywhere wouldn't have any effect).
So the solution is to ask the next question when the user has clicked on her choice (after you display the result for the last question).
It looks like you trying to solve data binding problem with wrong approach. I recommend you to look on AngularJS or Knockoutjs for solution of your problem (building dynamic user responsive javascript interface). It may save you some time.
It is difficult to understand from your code a bit. But I can give a general idea.
Implement a function called askQuestion like:
// add more questions
var questions = ["Eaten food?", "Exercised?"];
// add more choices of your own
var choices = [
["one", "four", "three", "two"],
["onasde", "foadur", "thradasdee", "two00"], ];
$(document).ready(function () {
askQuestion(0);
});
function askQuestion (index){
// where index is the index of question in questions array and choices in choices array
// display question and choices
$("#q").html(questions[index]);
$("#c").html(choices[index].toString());
//And then,
$("inout").keyup(function(){
validateUserInput(); // validate user input
// ask question passing another index
askQuestion(index + 1);
});
}
DEMO
So, there you see. On input change, fire an anonymous function, that validates user input and asks another question.
Hope that helps!
What I'm building is a game where the computer generates a random number (1-100) and the user must guess the correct number. The goal is for the computer to compare the current guess to the previous guess and spit out a statement: "hot", "cold", "hotter", "colder", etc.
My Code (focus on the JS): CodePen fiddle
//global variables--computer generated guess, and guess log
var answer = Math.floor((Math.random() * 100)+1);
var guessArray = [];
var index = 0;
//user clicks submit button and guess is registered by computer
$("#submit").click( function(){
var guess = $("#guess").val();
guessArray.push(guess);
//prints out the answer and user guesses
$("#answer").text("Answer:" + " "+ answer);
$("#guessArrayPrint").text("You guessed: " + " " + guessArray + " ");
if (answer === guess) {
$("#statement").text("woo hoo right answer");
} else {
var currentDifference = Math.abs(answer-guess);
var currentDiffArray = [];
currentDiffArray.push(currentDifference);
if (index = 0) {
//if-else statement comparing current guess range to answer
if ( currentDifference >=1 && currentDifference <= 10){
$("#statement").text("Ouch! You're hot!");
} else {
$("#statement").text("Brr! You're cold!");
}
} else {
//if-else statement comparing current guess to previous guess
var previousDiff = answer- prevguess;
var prevguess = guessArray [i-1];
if( previousDiff < currentDifference){
$("#statement").text("Ahh! Getting Warmer!");
} else {
$("#statement").text("Brrr...getting colder");
}
}
index++
}
});
My nested if-else statements are not working. When a user inputs a guess, no matter how close to the answer, it always returns the statement "brr.. getting colder", which is in the "else" section.
Ideally when the user inputs their first guess if (index = 0) should run then when the second guess is input, it should move to the "else" statement with the previous guess variables. I tried moving around the variables, changed orders of if/else, and thought maybe it's the placement of index++. Nothing is working. Not sure if something is wrong with my variables , arrays, or the syntax of my if/else statements.
tl;dr: when the program is run only the "else" portion of the nested if-else statement is run. Not sure how to fix… I've gone through my code a number of times. The syntax, the arrays, and variables. Uncertain what's wrong.
You JS has if (index = 0). This should be if (index === 0).
Additionally, you need to cast the value of your input field to a number. You can do this using:
var guess = +$("#guess").val(); // + cast as a number
More syntax errors:
prevguess = guessArray[i - 1] --> prevguess = guessArray[index - 1];
Here is a partial working Fiddle. I ran through some scenarios, and the fiddle really only works if you give the application the right answer. The code has many syntax errors, bad refs and calculations. I would suggest opening the console or a debugger, identifying those issue, and fixing them.
Here is a Fully Functional Demo.
I am having a strange issue, but it is not surprising as I am a bit of a JavaScript newbie. Basically I am creating a simple high-low card game. (Draw two cards, highest card wins). Anyways, the code is below.
The basic flow of the program is pretty simple. I choose 2 random numbers (1-52). These numbers are mapped to a corresponding card. (i.e. number 1 is the ace of spades, number 37 is the jack of clubs, etc.). Anyways, after drawing the cards, the program is to display the corresponding card and determine the winner. At the end of all of this, i have an alert that comes up and and tells the winner of the draw and asks if the user wants to play again.
The problem I am having is this: Even though the program should have already displayed the image of the card and output the results to a text area, the alert box shows up before any of that actually occurs and never displays the cards or the results. Any ideas? I am posting all of the code so far and any help would be appreciated. Thanks in advance.
function drawCards() {
var oppCard = randNumber();
var customerCard = randNumber();
while (oppCard == customerCard) {
customerCard = randNumber();
}
var oppCardName = displayCard(oppCard, "oppImage");
var customerCardName = displayCard(customerCard, "custImage");
var result2 = "Your card was: " + customerCardName;
var result1 = "The opponent's card was: " + oppCardName;
var result3 = determineWinner(oppCard, customerCard);
var result4 = result3 + '\n' + result1 + '\n' + result2;
$("#textareaRes").text(result4);
playAgain(result3);
}
function determineWinner(oppsCard, customersCard) {
var oppValue = oppsCard % 13;
var customerValue = oppsCard % 13;
var winnerString = "";
if (oppValue == 0) {
oppValue = 13;
}
if (customerValue == 0) {
customerValue = 13;
}
if (oppValue == customerValue) {
winnerString = "You Tied.";
}
else if (oppValue > customerValue) {
winnerString = "You Lose.";
}
else if (oppValue < customerValue) {
winnerString = "You Win!!";
}
return winnerString;
}
function randNumber() {
var min = 1;
var max = 52;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return random;
}
function playAgain(resultString) {
if (resultString == "You Lose." || resultString == "You Win!!") {
alert(resultString);
var conf = confirm("Play Again?");
if (conf == true) {
$("#textareaRes").text("");
document.getElementById("custImage").src="./cardImages/default.png";
document.getElementById("oppImage").src="./cardImages/default.png";
}
else {
window.location = "#mainMenuPage";
}
}
else {
alert(resultString);
alert("Try Again.");
$("#textareaRes").text("");
document.getElementById("custImage").src="./cardImages/default.png";
document.getElementById("oppImage").src="./cardImages/default.png";
}
}
So I did not place the code in here for the display card function, just because for testing it is exceptionally long. It is just a giant switch case for all 52 random numbers. The finished product will actually be pulling from an XML file, but I used this just for testing purposes. (If, for some reason, you need to see the display cards function, let me know and I can post it.) Anyway, to recap, the last call made in the drawCards() function is the playAgain function. Upon running this code the results nor the card images are displayed. It just jumps straight to the alert that is called for by the playAgain function. This is probably a pretty noobish question, but I am a little perplexed by it. So any help you guys can offer would be GREATLY appreciated. Thanks.
EDIT: It actually performs correctly in a computer's browser. However, the problem happens on a mobile device like a phone or tablet. So this is probably something that I am doing incorrectly here. Any help is greatly appreciated.
Changes in the browser doesn't show up as long as your Javascript code is running.
The browser is event driven, so changing an element in the DOM doesn't show the change immediately, instead an event is triggered to redraw the element. When your function has finished running, the browser will handle any pending events and show the changes.
So, when building an application, you have to use the same approach so that the browser has a chance to show the changes.
For anyone who finds this looking for the solution to the problem, the solution can be found in this answer: https://stackoverflow.com/a/13338585/870729
Here is a working fiddle of a simple example:
jQuery(function($) {
$.when($('#empty-me').html('')).done(function() {
alert('I did it!');
});
});
"./cardImages/default.png"
im not sure ... but try "../cardImages/default.png" ... i always use 2 dots for come to a higher level