Number-Guessing Game

The text below is a bit verbose, but don't get afraid! Today it is up to me to explain and up to you to do something beautiful! Read the intro part, until "implementation hints". Then play demo by the link and try to figure out how to create the game on your own. If it goes too hard, proceed with implementation hints below.

Game Description and Demo

This is probably the most popular first game for programmers and we won't break tradition. It is important because it includes both loops and conditions - and actually is built upon infamous yet simple "Binary Search" algorithm.

You can first play it verbally (or using a pencil and paper) with your friends or family members for practice. It generally starts with proposal:

Think of the number from 1 to 1000 - and I'll guess it in only 10 questions!

For people unfamiliar with the approach this may sound impressive at first. Really - one of 1000 numbers in just 10 attempts! But let's see how the game progress.

At every attempt the guesser should split the remaining range of numbers in two, and ask which of the halves the secret number falls into. This allows narrowing the range at every step, let's have a look.

1-st attempt, the range is 1 .. 1000. Guesser splits it in half and here are two sub-ranges 1 .. 500 and 501 .. 1000. The question comes "Is the number above 500?" (in other words, above the largest value in the smaller subrange). Suppose, the answer is yes.

2-st attempt, the range is now 501 .. 1000. Split gives us 501 .. 750 and 751 .. 1000 subranges. The question "Is the number above 750?" Suppose, now the answer is no.

3-rd attempt, the range is 501 .. 750. Subranges are 501 .. 625 and 626 .. 750. The question "Is the number above 625, and suppose it is yes again.

4-th attempt, we split 626 .. 750 into two slightly unequal subranges 626 .. 687 and 688 .. 750 - and the game continues in the same manner until after 10 attempts guesser gets the subrange of the size 1 so no more questions are needed - this is the secret number!

Try this demonstration to get better understanding of the process. It intentionally divides the range into somewhat unequal subranges so sometimes it may take more than 10 attempts and sometimes less. In other words don't haste to peek into it's code since it is a bit different :) When you feel yourself familiar, try to create such a game.

Implementation hints

You start with initializing graphics and clearing the screen. It is worth to print few words like "think of the secret number in such and such range". Then it would be good wait until user taps or clicks. For this just check click coordinates in a loop until they are non-negative.

while graph.click() < 0 then
    graph.delay(100)
end

We add a delay inside the loop to allow browser to do any other work it wants while we are waiting. We don't want it stuck (or frozen) performing maximum possible amount of checks per second. This doesn't make sense. Also note that we compare result of a function returning two variables (x, y) with single value. In such cases only first variable is used which is enough.

Now set two variables to describe upper and lower bounds of the range, e.g. high = 1000 and low = 1.

Next put the attempts loop itself. It could be both while checking if range still has more than 1 value - or for loop counting up to 10 attempts.

Inside this main loop we now need to define some "middle point" to split the range. If you take mean (average) value of both ends of the range, it would be almost all right, just let's look how it works on smaller example:

range 1 .. 10,  mean is (1 + 10) / 2 = 5.5
range 6 .. 10, mean is (6 + 10) / 2 = 8

We don't want to confuse user with fractional parts, so let's use "integer division" which rounds down to whole integer. It is described with double slash operator (//). Now how we pick the subranges? Let's agree to include the middle value into the lower range - otherwise they may be too unequal.

range 1 .. 10, mean is (1+10)//2 = 5     subranges 1..5 and 6..10
range 6 .. 10, mean is (6+10)//2 = 8     subranges 6..8 and 9..10

Ok, now print the question like "Is your number above (middle value)?" and we need to get user's reactions. Print "YES" in the upper part of the screen and "NO" in the lower. Now let's wait until user clicks somewhere and decide, whether it is upper or lower part. We again need a small loop waiting for click, just this time we need to preserve coordinates, so checking the click function immediately in the loop condition is not a good option. One of the options looks like this:

After this loop ends, which means user reacted, examine Y variable to see if it is more or less than graph.h (height of the canvas). If you are perfectionist, add some "insensitivity zone" in the middle, but it's better to do it as improvement when everything else is working.

Well, depending on the user's reaction change either upper or lower bound of the range (note if you go into upper part, lower bound should be 1 above the middle value).

After the main loop ends, print the higher or lower bound (they should be equal) as an answer.

Don't forget to erase necessary parts of the screen after you printed something (use rect of suitablse size).

As a bonus, you may offer the user to play again after the end, waiting for new tap here.