Single Digit Math Quiz 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) &lt;= 9 &amp;&amp; eval(expr) &gt;= 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.clearRect(0, 0, canvas.width, canvas.height)
    canvas.style.background = color;
    draw_welcome_and_score()
    expr = gen_single_digit_expression()
    write_at_random(expr);
  }

  window.addEventListener("keydown", check_expr_and_go_next, true);


}

main()
&lt;html&gt;
&lt;canvas id="canvas" width="800" height="600" style="border:1px solid #000000;"&gt;
&lt;/canvas&gt;
&lt;/html&gt;
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 &lt;= LHS &lt;= 8
Choose RHS: 1 &lt;= RHS &lt;= 9 - LHS  

LHS choose 5.
RHS can be 1, 2, 3 or 4 to yield a single digit answer.  

You can do the same for the other operators:  

'*' (multiplication)
Choose LHS: 1 &lt;= LHS &lt;= 4
Choose RHs: 1 &lt;= RHS &lt;= 9/LHS (rounded down).  

LHS choose 4.
RHS can be 1 or 2 to yield a single digit number. (9/4 = 2.25 -> 2)  

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