5
\$\begingroup\$

I am a beginner in programming and I wrote a simple game in Javascript in which you have to solve exercises. Division exercises have to be solved without remainder. If you have tips for improving the code I would like to hear them.

var level = 1;
var experience = 0;
var experience_needed = 10;

function increase_level()
{
    while(experience >= experience_needed)
    {
        level++;
        experience -= experience_needed;
        experience_needed = 5 * Math.pow(level, 2) + 5 * level;
        
        show_stats();
    }
}

function show_stats()
{
    document.getElementById("level").innerHTML = "Level: " + level;
    document.getElementById("experience").innerHTML = "Experience: " + experience + " / " + experience_needed;
}

generate_exercises = function() 
{
    exercises = document.getElementById("exercises");
    exercises.innerHTML = "";
    var generate = document.getElementById("generate");
    generate.innerHTML = "Check Exercises";
    generate.onclick = check_exercises;
    
    for(var i = 0; i < 10; i++)
    {
        var exercise = document.createElement("div");
        var textarea = document.createElement("textarea");
        textarea.id = i;
        textarea.rows = 1;
        textarea.cols = 3;
        var exercise_type = Math.floor(Math.random() * 4);
        var number1;
        var number2;
        
        if(exercise_type == 0)
        {
            number1 = Math.floor(Math.random() * 20) + 1;
            number2 = Math.floor(Math.random() * 20) + 1;
            textarea.solution = number1 + number2;
            exercise.innerHTML = number1 + " + " + number2 + " = ";
            
        }
        else if(exercise_type == 1)
        {
            number1 = Math.floor(Math.random() * 25) + 1;
            number2 = Math.floor(Math.random() * 20) + 1;
            textarea.solution = number1 - number2;
            exercise.innerHTML = number1 + " - " + number2 + " = ";
        }
        else if(exercise_type == 2)
        {
            number1 = Math.floor(Math.random() * 15) + 1;
            number2 = Math.floor(Math.random() * 15) + 1;
            textarea.solution = number1 * number2;
            exercise.innerHTML = number1 + " * " + number2 + " = ";
        }
        else if(exercise_type == 3)
        {
            number1 = Math.floor(Math.random() * 100) + 1;
            number2 = Math.floor(Math.random() * 20) + 1;
            textarea.solution = Math.floor(number1 / number2);
            exercise.innerHTML = number1 + " / " + number2 + " = ";
        }
        
        exercise.append(textarea);
        exercise.append(document.createElement("br"));
        exercise.append(document.createElement("br"));
        exercises.append(exercise);
    }
}

check_exercises = function() 
{
    var generate = document.getElementById("generate");
    generate.innerHTML = "Generate Exercises";
    generate.onclick= generate_exercises;
    
    var right = 0;
    
    for(var i = 0; i < 10; i++)
    {
        textarea = document.getElementById(i);
        if(textarea.value == textarea.solution)
        {
            right++;
            experience++;
        }
    }
    
    exercises = document.getElementById("exercises");
    exercises.innerHTML = "You have solved " + right + " of 10 exercises successfully!";
    increase_level();
    show_stats();
}

show_stats();
<html>
    <head>
        <title>Calculate</title>
        <script type="css">
            textarea
            {
                resize:none;
            }
        </script>
    </head>
    <body>
        <h3>Statistics</h3>
        <h4 id=level></h4>
        <h4 id=experience></h4>
        <div id=stats></div>
        <hr>
        <button id="generate" onclick="generate_exercises()">Generate Exercises</button>
        <hr/>
        <div id="exercises"></div>
        <script src="./script.js"></script>
    </body>
</html>

Unfortunately this script has a little bug: When the solution of an exercise is zero and you enter nothing, the answer of a user is seen as zero and get's accepted. Does anybody know a little workaround for that? I could assign a standard value to every textarea. But then the user would have to delete the standard value before he can write his answer. So thats not a good option.

\$\endgroup\$
4
\$\begingroup\$

Nice job with the game :) As far as fixing the bug you pointed out, you want to think about what two values you are comparing to determine if the answer is correct, and also how you are comparing them.

The value for textarea.solution will always be a number because that's all you ever assign to it. Getting the value of any textarea, on the other hand, will always return a string. If you use == (equality operator) to compare two values of different types, like a number and a string, Javascript will use type coercion to try to make sense of things. You can read the documentation here for some excellent examples of how this works.

This is a handy feature, but as you see, it can also be problematic. When the answer is something like '42', this gets converted to 42 before it's compared to the correct solution. But when the textarea is empty, textarea.value returns '' which gets converted to 0. 0 equals 0, so the answer is marked correct.

How do we fix this?

One way is to use strict equality (===). Strict equality, or identity, does not do any type coercion, unlike ==. That means '42' === 42 is false, while '42' == 42 is true.

We can use strict equality in this case, but of course we'll be creating another problem because now we'll be comparing strings to numbers. So, we want to make use of something like Number.parseInt(). While parseInt also converts strings to numbers, it will convert '' to NaN, so any blank answers will result in a comparison of Nan === 0, which will be false.

There's a place and time for using == (and !=), but it's generally good practice to utilize === (and !==) for comparisons instead. This does usually mean you have to be conscious of the types of the variables you're comparing, and may have to write a little additional code to convert one type into another. But the plus side is you remain fully in control of how that conversion happens, which helps avoid bugs like this one.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.