
Originally Posted by
paul_wilkins
The third time is the charm, time to admit defeat and do something else until at get back to a real computer.
Okay now - removing the need for the timer.
We can check if we need the timer before setting it. That will allow us to remove the need for the separate timer variable.
Code javcascript:
if (counter <= 50) {
setTimeout(roll, 50);
else {
isRolling = false;
counter = 0;
}
Those 50's each have different meanings, so we should place those in a config options area.
Code javascript:
var lotto = function (pick, from, to) {
var opts = {
totalRolls: 50,
rollDelay: 50
},
...
After other refactorings have occurred to simplify things, we'll replace those function parameters with a single options object instead.
The playing variable can be renamed to isRolling, and we can come back to that one later to decide if it's better as a variable, or a property on the button.
buttonText and initalText can go in to the opts object:
Code javascript:
var opts = {
buttonText: "Lotto Lucky Dip",
initialText: "Your Lucky Numbers",
...
playButton.value = opts.buttonText;
...
resultDiv.innerHTML = opts.initialText;
Let us now split up the roll function in to separate parts.
First there is the validation code, which uses pick, from and to.
Code:
if (from >= to) {
window.alert("from value must be less than to value");
return false;
}
if ((to + 1) - from < pick) {
window.alert("Error - You want " + pick + " numbers.\n\n" + "The range you have entered is from " + from + " to " + to + ".\n" + "This leaves " + (rng + 1) + " available random numbers.");
return false;
}
Because both parts return false, we can use a standard validation technique of having an isValid variable at the start of the function, which gets set to false if anything fails, and then return isValid.
Code javascript:
function validateChoices(pick, from, to) {
var isValid = true;
if (from >= to) {
window.alert("from value must be less than to value");
isValid = false;
}
if ((to + 1) - from < pick) {
window.alert("Error - You want " + pick + " numbers.\n\n" + "The range you have entered is from " + from + " to " + to + ".\n" + "This leaves " + (rng + 1) + " available random numbers.");
isValid = false;
}
return isValid;
}
...
if (!validateChoices(pick, from, to)) {
return false;
}
and the part of the roll function that draws the different numbers, can be extracted out to a drawNumbers function
Code:
function drawNumbers(pick, from, to) {
var draw = [],
rng = to - from,
e = (rng + 1),
i,
j,
number;
isRolling = true;
for (i = 0; i < pick; i += 1) {
number = parseInt(from + Math.random() * e, 10);
for (j = 0; j < pick; j) {
if (number !== draw[j]) {
j += 1;
} else {
number = parseInt(from + Math.random() * e, 10);
j = 0;
}
}
draw[i] = number;
}
return draw;
}
...
var i,
dum = "",
disp,
draw = drawNumbers(pick, from, to);
That drawNumbers function can now be refactored, so that instead of rng and e variables, we can just use a delta variable.
Code javascript:
var draw = [],
delta = to - from + 1, // inclusive of both ends
and the random number functions we can move out to a separate getRandomInteger function
Code javascript:
function getRandomInteger(from, to) {
var delta = to - from + 1; // inclusive of both ends
return parseInt(from + Math.random() * delta, 10);
}
...
number = getRandomInteger(from, to);
but we still need to simplify the nested loop that draws a new random number, which is currently:
Code:
for (i = 0; i < pick; i += 1) {
number = getRandomInteger(from, to);
for (j = 0; j < pick; j) {
if (number !== draw[j]) {
j += 1;
} else {
number = getRandomInteger(from, to);
j = 0;
}
}
draw[i] = number;
}
It may be easier to see what we need to do if we switch around the if/else statement
Code:
if (number === draw[j]) {
number = getRandomInteger(from, to);
j = 0;
} else {
j += 1;
}
So what we need to do, is to keep on picking numbers until we find one that has not already been picked.
We have a couple of different options here. We could tidy up the existing structure, or we could come up with a completely different solution where we randomize an array of numbers and then pick the first n from that array.
I'll leave off temporarily here to take care of some things, and consider those options.
Bookmarks