I want generate random lottery numbers, ranging from 1-59 with 7 numbers showing. They have to generate on the click of a submit button. Im struggling to get it to write to the console log saying random is not defined.
let lottoNum = [];
while (lottoNum.length < 7) {
let random = Math.floor(Math.random() * 59) + 1;
if (lottoNum.indexOf(random) === -1) lottoNum.push(random);
}
let btn = document.getElementById("Button");
button.addEventListener("click", function getNumbers() {
return random;
});
random is not defined
You was close, you should research into scopes however. Try the following:
generateNumbers = () => {
let lottoNum = [];
while (lottoNum.length < 7) {
let random = Math.floor(Math.random() * 59) + 1;
if (lottoNum.indexOf(random) === -1) lottoNum.push(random);
}
return lottoNum;
}
let btn = document.getElementById("Button");
btn.addEventListener("click", function getNumbers() {
const nums = generateNumbers();
console.log(nums);
});
I've put your main code into a function and returned it from said function. From there i've called the function in your click listener and logged them. You can do anything you'd like where i've done console.log however.
The reason you had your "random is not defined" is because you do let random inside your while loop. That means anything that isn't inside of the {} of your while loop cannot read random. hence the function and return :)
Related
I am using JavaScript to generate some random numbers. those random numbers are then checked against user input and correct/incorrect result is displayed. Then I have a button in place which refreshes the page to generate new random values.
I was wondering it there a better method that would re-run the JavaScript without having to reload the entire page again.
//Generates a pair of very peculiar two digit random numbers
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() \* (max - min + 1)) + min;
}
let a = getRandomInt(2,9);
let b = getRandomInt(0,8);
let d = getRandomInt(1,a-1);
let e = getRandomInt(b+1,9);
let ab ="" + a + b;
document.getElementById("AB").innerHTML = ab;
let de ="" + d + e;
document.getElementById("DE").innerHTML = de;
// finds their difference
let result = ab-de;
document.getElementById("R").innerHTML = result;
//checks the user input against correct result and displays a correct/incorrect message
function myFunction() {
let x = document.getElementById("numb").value;
let text;
if (x == result) {
text = "Correct";
} else {
text = "incorrect";
}
document.getElementById("demo").innerHTML = text;
}
Now I want new values to appear on a press of a button. One way to do is to simply refresh the page which I'm currently doing. I was wondering is there a better way to do this. I tried enveloping the entire script in a function and call it using a button. It works but it breaks the result checking functionality for some reason.
PS: I don't have any experience in HTML/JS apart from what I got while building this little side project. Any help is highly appreciated.
You're close with the idea of putting everything in another function, but not quite there. Instead of rerunning everything, another function to just generate new numbers and update the UI should do the trick.
// Generates a pair of very peculiar two digit random numbers
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Generate a new set of numbers
function getNewIntsToCheck() {
const a = getRandomInt(2,9);
const b = getRandomInt(0,8);
const d = getRandomInt(1,a-1);
const e = getRandomInt(b+1,9);
const ab ="" + a + b;
const de ="" + d + e;
const result = ab-de;
return { ab, de, result }
}
// Set in parent scope for access in myFunction
// There are other ways to do this, but this should be easy to understand since
// you don't have much experience with JS :)
let res = ""
// Update the UI on the click of the refresh button
function onRefreshButtonClick() {
const { ab, de, result } = getNewIntsToCheck()
// Set res from parent scope
res = result
document.getElementById("R").innerHTML = result;
document.getElementById("AB").innerHTML = ab;
document.getElementById("DE").innerHTML = de;
}
// Check current numbers in UI against user input and display message
function myFunction() {
let x = document.getElementById("numb").value;
let text;
// Check against res from parent scope, which was set in
// onRefreshButtonClick
if (x == res) {
text = "Correct";
} else {
text = "incorrect";
}
document.getElementById("demo").innerHTML = text;
}
I have written the following HTML for a button that on click calls a function and the output of the function is written in a div in the DOM. But it is not updating the DOM anyway, but freezing the whole browser tab as well as the HTML page. Please help.
Thank you in advance
let rows = [];
let cols = [];
let secKey = "";
const generateKey = () => {
var count = 0;
while (count != 5) {
let randomNumber = Math.floor((Math.random() * 10));
if (!rows.includes(randomNumber)) {
rows.push(randomNumber);
count++;
}
}
count = 0;
while (count != 6) {
let randomNumber = Math.floor((Math.random() * 10));
if (!cols.includes(randomNumber)) {
cols.push(randomNumber);
count++;
}
}
// put on the document
secKey = `${cols[0]}${rows[0]}${cols[1]}${rows[1]}${cols[2]}${rows[2]}${cols[3]}${rows[3]}${cols[4]}${rows[4]}${cols[5]}`;
document.querySelector("#sec-key").innerHTML = `Your secret key is <strong id="sec-key">${secKey}</strong>`; // #sec-key is a div where I want to show the output
};
Html:
<div class="key-container">
<button id="generate-key" class="util-btn" onclick="generateKey()">Generate new secret key</button>
<p class="key-holder" id="sec-key">
<!--output is expected here-->
</p>
<p id="caution">*please remember the secret key for decryption</p>
</div>
The problem is that upon running the function a second time, the globals likely already include the random values, and so the count variable is never incremented and the loop spins infinitely.
Either initialize the globals inside the function implementation, or use the length of the array instead of a counter. Second approach is shown below:
let rows = [];
let cols = [];
let secKey = "";
const generateKey = () => {
while (rows.length != 5) {
let randomNumber = Math.floor((Math.random() * 10));
if (!rows.includes(randomNumber)) {
rows.push(randomNumber);
}
}
while (cols.length != 6) {
let randomNumber = Math.floor((Math.random() * 10));
if (!cols.includes(randomNumber)) {
cols.push(randomNumber);
}
}
// put on the document
secKey = `${cols[0]}${rows[0]}${cols[1]}${rows[1]}${cols[2]}${rows[2]}${cols[3]}${rows[3]}${cols[4]}${rows[4]}${cols[5]}`;
document.querySelector("#sec-key").innerHTML = `Your secret key is <strong id="sec-key">${secKey}</strong>`; // #sec-key is a div where I want to show the output
};
I'm sorry if this has been asked before,
I've searched through Stackoverflow but couldn't find anything that answered my problem.
I'm building a simple memory game, an online version of Simon, when you click the "Start" button it runs the code below to create a random array (of length 4) out of the four colour buttons.
But when you click "Start" again for the next round it doesn't clear the array, and instead creates a second one, and then checks your input against both telling you you're both right and wrong, or right and right (depending on the random array created out of the buttons).
I've tried buttonsToClick = [] in the else section, but it doesn't reset.
I don't know what I'm missing, I've only been learning JavaScript/jQuery for about a month but I wanted to test my knowledge.
The code snipped:
var score = 0;
$("#score").html(`${score}`);
$("#button5").on("click", function() {
var buttons = document.getElementsByClassName("js-button");
var buttonsToClick = chooseRandomButtons(buttons);
currentButtons = buttonsToClick;
flashButtons(buttonsToClick, 0);
var currentOrder = 0;
$(".js-button").on("click", function() {
var selectedButton = $(this)[0];
var button = currentButtons[0];
if (selectedButton === button) {
currentButtons.splice(button,1);
/*alert("Correct");*/
score += 1;
$("#score").html(`${score}`);
} else {
currentButtons = buttonsToClick;
alert("Wrong. Click 'Start' to try again");
score = 0;
$("#score").html(`${score}`);
}
});
})
function chooseRandomButtons(buttons) {
var buttonsToClick = [];
var maxRandomNumber = buttons.length - 1;
for (var i = 0; i < 4; i++) {
buttonsToClick.push(buttons[randomIntFromInterval(0, maxRandomNumber)]);
}
return buttonsToClick;
}
function randomIntFromInterval(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}
function flashButtons(buttonsToClick, index) {
setTimeout(function() {
$(buttonsToClick[index]).fadeOut(500).fadeIn(500);
if (index === buttonsToClick.length - 1) {
return;
}
flashButtons(buttonsToClick, index = index + 1);
}, 1000);
}
welcome to SO.
In general you're doing anything correct with your arrays.
The issue is your event handler.
Every time you click the #button5, which I guess is the start button, you register on all your .js-button a new listener. Since you're not unbinding the old event listeners they're still active.
Since the old event listeners have a reference to your old array, you're basically checking the button against the old game and the new game.
Your solution would be to unregister the old one before registering the new one.
This could be done for example by the .off method.
Your code should then look like this:
var currentOrder = 0;
$(".js-button").off("click").on("click", function() {
var selectedButton = $(this)[0];
var button = currentButtons[0];
if (selectedButton === button) {
currentButtons.splice(button,1);
/*alert("Correct");*/
score += 1;
$("#score").html(`${score}`);
} else {
currentButtons = buttonsToClick;
alert("Wrong. Click 'Start' to try again");
score = 0;
$("#score").html(`${score}`);
}
});
Notice the .off() there.
The documentation about the method could be found here: https://api.jquery.com/off/
This question already has answers here:
How to randomize (shuffle) a JavaScript array?
(69 answers)
Closed 5 years ago.
I'm trying to create a sort of a bingo number generator, where I generate a unique number and display it alone.
I also want that number + all the next numbers I'm generating to display at the bottom in a line.
My issue here is that whenever it hits a duplicate it loops until it finds a unique number, but displays that number as many times as it looped in the bottom row. So if I generate the numbers [4, 6, 2] and then another 4 it would keep looping until it found another number that's not already in the array.
If it hits the numbers in the array 2 times then found a 5, it would display as [4, 6, 2, 5, 5, 5,]. Is there anything I can do to not make it display the first 2 5's?
window.onload = startup;
function startup() {
document.getElementById("button").onclick = newNumber1;
}
var number = 0;
var bingoNumber = [];
var i;
function newNumber1() {
number = Math.floor((Math.random() * 9) + 1);
clickME();
}
function clickME() {
for (i = 0; i < bingoNumber.length; i++) {
if (number === bingoNumber[i]) {
newNumber1();
}
}
bingoNumber.splice(0, 0, number);
document.getElementById("display").innerHTML = bingoNumber[0];
document.getElementById("row").innerHTML = bingoNumber;
}
<button type="button" id="button">Click</button>
<div id="display"></div>
<div id="row"></div>
Your clickMe calls newNumber1 before it finishes executing, which isn't the problem. The problem is that newNumber1 calls another instance of clickMe, and the loop continues. So by the time newNumber1 generates a unique number, the current and previous instances of clickMe finishes inserting the same new number every time.
Another problem is that, even if you get this working, the loop in clickMe will go on and on if bingoNumber contains all possible unique number that newNumber1 can generate.
Try this:
window.onload = startup;
var bingoNumber = []; // contains all generated numbers
function startup(){
document.getElementById("button").onclick = clickMe;
}
function newNumber(){
// generate a new number
return Math.floor((Math.random() * 9) + 1);
}
function clickMe(){
// if bingoNumber contains all possible values, don't run the rest
// change this to however you want to terminate it
if(bingoNumber.length==9){ return false; }
var num; // number to add to the array
// generate a new number until it is unique
for(num=newNumber();bingoNumber.indexOf(num)>=0;num=newNumber());
// add the unique number in the beginning of the array
bingoNumber.unshift(num);
// display last generated value
document.getElementById("display").innerHTML = bingoNumber[0];
// display all generated value
document.getElementById("row").innerHTML = bingoNumber;
}
Don't add the number to array and display stuff until you really found the unique number:
var found;
function clickME() {
found = true;
for (i=0; i < bingoNumber.length; i++) {
if (number === bingoNumber[i]){
newNumber1();
found = false;
}
}
if(found) {
bingoNumber.splice(0, 0, number);
document.getElementById("display").innerHTML = bingoNumber[0];
document.getElementById("row").innerHTML = bingoNumber;
}
}
This will give you all the numbers without running out of stack space. There is an alert at the end to let you know that all the numbers have been called and will also hide the button so you can't click it again. That one you don't need...but why not?
window.onload = startup;
var bingoNumber = [];
function startup(){
document.getElementById("button").onclick = newNumber1;
}
function newNumber1() {
clickME(Math.floor((Math.random() * 9) + 1));
}
function clickME(num) {
if(bingoNumber.length < 9){
if (bingoNumber.indexOf(num) !== -1){
newNumber1();
}else{
bingoNumber.splice(0, 0, num);
document.getElementById("display").innerHTML = bingoNumber[0];
document.getElementById("row").innerHTML = bingoNumber;
}
}else{
alert("All numbers have been picked");
document.getElementById("button").style.visibility = "hidden";
}
}
So I wanted to code a simple project. When a button is clicked, the program generates a random number between 1 and 50 and then prints it inside my DIV.
I wanted a little feature that if the number happens to be 18, the background color changes to red.
So I've tried do do this many times, but the background changing randomly. No order or whatsoever.
I've tried to log the numbers, to see is there any connection between the them when it changing to red, but no luck.
However, in the console, a little grey 2 appears. Also at random times.
function getRandomNumber(){
var randomNumber = Math.floor(Math.random()*50) + 1;
return randomNumber;
}
myButton.addEventListener('click', ()=>{
para.innerHTML = getRandomNumber();
console.log(getRandomNumber());
if(getRandomNumber() === 18){
para.style.backgroundColor = "red";
}
});
Everytime you call getRandomNumber() it's generating a new number. Call it once, save it to a variable, and everything should work as you expect.
function getRandomNumber() {
var randomNumber = Math.floor(Math.random() * 50) + 1;
return randomNumber;
}
myButton.addEventListener('click', () => {
let number = getRandomNumber();
para.innerHTML = number;
console.log(number);
if (number === 18) {
para.style.backgroundColor = "red";
}
});
Set return value of getRandomNumber() as a variable. Toggle backgroundColor between "red" and "unset" or empty string ""
function getRandomNumber(){
var randomNumber = Math.floor(Math.random()* 4) + 1;
return randomNumber;
}
var para = document.querySelector("p");
var myButton = document.querySelector("button");
myButton.addEventListener("click", () => {
const rand = getRandomNumber();
para.innerHTML = rand;
para.style.backgroundColor = rand === 1 ? "red" : "unset";
});
<button>click</button>
<p></p>
Your issue is that you are calling getRandomNumber twice, which will get you two different random numbers. Save the random number to a variable var randomNumber = getRandomNumber() and then use this variable to set the innerHTML of your para and check if it's eighteen to see if the background should change.
The grey number 2 just means that the same number is being printed twice in a row.