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.
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.
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:
graph.click
assiginig its result to X, Y
variablesAfter 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.