Guessing Game

A typical question asked in "History of JavaScript" classes where the teacher mistakenly believes they are teaching programming.


Have the computer guess an number between one and ten and then give the person three tries to guess the number the computer selected.

Now this is a reasonably good choice of question for learning how to attach event processing to a form and to validate fields within the form. This question is not often asked to test that part of JavaScript though, it is more commonly asked as an early question for testing loops and if statements.

Historical Answer:

var guess = Math.floor(Math.random()*10)+1;
var answer =
Number(prompt("Guess what number I'm thinking of (It's between 1 & 10)"));
var cnt = 3;
while (cnt > 1 && answer != guess) {
alert('Wrong. Please try again');
answer = Number(prompt("Guess what number I'm thinking of (It's between 1 & 10)"));
if (answer == guess) alert('Congratulations. Your guess was correct');
else alert('Bad lock. That was your last guess and you still got it wrong');

There is exactly one line of code in this historical answer that you should actually be using and that's the one making use of Math methods to set the number that the computer is asking you to guess in the first place.

The prompt() and alert() functions did need to be used for interacting with the user back in the days of Netscape 2 and 3 and Internet Explorer 3 but were replaced with better ways of interacting with the web page in Netscape 4 and IE4 and with a standard way of interacting in more modern browsers. At that time prompt() and alert() were re-purposed for debugging JavaScript and had extra checkboxes added to them in various browsers to make it easier to use them for that purpose by allowing the dialogs or JavaScript itself to be easily turned off.

While I have used the correct Number() function for converting the input strings to numbers in the above code you may find that the teacher expects parseInt() to be used for this instead. While parseInt has a side effect of converting a string to a number that is actually a misuse of that function. In fact there are values that parseInt will reat as a number that you probably wouldn't want it to accept (such as '0xa').

This code also uses != which is another piece of JavaScript best avoided as it can cause unexpected problems.

JavaScript Answer:

(function() {
"use strict";
var cnt, guess, answer, clear;
guess = Math.floor(Math.random()*10)+1;
cnt = 3;
answer = function() {
var a = +document.getElementById('g').value;
if (cnt > 1 && a !== guess) {
document.getElementById('m').innerHTML = 'Wrong. Please try again';
document.getElementById('g').value = '';
} else document.getElementById('game').innerHTML = (a === guess) ?
'Congratulations. Your guess was correct':
'Bad lock. That was your last guess and you still got it wrong';
clear = function() {
document.getElementById('m').innerHTML = '';
document.getElementById('game').innerHTML = '<form><fieldset><legend>' +
'Guess what number I\'m thinking of (It\'s between 1 & 10)</legend>' +
'<input type="text" id="g"/><input type="button" id="s" value="guess"/>' +
'<span id="m"></span></fieldset></form>';
document.getElementById('s').addEventListener('click', answer, false );
document.getElementById('g').addEventListener('focus', clear, false );

In this particular variant of a proper JavaScript solution to the problem I have used the innerHTML method that all modern browsers support. This results in less code than would be required if standard DOM calls were used and allows us to concentrate more on the other differences between modern and historical solutions.

As with all modern JavaScript we wrap our code in an anonymous function to remove it from the global namespace. As we are looking at a JavaScript only solution the form is being added to the page from JavaScript so that anyone with JavaScript disabled does not see a non-functional form. If we were going to provide a server side solution instead then we could hard code the form in the HTML and attach the first event listener to the form and listen for the submit event instead of attaching it to the button. All modern browsers support event listeners now so we would only need to modify the way we attach the event processing if we need to support older versions of Internet Explorer that use jScript instead of JavaScript - such as IE8.

Instead of a loop, each guess runs as a completely separate event and so we can use an if statement instead of a while loop. We also use !== rather than != so as to correctly test for not equal.

Instead of using Number() to convert the strings to numbers this example uses a unary + which will always perform that exact same conversion but requires less typing.


This article written by Stephen Chapman, Felgall Pty Ltd.

go to top

FaceBook Follow
Twitter Follow