More refactoring based you guys' great feedback. This time around I worked on using global/local variables properly and efficiently, putting return values to use, renaming variables so that the code is more understandable, and simplifying functions so that they serve one main purpose.
My main concerns/focuses now: I'm not sure that I like the global variable newScoreAlertIndex
and how it's being implemented, and am working on how to better write the newScoreAlert
function. Also, since the while loop can essentially be divided up into two structurally equivalent parts (the user's turn and the computer's turn), I was debating creating a function to run a full turn, and call it twice in the while loop, switching between user and computer factor/score parameters. However I felt like this blurred the line between query and command, so I left it as is. Let me know what you think.
var welcome = alert("Welcome to Zeros or Ones! Both you and the computer will start the game off with the number '2'. Whoever gets down to '1' or '0' first wins!"),
rules = alert("This is a turn based game. You must first choose a factor from the computer's number. If the chosen factor is even, it is added to your current score; if odd, it is subtracted. After this, the computer chooses a factor from your new number. This back-and-forth continues until someone gets their number down to 1 or 0."),
rules2 = alert("A few exceptions:\n\nWhen an odd number is being subtracted from your score, if your resulting score is a negative number, the absolute value is taken, turning the negative number into a positive.\n\nNeither player is allowed to win the game on a 2. For instance if your score is 2, you cannot choose the factors 1 or 3 from the computer's score.\n\nException to the exception! In the case that you have a 2 and the computer has a 3, it is allowable to choose either factor.");
var compScore = 2,
userScore = 2,
operator,
newScoreAlertIndex = 1;
function getFactors(integer) {
var factors = [];
for(var i = 1; i <= integer; i++){
if(integer % i === 0){
factors.push(i);
}
}
return factors;
}
function getUserFactor() {
var possibleFactors = getFactors(compScore);
var factor;
while (true) {
factor = parseInt(prompt("Your score: " + userScore + ". Computer's score: " + compScore + ". Which factor do you choose from the computer's score?"));
if (possibleFactors.indexOf(factor) !== -1) {
if (userScore !== 2 ||
userScore === 2 && compScore === 3 ||
userScore === 2 && compScore !== 3 && factor !== 1 && factor !== 3) {
return factor;
}
}
alert("Not a valid entry.");
}
}
function getCompFactor() {
var possibleFactors = getFactors(userScore);
var factor = possibleFactors[Math.floor(Math.random() * possibleFactors.length)];
if (compScore === 2 && userScore !== 3) {
while (factor === 1 || factor === 3) {
factor = possibleFactors[Math.floor(Math.random() * possibleFactors.length)];
}
}
return factor;
}
function updateScore(chosenFactor, oldScore) {
var newScore;
if (chosenFactor % 2 === 0) {
newScore = oldScore + chosenFactor;
operator = "added to";
} else {
newScore = oldScore - chosenFactor;
if (newScore < 0) {
newScore = newScore * -1;
}
operator = "subtracted from";
}
return newScore;
}
function newScoreAlert(chosenFactor, operator, newScore) {
var alertText;
if (newScoreAlertIndex % 2 !== 0) { alertText = " your score. You now have "; }
else { alertText = " the computer's score. The computer now has "; }
alert(chosenFactor + " was " + operator + alertText + newScore + ".");
newScoreAlertIndex += 1;
}
function checkForWin(number) {
if (number === 1 || number === 0) { return true; }
else { return false; }
}
while(true) {
var userFactor = getUserFactor();
userScore = updateScore(userFactor, userScore);
newScoreAlert(userFactor, operator, userScore);
if (checkForWin(userScore)) {
alert("YAY! You won! :D");
break;
}
var compFactor = getCompFactor();
compScore = updateScore(compFactor, compScore);
newScoreAlert(compFactor, operator, compScore);
if (checkForWin(compScore)) {
alert("Sorry! You lost :/");
break;
}
}
var welcome = alert ...
means that welcome is assigned to None. Remove everything before the=
. Replaceif cond return true else return false
\$\endgroup\$pop
method, common to stacks and arrays, as an example: It both returns the last element and removes it from the stack/array. Sure you could do that with 2 separate calls, but it's more useful as it is. \$\endgroup\$