HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Single Digit Math Quiz

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
digitsinglemathquiz

Problem

I decided to write a very simple web-game:



`function write_at(x, y, text, color, font) {
ctx.fillStyle = color || "black";
ctx.font = font || "50px Arial";
ctx.fillText(text, x + 50, y + 50);
}

function write_at_random(text, color, font) {
write_at(random_choice(range(0, canvas.width - 250)),
random_choice(range(200, canvas.height - 250)),
text, color, font);
}

function random_choice(array) {
index = Math.random() * array.length
return array[Math.floor(index)]
}

function range(start, end) {
return Array.apply(0, Array(end))
.map(function(element, index) {
return index + start;
});
}

function gen_math_expression() {
start = random_choice(range(0, 20));
operator = random_choice(['+', '-', '*']);
end = random_choice(range(0, 20));
return start + operator + end;
}

function single_digit(expr) {
return eval(expr) = 1
}

function gen_single_digit_expression() {
expr = gen_math_expression();
while (!single_digit(expr)) {
expr = gen_math_expression();
}
return expr;
}

function number_from_keycode(keycode) {
return keycode.which - 48;
}

function draw_welcome_and_score() {
write_at(0, 0, "Single Digit Math Quiz");
write_at(600, 0, points);
}

function lose_sound() {
var snd = new Audio("http://www.soundjay.com/misc/sounds/fail-buzzer-02.mp3");
snd.play();
}

function win_sound() {
var snd = new Audio("http://www.soundjay.com/misc/bell-ringing-05.mp3");
snd.play();
}

function main() {
canvas = document.getElementById("canvas")
ctx = canvas.getContext('2d');
points = 0
draw_welcome_and_score()
write_at(0, 100, "Press the result of the operation on your keyboard.", 0, "20px Arial");

expr = gen_single_digit_expression()
write_at_random(expr);

function check_expr_and_go_next(e) {
if (number_from_keycode(e) == eval(expr)) {
points++;
color = '#7CFC00'; // light green
win_sound()
} else {
points--;
color = 'red';
lose_sound()
}
ctx

Solution

You can't currently play with the numbers on the numpad of a keyboard - they have different keycodes to the numbers along the top.

It's normal to camelCase function names rather than snake_case.

Avoid abbreviations e.g. the gen in gen_single_digit_expression.

function number_from_keycode(keycode) { - keycode isn't a keycode at all, it's an event.

Try to remember your semicolons - it's not required but many people (myself included) prefer to see them. There are a couple of very subtle edge cases that can cause problems if you omit them.

eval is evil. You really don't need to invoke the interpreter to do a simple sum!

Here's an example of a simple constructor function (and usage) to show you a way of doing it without eval.

var MathExpression = function(left, operator, right) {
    this.evaluate = function () {
        switch (operator) {
            case '+':
                return left + right;
            case '-':
                return left - right;
            case '*':
                return left * right;
        }
    };
};

var e1 = new MathExpression(1, '+', 8);
console.log(e1.evaluate()); // 9


You don't need to brute force expression generation either. Choose the operator first, then choose the LHS and finally choose a number for the RHS that is within the allowed range.

'+' (addition)

Choose LHS: 1 2)

I'll leave '-' for you to do.

Code Snippets

var MathExpression = function(left, operator, right) {
    this.evaluate = function () {
        switch (operator) {
            case '+':
                return left + right;
            case '-':
                return left - right;
            case '*':
                return left * right;
        }
    };
};

var e1 = new MathExpression(1, '+', 8);
console.log(e1.evaluate()); // 9

Context

StackExchange Code Review Q#91750, answer score: 6

Revisions (0)

No revisions yet.