Below you can find the code for creating random 8 numbers between 1 and 80. It puts the random numbers into the numbers array and writes into the divs. Code runs without any problem if it increments the x inside if brackets.
If I put the 'x++' outside of if brackets, after several run I found that sometimes it creates a same random number and finds inside the numbers array. Then it skips and that div comes empty.
What is the difference between incrementing x in if block and incrementing x outside if block ?
Inside the if block :
var numbers = []
var luckyNumber;
var x = 1;
while (x <= 8) {
luckyNumber = Math.floor(Math.random() * 80 + 1);
if (numbers.indexOf(luckyNumber) == -1) {
document.getElementById('k' + x).innerHTML = luckyNumber;
numbers.push(luckyNumber);
x++;
}
}
Outside the if block :
var numbers = []
var luckyNumber;
var x = 1;
while (x <= 8) {
luckyNumber = Math.floor(Math.random() * 80 + 1);
if (numbers.indexOf(luckyNumber) == -1) {
document.getElementById('k' + x).innerHTML = luckyNumber;
numbers.push(luckyNumber);
}
x++;
}
HTML:
<div id="k1">K1</div>
<div id="k2">K2</div>
<div id="k3">K3</div>
<div id="k4">K4</div>
<div id="k5">K5</div>
<div id="k6">K6</div>
<div id="k7">K7</div>
<div id="k8">K8</div>
When you put the increment outside the if condition, if there is a number already present in the numbers array, then it wont enter into the if condition and hence the div never fills up. However you move on to the next div, since you incremented the x value. If you put the x incrementation outside, the x values remains the same when the condition inside if not met, hence in the next iteration the condition may pass or its keep trying.
Execution flow
When you have increment inside if
1) Generate random number.
2) Check in is already generated, if yes skip it. // you see ? when skip no increment happens, because the increment inside the the condition.
3) Generate again and go to step 2.
When you have increment outside if
1) Generate random number.
2) Check in is already generated, if yes skip it. Increase x value to next. //** you see ? incrementing no matter you skip it or not.
3) Generate again and go to step 2.
Because in the first example you advance x only in the case if a unique random number has been generated.
In the second example you advance x regardless if the generated number was unique or not. So it could happen in this case, that out of the 8 times it tried (because that is your while condition), it generated only two unique random numbers, for example.
if you write x++ outside if it always increases by 1 ..and if you put inside if its clear that it increases when your condition is satisfied.. according to this you output may differ.
You could use do while loop for checking, if the number is already taken.
var numbers = [],
luckyNumber,
x = 1;
while (x <= 8) {
do {
luckyNumber = Math.floor(Math.random() * 80 + 1);
} while (numbers.indexOf(luckyNumber) !== -1)
document.getElementById('k' + x).innerHTML = luckyNumber;
numbers.push(luckyNumber);
x++;
}
<div id="k1">K1</div>
<div id="k2">K2</div>
<div id="k3">K3</div>
<div id="k4">K4</div>
<div id="k5">K5</div>
<div id="k6">K6</div>
<div id="k7">K7</div>
<div id="k8">K8</div>
incrementing outside, if block will execute without any condition.
But you are incrementing inside, if block will execute only in that condition is true.
Related
The following code snippet is supposed to increase the opacity of a certain image(its id is 'img') by 0.01 per every 10 milliseconds until its opacity is set to 1.
```var t;
var frontimage=document.getElementById('img');
frontimage.style.top=200+'px';
frontimage.style.opacity=0; //line x
frontimage.style.left=200+'px';
frontimage.style.width=500+'px';
frontimage.style.height=300+'px';
function right(){
if(frontimage.style.opacity>=0 && frontimage.style.opacity<1){ //condition
frontimage.style.opacity=frontimage.style.opacity+0.01; //first statement
console.log(frontimage.style.opacity);
}else{
window.clearInterval(t);
}
}
t= window.setInterval(right,10);```
I believe that the 1st statement after the if condition(lets just call it as the first statement for now) gets executed only once while the other statement in the same condition gets executed perfectly as long as the condition remains true. The first statement is supposed to increase the opacity of the image by 0.01. The reason why I say that the first statement gets executed only once is because the 2nd statement of the same condition, which is supposed to display the opacity of the image on the console always displays 0.01(the opacity had been set to 0 before). Could someone please explain to me as to why the first statement gets executed only once when it is supposed to get executed until the condition remains true?
FYI the following code snippet has been created by modifying the 'line x', 'if condition' and the 'first statement' of the above code snippet and is supposed to decrease the opacity of the same image by 0.01 per every 10 milliseconds. This code gets executed perfectly.
var frontimage=document.getElementById('img');
frontimage.style.top=200+'px';
frontimage.style.opacity=1;
frontimage.style.left=200+'px';
frontimage.style.width=500+'px';
frontimage.style.height=300+'px';
function right(){
if(frontimage.style.opacity>0 && frontimage.style.opacity<=1){
frontimage.style.opacity=frontimage.style.opacity-0.01;
console.log(frontimage.style.opacity);
}else{
window.clearInterval(t);
}
}
t= window.setInterval(right,10);
The opacity property will return a string so you need to convert that to a number before you add to it because the + operator in JavaScript can mean numeric addition (when both operands are numbers) or string concatenation (when one or both operands are strings).
The reason it works with subtraction is because the - only works with numbers and so any operands that aren't numeric will automatically be converted to a number.
Also (FYI) instead of concatenating your pixel sizes with the px to produce a string, just pass both, together, as a string:
Instead of 200 + "px", just use "200px".
var t;
var frontimage = document.getElementById('img');
frontimage.style.top = "200px";
frontimage.style.opacity = 0;
frontimage.style.left = "200px";
frontimage.style.width = "500px";
frontimage.style.height = "300px";
console.log(typeof frontimage.style.opacity); // string
function right(){
if(frontimage.style.opacity>=0 && frontimage.style.opacity<1){
frontimage.style.opacity = parseFloat(frontimage.style.opacity) + 0.01;
//console.log(frontimage.style.opacity);
}else{
clearInterval(t);
}
}
t = setInterval(right,10);
<img src="https://www.drawingforall.net/wp-content/uploads/2020/11/6-how-to-draw-a-smiley-face.jpg.webp" id="img">
SO in your code every time opacity was getting set to 0 that's your code was keep going in an infinite loop.
I have used one temporary counter variable and compared it and increased it by 0.01 and updated it and in the end assigned its value to image.style.opacity.
Moreover, you were comparing string value with number. as it was not with the type check but you should also keep that thing in mind.
let timeIntervalId = null;
const image = document.querySelector("#img");
image.style.top = 200 + 'px';
image.style.left = 200 + 'px';
image.style.width = 500 + 'px';
image.style.height = 300 + 'px';
image.style.opacity = 0;
var counter = 0;
function right() {
if (counter >= 0 && counter <= 1) { //condition
counter = counter + 0.01;
image.style.opacity = counter;
//first statement
console.log(image.style.opacity);
} else {
window.clearInterval(timeIntervalId);
}
}
timeIntervalId = window.setInterval(right, 10);
<img id="img" src="https://cdn.pixabay.com/photo/2022/06/23/09/46/mountain-7279430__480.jpg" />
In the first case (the addition), the opacity property and 0.01 frontimage.style.opacity+0.01 are being concatenated rather than added. This is because the opacity property is provided as a string. In the second case (the subtraction), the opacity property is being cast to a number before the arithmetic operation is performed. Do the following typeof (frontimage.style.opacity) so you can see that what it is actually providing you is a string.You have two options
parseFloat(frontimage.style.opacity) + 0.01
+frontimage.style.opacity + 0.01
I'm learning on Udacity and they have a quiz which I couldn't pass myself. I decided to look at the provided solution but I need to understand the process of the code (I understand some of it). Here it is:
// creates a line of * for a given length
function makeLine(length) {
var line = "";
for (var j = 1; j <= length; j++) {
line += "* ";
}
return line + "\n";
}
// your code goes here. Make sure you call makeLine() in your own code.
function buildTriangle(length) {
// Let's build a huge string equivalent to the triangle
var triangle = "";
//Let's start from the topmost line
var lineNumber = 1;
for(lineNumber=1; lineNumber<=length; lineNumber++){
// We will not print one line at a time.
// Rather, we will make a huge string that will comprise the whole triangle
triangle = triangle + makeLine(lineNumber);
}
return triangle;
}
// test your code by uncommenting the following line
// Note that the function buildTriangle() must return a string
// because the console.log() accepts a string argument
console.log(buildTriangle(10));
I understand that makeLine() will create line of asterisks based on the value of length that passed to it when it gets called inside buildTriangle()
But I don't understand how this line works:
triangle = triangle + makeLine(lineNumber);
Is it not working like the line in makeLine () which is
line += "* ";
What's the difference between using += and triangle = triangle + makeLine(lineNumber)? If they work same then the output should be wrong.
Also please correct me if I'm wrong in my understanding to the variable length in makeLine(length) and buildTriangle (length). Are they different variables because of different scope? Can I change the name of the variable in buildTriangle function to be something like buildTriangle (passedValueToMakeLineFunc)?
Finally it would be highly appreciated if someone imitate the JavaScript engine and described how it will handle that code step by step in plain English.
what's the difference between using += and triangle = triangle + makeLine(lineNumber)
These are equivalent:
triangle = triangle + makeLine(lineNumber);
triangle += makeLine(lineNumber);
…the variable length in makeLine(length) and buildTriangle (length) ... are they different variables…
Correct.
The variables are entirely independent and
you can call them whatever you want.
step by step in plain English
Apologies if this is too verbose or not what you had in mind:
declare functions makeLine and buildTriangle (define but do not execute)
invoke buildTriangle with a single argument (10) to resolve value to be passed to console.log
Execution of buildTriangle:
function buildTriangle(length) {
// Let's build a huge string equivalent to the triangle
var triangle = "";
//Let's start from the topmost line
var lineNumber = 1;
for(lineNumber=1; lineNumber<=length; lineNumber++){
// We will not print one line at a time.
// Rather, we will make a huge string that will comprise the whole triangle
triangle = triangle + makeLine(lineNumber);
}
return triangle;
}
begin execution of buildTriangle with length = 10
declare a variable called triangle with an initial empty string value
declare a variable called lineNumber with an initial value of 1.
initialize for loop: set variable lineNumber to 1 (again)
evaluate for loop condition. is lineNumber less than or equal to length (10)?
lineNumber is 1, which is less than 10, so loop condition is true. execute loop body.
evaluate makeLine(1) (lineNumber is 1)
Execution of makeLine:
function makeLine(length) {
var line = "";
for (var j = 1; j <= length; j++) {
line += "* ";
}
return line + "\n";
}
begin execution of makeLine with length = 1
declare variable called line and initialize to empty string
begin for loop: declare and initialize variable j with initial value 1
evaluate for loop condition. is j less than or equal to length (1)?
j is 1, which is equal to 1, so loop condition is true. execute loop body.
append "* " to line. (line is now "* ")
increment j. j is now 2.
evaluate for loop condition. is j less than or equal to length (1)?
j is 2. condition is false. exit loop.
return line value with a newline appended: ("* \n")
(Resume buildTriangle execution)
set triangle to its current value (empty string) plus resolved makeLine value: triangle is now "* \n"
end of loop body. run post-loop expression (lineNumber++)
set lineNumber to 2
evaluate for loop condition. is lineNumber less than or equal to length (10)?
lineNumber is 2, which is less than 10, so loop condition is true. execute loop body.
evaluate makeLine(2) (lineNumber is 2)
Execution of makeLine:
begin execution of makeLine with length = 2
declare variable called line and initialize to empty string
begin for loop: declare and initialize variable j with initial value 1
evaluate for loop condition. is j less than or equal to length (2)?
j is 1, which is less than 2, so loop condition is true. execute loop body.
append "* " to line. (line is now "* ")
increment j. j is now 2.
evaluate for loop condition. is j less than or equal to length (2)?
j is 2, which is equal to 2, so loop condition is true. execute loop body.
append "* " to line. (line is now "* * ")
increment j. j is now 3.
evaluate for loop condition. is j less than or equal to length (2)?
j is 3. condition is false. exit loop.
return line value with a newline appended: ("* * \n")
(Resume buildTriangle execution)
set triangle to its current value "* \n" plus resolved makeLine value: triangle is now "* \n* * \n"
end of loop body. run post-loop expression (lineNumber++)
set lineNumber to 3
evaluate for loop condition. is lineNumber less than or equal to length (10)?
lineNumber is 3, which is less than 10, so loop condition is true. execute loop body.
evaluate makeLine(3) (lineNumber is 3)
Repeat steps above until lineNumber reaches 11 and loop exits.
return value of triangle to caller and exit buildTriangle. At this point the value of triangle is:
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
* * * * * * * * * *
invoke console.log with the value returned by buildTriangle.
exit
Your example included here for reference:
// creates a line of * for a given length
function makeLine(length) {
var line = "";
for (var j = 1; j <= length; j++) {
line += "* ";
}
return line + "\n";
}
// your code goes here. Make sure you call makeLine() in your own code.
function buildTriangle(length) {
// Let's build a huge string equivalent to the triangle
var triangle = "";
//Let's start from the topmost line
var lineNumber = 1;
for(lineNumber=1; lineNumber<=length; lineNumber++){
// We will not print one line at a time.
// Rather, we will make a huge string that will comprise the whole triangle
triangle = triangle + makeLine(lineNumber);
}
return triangle;
}
// test your code by uncommenting the following line
// Note that the function buildTriangle() must return a string
// because the console.log() accepts a string argument
console.log(buildTriangle(10));
Addition assignment operator (+=)
someVar += "someString" is the same as someVar = someVar + "someString"
Go ahead and replace your example with triangle += makeLine(lineNumber) and you'll see you get the same triangle.
The 2 lengths
In this case, they are both parameters to the functions makeLine and buildTriangle.
Function parameters are scoped to the function block, meaning they are only available inside the function, not accessible outside.
Name them as you like, this has no effect outside of the function block.
Note that if a length parameter did in fact exist outside of the function declarations, the length parameter would over/hide the external variable from use inside the function.
var length = 4;
console.log("outer", length); // 4
function someFunction(length) {
console.log("inner", length); // 5
}
someFunction(5);
console.log("outer", length); // 4
Code in english
I'm going to assume this is a little too detailed in some places and maybe not enough in others. Enjoy the story!
The makeLine function is declared (but not run yet)
The buildTriangle function is declared (but not run yet)
We hit a console.log() with a param of a function call (buildTriangle(10)). We'll execute that function, and the result of it will be passed to the log function call.
We've stepped into the buildTriangle function with a param length of value 10.
We make a triangle variable we'll build out the entire triangle into, new lines and all, initialized to an empty string.
We declare a lineNumber variable set to 1.
This one is just to mess with you
It did not need to be done before the for loop, would have been just the same to for (var lineNumber=1; lineNumber<=length; lineNumber++){ ... } and not declare it before hand.
It does not matter what it was or wasn't initialized to as the for loop sets it to 1 as it starts.
We hit a for loop, for(lineNumber=1; lineNumber<=length; lineNumber++)
We set lineNumber to 1
We will continue to run another iteration of this loop until lineNumber is <= length (10) (So up until and including 10)
We will, upon the completion of each iteration, before checking the continuation condition, increment the lineNumber by 1 (lineNumber++).
For each iteration of the loop (lineNumber values 1,2,3,4,5,6,7,8,9,10) we execute triangle = triangle + makeLine(lineNumber); Which just takes the current triangle string, appends the result of makeLine(lineNumber) to it, and assigns that value to triangle.
We've stepped into the makeLine function with a param length of value 1.
Note at this point, the only variable available to our scope is the length param. (Besides the 2 functions I suppose)
We initialize a new variable line to an empty string.
Note, this will be a brand new / separate line variable for every execution of this function Sounds like this is where you maybe hung up?
Since the line variable is declared inside the function, it is scoped there, and is not accessible outside or across function executions.
This would be different if it were declared outside of the function and not reset at the begining. Then every execution would continue to just add on.
We encounter another for loop, this time with the iterator variable declared inside (j) for (var j = 1; j <= length; j++) { ... }
We declare and initialize j to 1
We will continue to run another iteration of this loop until j is <= length (1) (So just 1 on this makeLine execution, subsequent times, 1-2, 1-3, ..., 1-10)
We will, upon the completion of each iteration, before checking the continuation condition, increment the j by 1 (j++).
For each iteration of the loop we execute line += "* "; which just takes the current line string, appends a "* " and assigns that value to line.
After this loop we encounter a return statement that is the result of combining our build out line with a newline character ("\n").
Assuming we've made it through all of our buildTriangle for loop iterations, we encounter our return statement and return the build out triangle.
We've now supplied the return value to be supplied as the parameter to console.log.
done.
I am not able to understand this solution properly. I understood the Array declaration part but I am not sure what's going on in the while loop.
function roman(num) {
var decimalValue = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
var romanNumeral = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
var romanized = '';
for (var index = 0; index < decimalValue.length; index++) {
while (decimalValue[index] <= num) {
romanized += romanNumeral[index];
num -= decimalValue[index];
}
}
return romanized;
}
Next time you're stuck on a loop-based problem like this, I would suggest learning about the debugger; command and breakpoints.
Let's use a specific number as an example, say... 2,652. Here's what will happen:
Starting with 1,000 (the first number in decimalValue), check if 2,562 > 1,000.
It is! So, we know that the Roman numeral for 2,652 has at least one M in it. We add M to our output Roman numeral.
We've "accounted for" 1,000 of our number as a numeral, so we remove 1,000 from the number. We now have 1,562.
We jump back up to checking if num > 1,000. It still is. So, we add another M and subtract another 1,000. Now we have 562 of our number "unaccounted for."
This time, when we jump up to the start of our while() loop to test if num > 1,000, we find that it isn't the case! So the loop does not run this time.
This process repeats for all the numbers in decimalValue; all the numbers that have Roman numeral equivalents.
So, we check 900/CM, and find that this number (which is now down to 562) can not be represented as a sum including 900.
Next, we check 500, and find that it can! We add the Roman numeral for 500 to our current romanized string and carry on. We now have MMD and our number is down to 62 "unaccounted for" digits/units/whatever we're counting.
The next number to catch our while() loop is 50, since 62 > 50. We add the L for 50 and bring our number down to 12. Then again on 10, and we add an X. Finally, we match on the last item in decimalValue, 1, twice, and add two Is.
Our final string for this number, 2,652, is MMDXII.
The While loop does a comparison starting from index zero to the last and compares if the value of num passed in is less that the value at index of decimal value array if it is, It will then it appends(concatenate) the ruman numeral at that particular index to the randomize and subtract the equivalent number in decimal(mutate the num variable) from the num which was sent in.
It then checks if num is still greater than the value at that particular index indicating decimal.
taking a walk through with 3002 as example.
First check if index 0 which has 1000 is less than 3002 true
Set randomize to ruman numeral at position index. In this case we have 'M' then subtract decimal at position index from num(3002) we now have num = 2002.
The while loop iterate again and check is 1000 less than 2002? yes it is so it will execute the body of the while loop again.
Append(Concatenate the value at position index(which has not changed yet) to the randomize variable this case index is still zero so we appending 'M' now randomize is 'MM'. Subtract the decimal at position index(0) from num(2002) we now have num = 1002.
Iterate the while loop and check if decimal value at position index(0) of the decimalValue array is less than num(1002) which is true in this case. execute the loop as before.
Append(Concatenate the value at position index(which has not changed yet) to the randomize variable this case index is still zero so we appending 'M' now randomize is 'MMM'. Subtract the decimal at position index(0) from num(1002) we now have num = 2.
Iterate the while loop and check if decimal value at position index(0) of the decimalValue array is less than num(2) which is false in this case. Stop execution of the loop and increment the value of index in the for loop and do the checks again. till you reach the end.
decimalValue[i] represents the same value as romanNumeral[i] for any i. This represents the same data as if the author used a object {4:"IV", 5:"V", ...} except objects to not preserve order. Since the author wants to check larger numbers before smaller numbers, they use this to preserve order and also associate the decimal values with the Roman Numerals.
The loop is confusing because javascript uses + to represent both numerical addition, 2+4==6, and string concatenation, "a"+"b"=="ab".
romanized += romanNumeral[index] means append the string contained in romanNumberal[index] to the end of the string romanized.
num -= decimalValue[index]; means decrease num by the number contained in decimalValue[index]
//start at the big values that have roman number codes, then try smaller values
for (var index = 0; index < decimalValue.length; index++) {
//if the value we are testing is less or equal to num
// (actually loop but for reasons explained below)
while (decimalValue[index] <= num) {
//append the string in romanNumberal to
//the end of the string in the variable romanized
romanized += romanNumeral[index];
//from the number num, substract the
//value we just added to romanized
num -= decimalValue[index];
//what about a case like 3, which needs
//repeated letters in that case "III".
//That is why this is a while statement and not an if.
//the while loop keeps processing
//those cases until we have enough repeated letters.
}
}
When we need more than one of the same the same letter, then decimalvalue[index] will still be less than or equal to num.
This is because when we reach decimalvalue[index], we know that num < decimalvalue[index-1] (except for the start), because the while loop prevents index from increasing until that is true.
Often the loop only runs once. For example, going from decimalvalue[index] == 10 to decimalvalue[index] == 9 loop only runs once at most because num < 10 and 10-9==1 which is less than 9. So then, the while loop acts as just an if statement.
The loop only loops for values where duplicate letters are valid in roman numerals, because that is were the drop in value between decimalvalue[i-1] and decimal[i] is great enough. More precisely those are the only times when decimalvalue[i-1]/decimalvalue[i] >= 2 (that is 2 or more of a value in decimalvalue[i] fits in the previous decimalvalue)
if you know the division algorithm from math this is kinda like that.
Found this codepen on google. The code is pretty straightforward, I hope it will help.
Roman Numeral Converter in Javascript
function convert(num){
num = parseInt(num);
var result = '',
ref = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'],
xis = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
if (num >= 4000) {
num += ''; // need to convert to string for .substring()
result = '<span style="border-top: 1px solid; margin-top: 2px; display: inline-block; padding-top: 0px;">'+convert(num.substring(0,num.length-3))+'</span>';
num = num.substring(num.length-3);
}
for (x = 0; x < ref.length; x++){
while(num >= xis[x]){
result += ref[x];
num -= xis[x];
}
}
return result;
}
$('input').on('keyup keydown change',function(e){
var $this = $(this),
val = $this.val();
if (val.length == 0) return $('#result').html('');
if (isNaN(val)) return $('#result').html('Invalid input');
if (e.type == 'keydown'){
if (e.keyCode === 38) $this.val(++val);
if (e.keyCode === 40) $this.val(--val);
}
if (val < 1) return $('#result').html('Number is too small');
$('#result').html(convert(val));
})
I just have a question about some while loop logic.
So, when you write a loop that displays a string of numbers to a document and say that while the loop is <= (less than or equal to) say, 5, and you tell the loop to add 1 each time this is true, wouldn't that mean that: while the loop is equal to 5 that it would add one to 5 too? It doesn't, but I messed up on some code when I was practicing and noticed that when it is equal to five it does not add one, but I thought it would...
console.log('2nd Loop:');
text = '';
// loop:
i = 1;
while (i <= 5) {
text += i + ' ';
i += 1
}
console.log(text); // Should print `1 2 3 4 5 `.
the reason your text doesn't display a 6 isn't because i isn't incremented. It's because the text gets added onto before it's incremented.
In other words when executing on that 5th loop, the text would add on 5, and then it would increment i, and then it would check the loop again, which would no longer be valid and therefore 6 is never printed.
In memory, it adds one. It doesn't add it to the text though.
Since you're incrementing the value after assigning it and then the loop condition fails, it doesn't get to the part where you concatenate the string.
It does. Just output i and you'll see it's 6. text never gets the 6 because of when you increment i.
console.log('2nd Loop:');
text = '';
// loop:
i = 1;
while (i <= 5) {
text += i + ' ';
i += 1
}
console.log(text,i); // Should print `1 2 3 4 5 `.
b/c you +1 after you add i to text, all you need to do is switch the two line order.
EDIT
if you want it start with one just change your i to 0 to start with.
i = 1
console.log('2nd Loop:');
text = '';
i = 0;
while (i <= 5) {
i += 1
text += i + ' ';
}
console.log(text);
I'm trying to generate a random number between 1-75, then compare it to an array so that I can later use the result as an argument for an if / else statement; (i.e., if the number is in the array, do this, otherwise do that.)
Here is the relevant code:
var pickable = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75];
var grid = [7,14,8,10,4,25,18,20,26,27,37,33,40,45,32,48,55,49,52,53,61,63,74,73,67];
function pick()
{
var temp1 = Math.floor(Math.random() * (pickable.length));
var temp2 = temp1.toString();
var check = grid.indexOf(temp2);
alert (check + "\n" + grid);
}
But this code isn't giving me index numbers that make sense; It returns -1 when the number is clearly in the array, returns other numbers for numbers that are not in the array, or returns a number that has no obvious relationship to the position of the number in the array. Why is this not working, and what would work better? Please keep in mind, I'm just learning to code, so detailed explanations are appreciated.
After a bit of experimenting, I've found that what it is doing is picking the random number, writing it to the appropriate places on the screen, then subtracting the number of iterations of the loop before using that number to check the index. (I think.) In other words, the first time I cick the button, it displays 48 on the screen, but searches the index for 47. The next time I click the button it displays 56, but searches for 54, etc. Here is the entire function:
function pick()
{
if (pickable.length > 0)
{
var temp1 = Math.floor(Math.random() * (pickable.length));
var temp2 = temp1.toString();
var check = grid.indexOf(temp2);
alert ("index: " + check + "\nball: " + temp1 + "\n");
document.getElementById("ballNum").innerHTML = pickable[temp1];
pickable[temp1] = pickable[0];
pickable.shift();
picked.push(document.getElementById("ballNum").innerHTML);
document.getElementById("pickedNums").innerHTML = picked.join("| ");
}
else
{
alert("You are out of Bingo balls! \nPlease start over by clicking the " +
" \n\"Populate Board\" button.");
}
}