How can I make a simple mind game, that includes addition, multiplications

hello,

I would like to create a simple mind game, that includes addition, multiplications, times and divisions.
in this game i like users to answer questions by direct input and at the end of the game, have an update of their performance.
In this game i also like to alert users of wrong answers and display play time and speed.

could you please advise me how i can code this. i am new to making games and is excited to learn how to build games.

I don’t know a whole lot when it comes to game production, but I am thinking you would be better off making this using something other than jQuery, my guess would be Flash maybe? I’m sure it can be done in java, etc, and it has been, but from seeing games in the past, Flash seems to be the most effective.

One option would be to go the Desktop Platform. Such as Java (already mentioned), or you can go the .NET (Windows Forms) route to make your game. It would be much easier for it not to be a web application, if that is possible.

Here’s how I might code something like this:


Question: 10 / 10

What is 8 minus 3?

[5             ] [Answer]

You got 8 questions right.
You played for 28 seconds, and took an average of 2.8 seconds to answer each question.


<html>
<head>
</head>
<body>
<form id="game">
    <p>Question: <span id="questionnumber"></p>
    <p>What is <span id="first"></span> <span id="operator"></span> <span id="second"></span>?</p>
    <p><input name="answer" autocomplete="off"></label> <input type="submit" name="submit" value="answer"></p>
</form>
<script src="script.js"></script>
</body>
</html>


window.questions = {
    history: [],
    init: function (form) {
        this.minValue = 1;
        this.maxValue = 20;
        this.totalQuestions = 10;
        this.startTime = new Date();
        form.questions = this;
        form.onsubmit = this.ask;
        form.questions.show(form);
    },
    get: function () {
        var question = {},
            operatorType = Math.floor(Math.random() * 4);
        do {
            question.first = Math.floor(Math.random() * 12) + 1;
            question.second = Math.floor(Math.random() * 12) + 1;
            switch (operatorType) {
            case 0:
                question.operator = 'plus';
                question.answer = question.first + question.second;
                break;
            case 1:
                question.operator = 'minus';
                question.answer = question.first - question.second;
                break;
            case 2:
                question.operator = 'times';
                question.answer = question.first * question.second;
                break;
            case 3:
                question.operator = 'divided by';
                question.answer = (question.first / question.second * 100) / 100;
                break;
            default:
                question.operator = '';
                question.answer = '';
            }
        } while (!this.valid(question));
        return question;
    },
    valid: function (question) {
        var isValid = (question.answer === Math.floor(question.answer)
            && question.answer >= this.minValue
            && question.answer <= this.maxValue);
        if (isValid && question.operator === 'divided by') {
            isValid === (question.first > 1 && question.second > 1);
        }
        return isValid;
    },
    ask: function (evt) {
        var form = this,
            that = form.questions;
        if (!form.elements.answer.value) {
            return false;
        }
        that.answer(form);
        if (that.history.length < that.totalQuestions) {
            that.show(form);
        } else {
            that.endTime = new Date();
            that.summary();
        }
        return false;
    },
    show: function (form) {
        var question = this.get();
        this.history.push(question);
        document.getElementById('questionnumber').innerHTML = this.history.length + ' / ' + this.totalQuestions;
        document.getElementById('first').innerHTML = question.first;
        document.getElementById('operator').innerHTML = question.operator;
        document.getElementById('second').innerHTML = question.second;
        form.elements.answer.value = '';
        form.elements.answer.focus();
    },
    answer: function (form) {
        var question = this.history[this.history.length - 1],
            answer = question.answer;
        question.guess = form.elements.answer.value;
        question.result = true;
        if (Number(question.guess) !== answer) {
            question.result = false;
            alert(question.guess + ' is not the right answer.\
\
' + question.first + ' ' + question.operator + ' ' + question.second + ' is ' + question.answer);
        }
    },
    summary: function () {
        var i,
            correct = 0,
            playtime = Math.floor((this.endTime - this.startTime) / 1000),
            average = Math.floor(playtime / this.totalQuestions * 10) / 10,
            summary = document.createDocumentFragment();
        for (i = 0; i < this.history.length; i += 1) {
            correct += (this.history[i].result ? 1 : 0);
        }
        summary.appendChild(document.createTextNode('You got ' + correct + ' questions right.'));
        summary.appendChild(document.createElement('br'));
        summary.appendChild(document.createTextNode('You played for ' + playtime + ' seconds, and took an average of ' + average + ' seconds to answer each question.'));
        document.body.appendChild(summary);
    }
};
window.questions.init(document.getElementById('game'));

