BWD Chapter 07: The game becomes more fun

2004-11-08 18:55 - Beginners Web Development

Chapter 07
The game becomes more fun

It was fun to make a game, if a very simple one, right? Perhaps it will be more fun to make a bigger game! Almost everyone has played that same guessing game, but where the number goes from 1 to 100, with 10 chances to guess it, and a remark of higher or lower. Let's try to program that game.

The first thing we need is a better definition of how the game really works. Let's list the rules:

  1. The game involves two players, the master and the guesser.
  2. The master begins the game by picking a secret number between one and one hundred, inclusive.
  3. The guesser then receives up to ten turns to attempt to guess the secret number. After each guess, the master announces one of three possible outcomes:
    1. Right answer, guesser wins
    2. Wrong answer, too low
    3. Wrong answer, too high
  4. If the right answer is given the guesser wins and the game ends. If the wrong answer is given the guesser receives his hint and play continues on the next turn.
  5. If play reaches the eleventh turn, the guesser has used up his ten turns and has lost.

Wow, the simple childs game is actually quite involved, with quite a few strict procedures to follow in just the right order. Think back a few chapters, the secret to programming well is divide and conquer. We have divided our game into a logical set of steps. It is not split fine enough to go right into a computrer program yet, but now we have a number of small easy to solve problems on our hands. No sweat. Let's discuss them in order.

Number 1 is a simple declaration rather than a process we need to program. Number two though definetly requires our attention. Pick a number. Last chapter we used a constant number. Perhaps fun once, but once the secret is out there goes our fun. How about we choose a different number each time we run the game?

Sounds simple, but this actually requires a good few steps. We need to choose a "random" number each time, something different. To put it simply, the computer cannot do this. A computer can only follow exact instructions, it cannot simply conjure a number from thin air. Modern computers, though, can produce a very close simulation. We can improve the randomness with a simple seed. By providing th computer with a number to use as a starting point that itself is random and unpredictable, the generated numbers can be more unique.

We cannot get truly random numbers, but what we really want is a number that is different each time. This is usually the case, and there is a special statement to accomplish it. The RANDOMIZE statement gives the computer a seed, and the RANDOMIZE TIMER statement uses the clock (timer) to get the seed. Of course the time changes with each run of the program, so wala mostly random numbers!

So now we can set up the random numer generator well. Great, our game will be fun! So how do we generate random numbers? It's both simple and complex. Simple because it's just one small command: RND. Complex because RND doesn't quite do what we want it to. The command works just like a variable, we use it where we need its value.

The RND command does return a random number, but it is a random fraction from 0 to 1. This is good in the long haul but in the beginning we need to learn how to deal with it. The benefit is a little math can turn 0 to 1 into any range we like, once we learn how. Basically we multiply the number by how big we want it to be and possibly add a bit. Let's look at a formula:

num = INT(RND * (max - min)) + min

This is the basic formula to get a random whole number in BASIC. Look first at the bit inside parenthesis. The RND command gives us our fraction. We then multiply by the number that is the biggest we want minus the smallest we want. In our game this is 100-1 or 99. What we have now is a number from 0 to 1 times 99. The smallest it can be is zero, the biggest 99. But it can be any fraction in between. We apply a function, called INT. Functions always have a name, and a set of arguments in parenthesis. The parenthesis always follow the function name with no spaces in between. The arguments go inside the parenthesis. More than one argument is separated with commas. Some functions take only one, or no arguments at all.

The INT function takes one argument, any number. It returns that number, but with any fraction part removed. It does not round, it truncates, simply removing the decimal point and everything after. We have passed an expression in to INT, one that gives us almost the random number we want. Once we take just the integer part of our number between 0 and 99, we add one and have our range of 1-100.

Now to assemble all these pieces into one, let's show the code to choose the random number for our game. Can you figure it out before revealing it?

RANDOMIZE TIMER secret = INT(RND * 99) + 1

The first step is now complete, each time we run the program, a different secret number will be selected. Now for the actual game, where the guesser takes his ten turns, and gets his responses. If you look back at the program we wrote in the last chapter, you can see the basic structure for one step. Ask the player for his guess and compare it to the secret number. But that program only asks once, how do we give the guesser his ten chances? The answer is loops.

Loops are special commands that run in a loop, from beginning to end then starting over at the beginning again. Much like the famous shampoo intructions, "lather, rinse, repeat." As an aside there is also a common joke about the computer programmer who died in his shower, because he followed the instructions. Why? Every time he got done rinsing, the next step was repeat, so he did and eventually starved.

This joke pokes fun at the very exact nature of computer programmers. We have to think exactly to convince a machine to do what we want. It also demonstrates a very important programming concept: the infinite loop. With loop commands, a program can be incorrectly set into a loop that has no ending. This is always a big problem and must be avoided. Every loop structure contains a part that lays out how and when the loop stops looping, and this part must be set up carefully.

The simplest loop is the WHILE loop ans an example WHILE loop is shown below.

WHILE condition
  .
  .
  .
WEND

In BASIC the WHILE statement starts the loop and the WEND finishes it, the While END. The WHILE statement is given a condition. When this condition is true, the loop runs and everything between the WHILE and WEND statements runs. When the WEND is reached, control jumps up to the matching WHILE. This behavior continues, hence the loop name. Once the WHILE statement runs and the condition is false, control jumps to after the matching WEND.

So clearly, the condition a WHILE is based on should contain a variable whose value will change to eventually terminate the loop. To set up the condition we will almost always use a conditional operator to compare a variable to another value. Here is an example of an entire functional WHILE loop. You should type this into BASIC by hand and run it.

counter = 1
WHILE (counter < 10)
  PRINT "This is loop run"; counter
  counter = counter + 1
WEND

Isn't that fancy? Plus, surprise, we now know how to complete the game we described at the beginning of the chapter! Look over the examples in this chapter and the last, and be sure you understand what each line does. Go back and re read the chapters describing the concepts you have trouble with, if any. Then, read carefully through the definition of the game at the top of this chapter. Hopefully you will be able to complete it. One of many possible solutions is shown below. Be sure to go over this answer, as it involves some big ideas that we covered lightly or not at all which you might or might not figure out on your own yet. Carefully go over each line and be sure to figure out what each one does, and how, and why.

RANDOMIZE TIMER secret = INT(RND * 99) + 1 turn = 1 PRINT "I have chosen a secret number from 1 to 100." PRINT "Can you guess it in ten turns or less?" PRINT "" WHILE (turn < 11) PRINT "Turn"; turn INPUT "What is your guess? ", guess IF (secret = guess) THEN PRINT "That's it, you guessed my secret number!" PRINT "You win, good job!" turn = 99 ELSEIF (guess < secret) THEN PRINT "Too low, guess again." ELSEIF (guess > secret) THEN PRINT "Too high, guess again." END IF turn = turn + 1 IF (turn = 11) THEN PRINT "You used up all your turns. You lose." END IF WEND

Wasn't that a lot of fun? Next chapter we will learn more about loops.

Comments:

No comments!

Post a comment:

Username
Password
  If you do not have an account to log in to yet, register your own account. You will not enter any personal info and need not supply an email address.
Subject:
Comment:

You may use Markdown syntax in the comment, but no HTML. Hints:

If you are attempting to contact me, ask me a question, etc, please send me a message through the contact form rather than posting a comment here. Thank you. (If you post a comment anyway when it should be a message to me, I'll probably just delete your comment. I don't like clutter.)