I can't seem to find any solutions.
I want to create a form that collects 4 nicknames after submit a form and then displays them all randomly in html code using javascript
My 4 input values are now in an array.
I have to display them randomly in two different teams.
I'm trying to get a random index, and as long as it's different from the ones already assigned to avoid one person being on both teams.
This code works, but sometimes, one player is assigned to 2 teams. Then, the randomizer doesn't work... Do you have an idea ?
function getRandomNumber(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function getData() {
let joueur1 = document.querySelector("#player1").value;
let joueur2 = document.querySelector("#player2").value;
let joueur3 = document.querySelector("#player3").value;
let joueur4 = document.querySelector("#player4").value;
playerList.push(player1.value);
playerList.push(player2.value);
playerList.push(player3.value);
playerList.push(player4.value);
randomNumber1 = getRandomNumber(playerList.length);
last1 += randomNumber1;
random1.textContent = playerList[randomNumber1];
do {
randomNumber2 = getRandomNumber(playerList.length);
} while (randomNumber2 == last1 && last4 && last3);
last2 += randomNumber2
random2.textContent = playerList[randomNumber2];
do {
randomNumber3 = getRandomNumber(playerList.length);
} while (randomNumber3 == last1 && last2 && last4);
last3 += randomNumber3
random3.textContent = playerList[randomNumber3];
do {
randomNumber4 = getRandomNumber(playerList.length);
}while (randomNumber4 == last1 && last2 && last3)
random4.textContent = playerList[randomNumber4];
last4 += randomNumber4
}
Thanks for your help !
Here is a simple way of getting a random item from your array
Here you add your items into array
let joueur1 = document.querySelector("#player1").value;
let joueur2 = document.querySelector("#player2").value;
let joueur3 = document.querySelector("#player3").value;
let joueur4 = document.querySelector("#player4").value;
let playerList=[];
playerList.push(joueur1);
playerList.push(joueur2);
playerList.push(joueur3);
playerList.push(joueur4);
Then, Here is how you can get randomized content
let randomPlayer = playerList[Math.floor(Math.random() * playerList.length)];
Math.random() will never be 1. The largest index is always one less than the length of the array
Related
I'm starting to learn javascript, and I'm trying to make a calculator app to solve simple harmonic motion. and made a js code to solve automatically if there are values from the input fields.
similar mechanics on this website when you put values it automatically solves and you can delete the value to solve another one https://www.omnicalculator.com/physics/displacement
const mass_event = document.getElementById("mass");
const k_event = document.getElementById("spring-constant");
const period_event = document.getElementById("period");
mass_event.addEventListener("input", solve);
k_event.addEventListener("input", solve);
period_event.addEventListener("input", solve);
function solve () {
var mass = document.getElementById("mass").value;
var konstant = document.getElementById("spring-constant").value;
var time = document.getElementById("period").value;
m = Number(mass);
k = Number(konstant);
t = Number(time);
if (m && k != 0) {
period = (2 * Math.PI * Math.sqrt((m/k)));
document.getElementById("period").value = (period);
} else if (k && t != 0) {
mass_kg = (Math.pow(t, 2) * k) / (4 * Math.pow(Math.PI, 2));
document.getElementById("mass").value = (mass_kg);
} else if (m && t != 0) {
spring_constant = (4 * Math.pow(Math.PI, 2) * m) / (Math.pow(t, 2));
document.getElementById("spring-constant").value = (spring_constant);
}}
It works but when there are already 2 values you cant delete the input values to solve for another. I'm trying to do this so that i can remove the solve button
I have a random number generator that gives me a value between 1 and 6 (N).
I want to change the image SRC based on what number I get.
for instance, I have 6 images named [image1, image2, image3, image4, image5, image6].
let N = Math.random() * 6;
N = Math.floor(N);
document.querySelector(".img").src = `images/image${N}.png `;
I think the problem is caused by JS parsing images/img${N}.png as a HTML code due to ${N} being JavaScript code and HTML not being able to assign a value to it.
is there another way of writing this without using if / else if for every value of N?
like so =>
let N = Math.random() * 6;
N = Math.floor(N);
if (N === 1) {
document.querySelector(".img1").src = "images/image1.png";
} else if (N === 2) {
document.querySelector(".img1").src = "images/image2.png";
} else if (N === 3) {
document.querySelector(".img1").src = "images/image3.png";
} else if (N === 4) {
document.querySelector(".img1").src = "images/image4.png";
} else if (N === 5) {
document.querySelector(".img1").src = "images/image5.png";
} else {
document.querySelector(".img1").src = "images/image6.png";
}
Your problem is a superfluous space at the end of the template/string
document.querySelector(".img").src = `images/image${N}.png `;
// ^
and missing one for one based counting.
Your actual random values are 0 ... 5, but you need 1 ... 6.
You could take a shorter approach by moving the random/flooring part into the expression.
document.querySelector(".img").src = `images/image${Math.floor(Math.random() * 6) + 1}.png`;
const n = Math.floor(Math.random() * 6) + 1;
console.log(`images/image${n}.png`);
You can use array index like this:
let N = Math.random() * 6;
N = Math.floor(N);
const imgs = [image1, image2, image3, image4, image5, image6]
document.querySelector(".img1").src = imgs[N];
You can use something like this :
let N = 6 // no of images
const imageBase='images/image';// relative or absolute url
document.querySelector(".img").src = `${imageBase}${Math.floor(Math.random() * N)}.png`;
using the code below, I've created a grid of buttons, 5x5, with random 1-25 numbers assigned to each button. They are to be clicked in numerical order, each's background turns red when clicked in the correct order. I can't use a global variable for this prompt. Without a global variable, I can't figure out how to increment the correctNumbers function which checks whether the right number is clicked each time. I think I'm missing something, a js function or something that would enable an incrementing variable declared within the incrementing function. I'm not looking for the whole explanation, just tips on functions i might not know about, and whether or not what i'm trying to do just isn't logicly possible.
<div id="numbers" class="hidden"></div>
<div id="youWon" class="hidden">You Won!</div>
The relevant JS:
... /**
* Gives the numbers a random order
* the "Fisher-Yates shuffle" found at: https://www.frankmitchell.org/2015/01/fisher-yates/
* #param {*} array
*/
const shuffle = (array) => {
let i = 0,
j = 0,
temp = null
for (i = array.length - 1; i > 0; i -= 1) {
j = Math.floor(Math.random() * (i + 1))
temp = array[i]
array[i] = array[j]
array[j] = temp
}
}
/**
* Generates an array of numbers 1-25
*/
const generateNums = () => {
document.getElementById("youWon").classList.toggle("hidden", "visible");
const numberArray = [];
for (let a = 1; a <= 25; a++) {
numberArray.push(a);
}
shuffle(numberArray);
let numEl = document.getElementById('numbers'); //write into html div id "numbers"
for (let b = 0; b <= 24; b++) { //loop to create button array
let newBtn = document.createElement('button'); //create buttons
newBtn.className = 'number'; //assign newBtns 'number' class
newBtn.innerText = numberArray[b]; //assign numbers to each button
numEl.appendChild(newBtn); //match with number elements in "numbers" array
newBtn.addEventListener("click", onNumberClick) //create function trigger
}
}
/**
* Creates a function to decide correct and incorrect clicks
* When a user clicks a number, if it is the next number in order, then it turns a different color for the remainder of the test
* If it is the wrong number, nothing happens
* #param {*} event
*/
const incrementNum = (correctNumber) => {
correctNumber++;
}
const onNumberClick = (event) => {
let correctNumber = 1; //start at 1
let numberVal = event.target; //apply it to clicks on the numbers
if (Number(numberVal.innerHTML) + 1 == incrementNum(correctNumber)) {
incrementNum(correctNumber);
numberVal.classList.add("red");
}
if (correctNumber == 26) {
document.getElementById("youWon").classList.toggle("visible"); //show win message if 25 is the last button and gets clicked
}
}
I would suggest that you count the number of elements in the DOM that have the class "red" and add 1... checking if the innerHTML is equal to that number to get the sequence right. So, instead of this:
if (Number(numberVal.innerHTML) + 1 == incrementNum(correctNumber)) {
incrementNum(correctNumber);
numberVal.classList.add("red");
}
You can have something like this:
if(Number(numberVal.innerHTML) == document.getElementsByClassName('red').length + 1) {
numberVal.classList.add("red");
}
I am new to Javascript and working with the basics. I am wanting to create an array whose individual elements are randomly drawn, one at a time, with a click of a button, until all array elements are displayed on the screen. The code I have is almost there. But the issue is that when it runs, it always grabs 2 elements on the first button click, rather than 1. It runs well for the remaining elements. Sure would appreciate some insight to this problem. Thank you.
var myArray=['1','2','3','4','5','6','7']
var text = "";
var i;
function RandomDraw() {
for(i = 0; i < myArray.length; i+=text) {
var ri = Math.floor(Math.random() * myArray.length);
var rs = myArray.splice(ri, 1);
document.getElementById("showSplice").innerHTML = text+=rs;
//document.getElementById("showArrayList").innerHTML = myArray;
}
}
It "always" draws 2 elements because of the i+=text. Your array is small thus the loop needs 2 iteration (of cocatinating the strings to get the number i) to go over myArray.length.
First iteration:
i = 0 => 0 < myArray.length => true
prints number
Second iteration: (say '4' get choosen)
i = i + text and text = '4' => i = "04" => "04" < myArray.length => true
prints number
Third iteration: (say '3' get choosen)
i = i + text and text = '43' => i = "0443" => "0443" < myArray.length => false
loop breaks
So there is a possibility that two elements get printed. Depending on the length of the array, there could be more.
You don't need the loop, just choose a number and print it:
function RandomDraw() {
if(myArray.length > 0) { // if there still elements in the array
var ri = Math.floor(Math.random() * myArray.length); // do your job ...
var rs = myArray.splice(ri, 1);
document.getElementById("showSplice").textContent = rs; // .textContent is better
}
else {
// print a message indicating that the array is now empty
}
}
Another solution is to shuffle the array and then, on each click, pop the element from the shuffled array.
function shuffle(array) {
return array.sort(function() { return Math.random() - 0.5; });
}
var button = document.getElementById('button');
var origin = ['1','2','3','4','5','6','7'];
var myArray = shuffle(origin);
var currentValue = null;
button.onclick = function() {
currentValue = myArray.pop();
if(!!currentValue) {
console.log(currentValue);
}
}
<button id='button'>
get element
</button>
You can shuffle the array again on each click, but I think it is not necessary whatsoever...
If you're wondering about Math.random() - 0.5:
[...] Math.random is returning a number between 0 and 1. Therefore, if you call Math.random() - 0.5 there is a 50% chance you will get a negative number and 50% chance you'll get a positive number.
If you run a for loop and add these results in an array, you will effectively get a full distribution of negative and positive numbers.
https://teamtreehouse.com/community/mathrandom05
I would do it this way:
let myArray=['1','2','3','4','5','6','7']
function RandomDraw(){
const selectedIndex = Math.floor(Math.random() * myArray.length);
const selected = myArray[selectedIndex]
myArray = myArray.slice(0, selected).concat(myArray.slice(selected + 1));
return selected;
}
Every time you call RandomDraw it will return a random number, without repeating.
The way I understand it, you want to draw every items from the array after a single click. So the loop is needed.
As others have said, there are several issues in your for loop :
that i+= text makes no sense
you are looping until i reaches the length of your array, but you are splicing that array, hence reducing its length
You could correct your for loop :
function RandomDraw() {
var length = myArray.length;
var ri = 0;
for (var i=0;i<length;i++) {
ri = Math.floor(Math.random() * myArray.length);
console.log("Random index to be drawn : " + ri);
// removing that index from the array :
myArray.splice(ri, 1);
console.log("myArray after a random draw : ", myArray);
}
}
Or, you could use a while loop :
function RandomDraw() {
var ri = 0;
while (myArray.length > 0) {
ri = Math.floor(Math.random() * myArray.length);
console.log("Random index to be drawn : " + ri);
// removing that index from the array :
myArray.splice(ri, 1);
console.log("myArray after a random draw : ", myArray);
}
}
I'm creating a random image generator that displays images when a button is clicked. I'm trying to prevent the same image being displayed twice in a row by having the random number connected to each image increase by 1 if duplicated (in other words the next image will be shown rather than the same image twice). I'm trying to use if statements to achieve this but there seems to be a glitch in my code as the same image is still being displayed more than once. Not sure where the problem is. Any solutions out there ?
Thanks
document.getElementById('ranImgBtn').onclick = function() {
var ranImgDis = document.getElementById('ranImgDis');
ranImgDis.style.width = '300px';
ranImgDis.style.height = '200px';
var pic1 = href="http://farm4.staticflickr.com/3691/11268502654_f28f05966c_m.jpg";
var pic2 = href="http://farm1.staticflickr.com/33/45336904_1aef569b30_n.jpg";
var pic3 = href="http://farm6.staticflickr.com/5211/5384592886_80a512e2c9.jpg";
var num = Math.floor(Math.random() * (3 - 1 +1)) + 1;
if(num !== 2 && num !== 3) {
if(ranImgDis.src !== pic1) {
ranImgDis.src = pic1;
} ranImgDis.src = pic2;
} else if (num !== 1 && num !== 3) {
if(ranImgDis.src !== pic2) {
ranImgDis.src = pic2;
} ranImgDis.src = pic3;
} else if (num !== 1 && num !== 2) {
if(ranImgDis.src !== pic3) {
ranImgDis.src = pic3;
} ranImgDis.src = pic1;
}
}
You are missing an else in all your inner if statements. The result is that even if the code in the if statement is executed, the code after it is always executed and replaces what the code inside the if statement did.
You code like this:
if(ranImgDis.src !== pic1) {
ranImgDis.src = pic1;
} ranImgDis.src = pic2;
should be:
if(ranImgDis.src !== pic1) {
ranImgDis.src = pic1;
} else {
ranImgDis.src = pic2;
}
You can make the code simpler and more flexible by putting the images in an array, and keep the index of the current image rather than checking the source of the image. You can use the length of the array when you create the random number, then you can just add more images to the array without changing anything else in the code.
var pics = [
"http://farm4.staticflickr.com/3691/11268502654_f28f05966c_m.jpg".
"http://farm1.staticflickr.com/33/45336904_1aef569b30_n.jpg",
"http://farm6.staticflickr.com/5211/5384592886_80a512e2c9.jpg"
];
var current = 0;
document.getElementById('ranImgBtn').onclick = function() {
var ranImgDis = document.getElementById('ranImgDis');
ranImgDis.style.width = '300px';
ranImgDis.style.height = '200px';
// get a random number within a range one less than the number of images
var num = Math.floor(Math.random() * (pics.length - 1)) + 1;
// use the random number to pick a different image from the current one
current = (current + num) % pics.length;
ranImgDis.src = pics[current];
}
This'll work, and let you expand the number of images beyond three.
document.getElementById('ranImgBtn').onclick = function() {
var ranImgDis = document.getElementById('ranImgDis');
ranImgDis.style.width = '300px';
ranImgDis.style.height = '200px';
var pics = [
"http://farm4.staticflickr.com/3691/11268502654_f28f05966c_m.jpg",
"http://farm1.staticflickr.com/33/45336904_1aef569b30_n.jpg",
"http://farm6.staticflickr.com/5211/5384592886_80a512e2c9.jpg"
]
var currentSrc = document.getElementById('ranImgDis').src
var newSrc = currentSrc
while (newSrc == currentSrc) {
newSrc = pics[Math.floor( Math.random() * pics.length )]
}
ranImgDis.src = newSrc
}
JSFiddle of it at http://jsfiddle.net/X7HM2/
Why dont you change the logic abit.
Rename the images to numbers from 1 to 3 .
Than generate the random number between 1 to 3 and if that random number is same as currently loaded image regenerate the number , this logic will help you even when you will add images from 3 to finite limit.
Your logic is a bit messy, and also there are some obvious problems like:
if(ranImgDis.src !== pic1) {
ranImgDis.src = pic1;
} ranImgDis.src = pic2;
This will unconditionally set ranImgDis.src to pic2 at the end of the day. So maybe you should think this over. I suggest you to maintain an array instead to avoid dupes.