Thank you very much!

could you please also advice how i can perform the following actions?

(1) after the user’s summary, can i redirect or alert the user to start a new round without having to refresh the webpage?
(2) could i also allow the user to either re-start the same level or move to difficult level or to quit?
(3) also, for advanced level can i allow users to select their (a) type (times, plus, minus or divide), (b) number of questions and (3) time taken to complete it?

You want me to create the code for you for doing that too?

I am using this exercise (my main goal is) to develop a better understanding of javascripts, hence, if possible, could you please list the kind of tags that i should be using.

Many thanks,

Yes you can, by using a button that would clear the history and then init the game again.

Yes you can, by adjusting minValue and maxValue, and making some level-based changes to the function called valid.

Yes you can. The type of operations is currently picked at random, but a small update would allow you to provide a list of allowed operations, from which one is picked, the totalQuestions variable stores the number of questions, and the start time is recorded, so you can use a setInterval event to compare the elapased time against a desired amount of time for completion.

Just wanted to say THANK YOU for your very useful code and advise!

I am trying to place two sets of form on the same page using different levels. but only the first set of form is working the other ones are not correctly linking, could you please advise what i need to change so that each form is linked to the correct javascript file?

<body>

<form id=“game”>
<p>Level 1</p>
<p>Question: <span id=“questionnumber”></p>
<p>What is <span id=“first”></span> <span id=“operator”></span> <span id=“second”></span>?</p>
<p><input name=“answer” autocomplete=“off”></label> <input type=“submit” name=“submit” value=“answer”></p>
</form>
<script src=“script.js”></script>

<div>
<form id=“gameLevel2”>
<p>Level 2</p>
<p>Question: <span id=“questionnumber”></p>
<p>What is <span id=“first”></span> <span id=“operator”></span> <span id=“second”></span>?</p>
<p><input name=“answer” autocomplete=“off”></label> <input type=“submit” name=“submit” value=“answer”></p>
</form>
<script src=“scriptLevel2.js”></script>
<div>

<div>
<form id=“gameLevel3”>
<p>Level 2</p>
<p>Question: <span id=“questionnumber”></p>
<p>What is <span id=“first”></span> <span id=“operator”></span> <span id=“second”></span>?</p>
<p><input name=“answer” autocomplete=“off”></label> <input type=“submit” name=“submit” value=“answer”></p>
</form>

<script src=“scriptLevel3.js”></script>
</div>

</body>

I’m not a Javascript pro (I’m actuallly learning more of it now as we speak via lessons), but I’d do like…if(document.getElementById(“gameLevel1”)){} and use elseifs

Inside the brackets, do whatever code you want. I think using case: could also work here? I think that’s a more optimized version of it?

You should only need the one script, which can be customized for each form.

By changing the id attributes inside of the form to be class attributes instead, you can replace the document.getElementById lines inside of the show function to use form.querySelector instead.

That way when you init the game for each form, the script will be able to easily find the parts that it needs to interact with.

thank you!
do i also need to convert the linked javascript codes to embedded, using the <style type:“text/javascript”>…</style>?

at the moment my codes are changed to the following:

<form>
<p>Level 1</p>
<p>Question: <span class=“questionnumber”></p>
<p>What is <span class=“first”></span> <span class=“operator”></span> <span class=“second”></span>?</p>
<p><input name=“answer” autocomplete=“off”></label> <input type=“submit” name=“submit” value=“answer”></p>
</form>
<script src=“script.js”></script>

show: function (form) {
var question = this.get();
this.history.push(question);
document.queryselector (‘questionnumber’).innerHTML = this.history.length + ’ / ’ + this.totalQuestions;
document.queryselector(‘first’).innerHTML = question.first;
document.queryselector(‘operator’).innerHTML = question.operator;
document.queryselector
(‘second’).innerHTML = question.second;
form.elements.answer.value = ‘’;
form.elements.answer.focus();
},

Don’t remove the id attribute on the form tag itself. That’s what is used to tell the script which form to use.
Query selectors also use the same syntax that is used with CSS selectors, such as ‘.first’

OK - i now understand that i need to link questionnumber, first, operator and second to its appropeiate form, but don’t understand how to repeat the entire jave code three times, in the same file, using different rules? and, how to find the correct way to separately identity them?

