1

I have the below code that generates non repeating random numbers for a bingo card. For you to understand, I am also putting HTML code of the same:

window.onload = newCard;
var usedNums = new Array(76);


function newCard() {
    if (document.getElementById) {
        for (var i=0; i<24; i++) {
            setSquare(i);
        }
    }
    else {
        alert("Sorry, your browser doesn't support this script");
    }
}

function setSquare(thisSquare) {
    var currSquare = "square" + thisSquare;
    var colPlace = new Array(0,1,2,3,4,0,1,2,3,4,0,1,3,4,0,1,2,3,4,0,1,2,3,4);
    var colBasis = colPlace[thisSquare] * 15;
    var newNum;

    do {
        newNum = colBasis + getNewNum() + 1;
    }
    while (usedNums[newNum]);

    usedNums[newNum] = true;
    document.getElementById(currSquare).innerHTML = newNum;
}

function getNewNum() {
    return Math.floor(Math.random() * 15);
}

==================================================================================

    <html>
<head>
    <title>Make Your Own Bingo Card</title>
    <link rel="stylesheet" rev="stylesheet" href="script.css" />
    <script type="text/javascript" src="script.js">
    </script>
</head>
<body>
<h1>Create A Bingo Card</h1>
<table>
    <tr>
        <th width="20%">B</th>
        <th width="20%">I</th>
        <th width="20%">N</th>
        <th width="20%">G</th>
        <th width="20%">O</th>
    </tr>
    <tr>
        <td id="square0">&nbsp;</td>
        <td id="square1">&nbsp;</td>
        <td id="square2">&nbsp;</td>
        <td id="square3">&nbsp;</td>
        <td id="square4">&nbsp;</td>
    </tr>
    <tr>
        <td id="square5">&nbsp;</td>
        <td id="square6">&nbsp;</td>
        <td id="square7">&nbsp;</td>
        <td id="square8">&nbsp;</td>
        <td id="square9">&nbsp;</td>
    </tr>
    <tr>
        <td id="square10">&nbsp;</td>
        <td id="square11">&nbsp;</td>
        <td id="free">Free</td>
        <td id="square12">&nbsp;</td>
        <td id="square13">&nbsp;</td>
    </tr>
    <tr>
        <td id="square14">&nbsp;</td>
        <td id="square15">&nbsp;</td>
        <td id="square16">&nbsp;</td>
        <td id="square17">&nbsp;</td>
        <td id="square18">&nbsp;</td>
    </tr>
    <tr>
        <td id="square19">&nbsp;</td>
        <td id="square20">&nbsp;</td>
        <td id="square21">&nbsp;</td>
        <td id="square22">&nbsp;</td>
        <td id="square23">&nbsp;</td>
    </tr>
</table>
<p><a href="script.html" id="reload">Click here</a> to create a new card</p>
</body>
</html>

Is it correct that, "while (usedNums[newNum]);" is checking whether a number exists in the array? Is that correct that, "usedNums[newNum] = true;" is setting the item in the array to a non-zero value?

If the above two questions are correct, then I am wondering, how is it generating non-repeating random numbers?

If I make "usedNums[newNum]" to false, it generates repeating numbers, can you please explain the backend functionality of this statement?

If convenient, also paste the reference links, I want to study in detail about this.

danrodi
  • 296
  • 1
  • 4
  • 24
Yogie
  • 986
  • 2
  • 12
  • 14
  • Possibly of interest to you: http://phrogz.net/tmp/7x7_random.html Just calculate all the numbers, then [shuffle them](http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array), and then draw them out in shuffled order. – Phrogz Jul 30 '14 at 13:49

2 Answers2

2

I'll try to explain what happens in chunks.

First the variable newNum is declared:

var newNum; //The value is undefined

Then a do-while-loop is used. To keep it short the main benefit of the do-while-loop is that it will always be executed at least ones. You can read about the do-while-loop here.

do {
    //This will run at least ones.
    newNum = colBasis + getNewNum() + 1;
} while (usedNums[newNum]); //Here we check if the new number is all ready used.

usedNums[newNum] = true;

To explain the above snippet I'm going to use an example:

  1. The loop runs the first time and the number 3 is generated so newNum = 3.
  2. The loop conditional is checked, meaning we check if the value at usedNums[3] is true.
  3. Because it's the first time we generate a number usedNums[3] is undefined which evalutes to false - this means the the loop exits.
  4. We now set the value of usedNums[3] to true indicating that the number has been used.
  5. We try to generate a new number.
  6. The loop runs the first time and again it generates 3 as the new number.
  7. The loop conditional is checked and because usedNums[3] is now true, the loop runs again.
  8. This time the loop generates 56 and repeats step 2-4 with the number 56 instead of 3.

I hope this clarifies what is going on in the code.

kaspermoerch
  • 16,127
  • 4
  • 44
  • 67
1

The first statement is correct. Because Javascript is a weakly typed language, you can do cross-type comparisons. If an object is not undefined, and you do a boolean comparison on it, it will return true. (the opposite also applies)

Since true is not undefined, the second statement is also correct.

The reason you get repeated numbers if you turn usedNums[newNum] to false, is also related to this. The following while loop (which assigns the random numbers) is only executed once when usedNums[newNum] equals false or undefined

 do {
        newNum = colBasis + getNewNum() + 1;
    }
    while (usedNums[newNum]);

for the rest, this isn't exactly rocket science. If you want to know how it generates random numbers, look at function getNewNum (because it's doing exactly that using Javascript's Math.random() function)

To get a better understanding of what "weakly typed" means, i suggest this wikipedia article on weakly typed vs strong typed

Timothy Groote
  • 8,614
  • 26
  • 52