I wrote this entire program earlier today, and would like to get it reviewed.
It is an arcade style math game, where you are presented with two expressions on the left and right side. You will determine whether or not the first expression is less than, equal to or greater than the second expression.
If you get the question right, two new expressions will pop up. If you get it wrong, or you spend more than 5 seconds, you will lose. As you level up, the game gets harder and harder.
I will do my best to breakdown the code.
var scoreIndicator = document.getElementById("score");
var levelIndicator = document.getElementById("level");
var gameBlock = document.getElementsByClassName("game-block")[0];
var controls = document.getElementsByClassName("controls")[0];
var score = 0;
var level = 1;
var colors = ["red", "orange", "yellow", "green", "lightblue"];
I'm creating multiple arrays to store numbers here.
var easyNums = [];
var medNums = [];
var hardNums = [];
var extremeNums = [];
var operators = ["+", "-", "*", "/"];
I will fill these arrays with different numbers.
easyNums
is designed for the lowest difficulty and only consists of positive digits between 1 and 10.
medNums
includes all the digits that easyNums` does plus negative numbers greater than -10. It also includes all positive numbers less than 20
hardNums
contains all numbers between -100 and 100.
extremeNums
contains all triple digit numbers, positive and negative.
for (var i = 1; i <= 10; i++) {
easyNums.push(i);
medNums.push(i);
medNums.push(-i);
hardNums.push(i);
hardNums.push(-i);
extremeNums.push(i);
extremeNums.push(-i);
}
for (var i = 11; i < 20; i++) {
medNums.push(i);
medNums.push(-i);
hardNums.push(i);
hardNums.push(-i);
extremeNums.push(i);
extremeNums.push(-i);
}
for (var i = 21; i < 100; i++) {
hardNums.push(i);
hardNums.push(-i);
extremeNums.push(i);
extremeNums.push(-i);
}
for (var i = 100; i < 1000; i++) {
extremeNums.push(i);
extremeNums.push(-i);
}
Here I'm creating functions to generate a random number from the number sets. At higher levels, the expressions will not contain just addition, but also subtraction, multiplication and division. To add to the difficulty, the expressions will also have random colors.
function randEasy() {
return easyNums[Math.floor(Math.random() * easyNums.length)];
}
function randMed() {
return medNums[Math.floor(Math.random() * medNums.length)];
}
function randHard() {
return hardNums[Math.floor(Math.random() * hardNums.length)];
}
function randExtreme() {
return extremeNums[Math.floor(Math.random() * extremeNums.length)];
}
function randOperation() {
return operators[Math.floor(Math.random() * operators.length)];
}
function randColor() {
return colors[Math.floor(Math.random() * colors.length)];
}
As the name suggests, this function generates both the left-hand and right-hand expressions. Each expression contains two numbers and an operand. Because I will be removing and re-adding expressions, I'm using classes and not ids.
I'm also applying the styles to both expressions.
function generateExpressions() {
var exp1 = document.createElement("div");
var exp2 = document.createElement("div");
[exp1, exp2].forEach(function(exp,index) {
exp.classList.add("exp" + (index + 1));
exp.style.color = "white";
exp.style.background = randColor();
exp.style.textAlign = "center";
exp.style.padding = "8px 0";
gameBlock.appendChild(exp);
I mentioned earlier that the game gets harder and harder the longer you stay alive. At first, you will get easy questions you will be able to answer. As you level up, you're now getting harder questions from the harder numbersets.
if (level == 1) {
exp.innerHTML = "" + randEasy() + " + " + randEasy();
}
else if (level == 2 || level == 3) {
exp.innerHTML = "" + randMed() + " + " + randMed();
}
else if (level == 4 || level == 5) {
exp.innerHTML = "" + randHard() + " + " + randHard();
}
else if (level == 6 || level == 7) {
exp.innerHTML = "" + randHard() + randOperation() + randHard();
}
else {
exp.innerHTML = "" + randExtreme() + randOperation() +
randExtreme();
}
});
}
This code is used to create the buttons. I think it's pretty self-explanatory
function createButtons() {
var buttonGroup = document.createElement("div");
buttonGroup.className = "button-group";
controls.appendChild(buttonGroup);
var greaterThan = document.createElement("button");
greaterThan.classList.add("greaterThan");
var equals = document.createElement("button");
equals.classList.add("equals");
var lessThan = document.createElement("button");
lessThan.classList.add("lessThan");
greaterThan.innerHTML = ">";
equals.innerHTML = "=";
lessThan.innerHTML ="<";
buttonGroup.appendChild(greaterThan);
buttonGroup.appendChild(equals);
buttonGroup.appendChild(lessThan);
}
This is used to increase the score. If you got a problem right, you will gain 1 point. The existing expressions will be removed and replaced by new expressions which will be animated. The score will be checked to see if you met the requirements for leveling up.
function incrementScore() {
score++;
scoreIndicator.innerHTML = "<strong>Score: </strong>" + score;
$(".exp1, .exp2").remove();
generateExpressions();
animateDivs();
incrementLevel();
}
This is the function for leveling up. I thought a switch
statement would work best here.
function incrementLevel() {
switch(true) {
case (score < 10):
level = 1;
break;
case (score >= 10 && score < 20):
level = 2;
break;
case (score >= 20 && score < 30):
level = 3;
break;
case (score >= 30 && score < 40):
level = 4;
break;
case (score >= 40 && score < 50):
level = 5;
break;
case (score >= 50):
level = 6;
break;
}
levelIndicator.innerHTML = "<strong>Level: </strong>" + level;
}
These functions are used to evaluate the results. There is one for each of the three buttons.
$("body").on("click", ".lessThan", function() {
var num1 = eval($(".exp1").text());
var num2 = eval($(".exp2").text());
(num1 < num2) ? incrementScore() : endGame();
});
$("body").on("click", ".equals", function() {
var num1 = eval($(".exp1").text());
var num2 = eval($(".exp2").text());
(num1 == num2) ? incrementScore() : endGame();
});
$("body").on("click", ".greaterThan", function() {
var num1 = eval($(".exp1").text());
var num2 = eval($(".exp2").text());
(num1 > num2) ? incrementScore() : endGame();
});
This function is used to start a new game. Again, I think it's fairly self-explanatory.
function startGame() {
score = 0;
level = 1;
generateExpressions();
animateDivs();
scoreIndicator.innerHTML ="<strong>Score: </strong>" + score;
levelIndicator.innerHTML = "<strong>Level: </strong>" + level;
createButtons();
}
When a game ends, we will remove all the game elements.
function endGame() {
$(".exp1, .exp2, .lessThan, .equals, .greaterThan").remove();
}
This is where the animation and timing function comes in.
function animateDivs() {
$(".exp2").animate( { "marginRight": "70%" }, 5000);
var previousScore = score;
setTimeout(function() {
if (score == previousScore) {
endGame()
}
}, 5000);
}
I really worked hard creating this post, because I want to analyze my code and improve as a developer. I put a lot of effort into this post.
You guys are welcome to try out the game here.