how can i identify the correct place to call the id, e.g. 'games? For example, i have tried putting the id (‘games’) in the following lines but i got syntax error.

… init: function (form.game)
… get: function (games)

<form id=“game”>
<p>Level 1</p>
<p>Question: <span class=“questionnumber”></p>
<p>What is <span class=“first”></span> <span class=“operator”></span> <span class=“second”></span>?</p>
<p><input name=“answer” autocomplete=“off”></label> <input type=“submit” name=“submit” value=“answer”></p>
</form>
<script src=“script.js”></script>

in fact, i have the same problem when trying to link other javascripts to my html document, such as,

<script type=“text/javascript”>
var c=0;
var t;
var timer_is_on=0;

function timedCount()
{
document.getElementById(‘txt’).value=c;
c=c+1;
t=setTimeout(“timedCount()”,1000);
}

function doTimer()
{
if (!timer_is_on)
{
timer_is_on=1;
timedCount();
}
}
</script>
</head>

<body>
<form>
<input type=“button” value=“Start count!” onClick=“doTimer()”>
<input type=“text” id=“txt”>
</form>
</body>

As a second question, could you please suggest a better way to display the following code?

	if (Number(question.guess) == answer) {
        question.result = true;
        alert(' Well done!!! ' + question.guess +  ' is the right answer.\


’ );
}

with this code i can inform users of their correct answer - however, ideally it would be better to display this message as a label (read only message) on the html page, rather than forcing the user to click ok, for every correct answer.

Don’t repeat yourself is a fundamental maxim of programming. When you’re tempted to repeat yourself, you’re most certainly doing things wrong.

Don’t repeat the entire code three times!

In this case, you can supply a replacement for parts that require customisation:


init: function (form[color="green"], config[/color]) {
    [color="green"]var prop;[/color]
    this.minValue = 1;
    this.maxValue = 20;
    this.totalQuestions = 20;
    this.startTime = new Date();
    form.questions = this;
    form.onsubmit = this.ask;
    form.questions.show(form);

    [color="green"]for (prop in config) {
        if (config.hasOwnProperty(prop)) {
            this[prop] = config[prop];
        }
    }[/color]
},

Now you can supply different values when using init to set things up.


window.questions.init(document.getElementById('game2'), {
    minValue: 7,
    maxValue: 50
});

And yes, you can even supply replacements for function methods too, for example with the valid function:


window.questions.init(document.getElementById('game2'), {
    minValue: 7,
    maxValue: 50,
    valid: function (question) {
        ...
    }
});

As in the above samples of code.

The script file has the code that doesn’t change:


window.questions = {
    ...
};

And elsewhere, commonly at the end of the page just before the </body> tag, you have the code that you want to customize:


window.questions.init(document.getElementById('game2'), {
    minValue: 7,
    maxValue: 50
});

Place a response section in the form, such as:


<div class="response"></div>

Then use that response section when giving the message instead:


form.querySelector('.response').innerHTML = '<p>question.guess + ' is not the right answer.</p><p>' + question.first + ' ' + question.operator + ' ' + question.second + ' is ' + question.answer) + '</p>';

And lastly, clear it when someone tries again:


ask: function (evt) {
    var form = this,
        that = form.questions;
    [color="green"]form.querySelector('.response').innerHTML = '';[/color]
    ...
}

I am not able to make the form connect correctly. To my understanding, I need to perform the following steps;

Step 1 – replace document.getElementById With document.queryselector

Step 2 – inside the form, replace ids with class but keep the form id i.e., so that each the form can connect with its related script,

<form id=“game”>
<p>Question: <span class=“questionnumber”></p>
<p>What is <span class=“first”></span> <span class=“operator”></span> <span class=“second”></span>?</p>
<p><input name=“answer” autocomplete=“off”></label> <input type=“submit” name=“submit” value=“answer”></p>
</form>

Step 3 - replace init: function (form) {…},
with init: function (form, config) {…},

step 4 – insert, window.questions.init(document.getElementById(‘gamelevel2’), {
minValue: 7,
maxValue: 50,
valid: function (question) {

}
});

At the bottom of script. Thus, I would also need to have a third

window.questions.init(document.getElementById(‘gamelevel3’), {
minValue: 13,
maxValue: 100,
valid: function (question) {

}
});

Is this correct – did I understand the code structure correctly, please advise?