Beginning Programming 3 - Section One

by Brad Moore

Answering the Challenge

The Challenge

As you may recall, we spent a great deal of part two discussing the process of programming, or more specifically, the process of thinking and analyzing a problem so that we can create a program. We discussed both pseudo-code and flow charting as useful tools in conceptualizing a problem and solution.

I also left you with a challenge. Examine a flow chart and write the code that accomplishes what it describes. The flow chart was for a simple computer based implementation of the "Magic 8 Ball", only we had just six possible answers - I suppose you call this a "Magic Six Ball". That flow chart appears again in figure 1 below.

I of course can't tell whether you actually tried to write a program that followed the flow chart, but I hope you at least tried. Learning to programming involves a lot more than just reading a few articles or a book. It involves experimenting. Putting some code up and then running it to see what it will do. Changing it around and trying it again. How did it change? Did it change the way you thought it would?

No one can do that for you. If you want to become a good programmer who can think the way the computer needs you to think and write computer programs that do what you want them to so, then you will need to get your hands dirty along the way in the learning process. I had to when I was learning to program, even Bill Gates had to.

So before you go on with the article, and read about my solution to the problem described by the flow chart, you need to try to create a program that represents your solution.

(FIGURE 1)

Where to begin...

The flow chart is not utterly confusing (I have seen much worse), but it might appear intimidating. So where do we start? Well that is easy - we start at the start, the block named start that is.

There is no code associated with the start block, but this is the perfect place to put some comments about our program. I mentioned it before, and I will say it again (this is one of my soapbox topics) - every program needs some basic stuff in the header comments of the program.

This is where we put the name of the program, the name of the author, maybe an email address, the version of Liberty Basic it is written for and finally the copyright and other legal terms (keep those breif). For my Magic Eight Ball program I included the following:

'The Magic 6 ball - version 1
'Written by Joshua Moore and Brad Moore'
'Copyright 2002, all rights reserved
'written for LB3.x
'You are free to incorporate any portion of this code
'into your own programs without notification or credit
'to the authors.  Please do not distribute as-is.

Next the flow chart indicates we are to ask for and get the users name. With thier name we can personalize the questions later on. You should recognize this as a place to use the INPUT statement. Here is how my son and I did it in our program:

print "Hello - Ready to play Magic 6 Ball."

[getPlayer]
print "Enter your name please";
input name$
print ""

What happens if they just press the enter key when prompted for their name? Then the variable name$ will hold a null value. (A null value is an empty or blank value assigned to a string. If it were a numeric variable it would be a zero.) Since we are going to use the value stored in name$ later, lets test it to insure it actually contains a value. If it does not, then we will cause the program to go back to the label [getPlayer].

This feature is called Error Checking. Error checking is an important part of programming. It is the anticipation of bad data that the unknown user can and will enter into your program, and the correction of that bad entry. Good error checking separates mediocre programs from superior programs. As you probably realized, the error checking is not shown in the flow chart, but is always a good idea to build into any program where user entry is possible.

if name$ = "" then 
  print "You did not enter anything for your name!"
  print "Try agian...";
  goto [getPlayer]
end if

Did you notice the semi-colon after the line: "print "Try again...";"? Did you remember that this causes the next thing printed to the screen to follow this printed line immediately on the same line.

The thing the flow chart tells us is that we need to display the rules. This is a simple case of putting text on the screen. Here is what we did. Notice the statements that print "" to the screen. These statements simply put a blank line on the screen. It is useful in creating white space in our output, which breaks up the messages into blocks that are more easily read.

[instructions]
Print ""
print "I am the Magic 6 ball - I can tell the future..."
print "Ask me a yes or no question and I will tell the answer!"
print ""

Now that we have introduced the game and the rules briefly, lets get on with the business of asking for the user's question. This is done using the INPUT statement.

[loop]
print name$; " What do you wish to ask the Magic 6 ball,"
print "(please make it a 'yes' or 'no' question)";
input question$
print ""

if question$ = "" then 
  print "I am sorry, I did not hear you."
  print "  Perhaps you should type a little louder.";
  goto [loop]
end if

Notice that we have added some error checking again to the question input cycle. If the user did not type anything in then the program will scold them and ask for input again. Traditional and basic error checking.

Now we have the user's name out of the way, and we have the users question. It is time to decide what the Magic 6 ball will answer. We will again turn to our old friend the random function. It is a function because it returns a value. Here is what the Liberty Basic Help file says about the function called RND (random number generator):

RND(number)

Description:

This function returns a random number between 0 and 1. This can be useful in writing games and some simulations. In MBASIC it makes a difference what the value of parameter number is, but in Liberty BASIC, it makes no difference. The function will always return an arbitrary number between 0 and 1.

We will need to scale the result of the RND function to fit our needs, since we require a number that is bigger than 1. In fact our desired range of values is from 1 to six, inclusive. To scale the result returned by the RND function, we simply multiply it by the largest value we wish to obtain. As you will recall from the first part of this series where we first introduced the RND function, after scaling the result of the function, we still have a decimal and fractional number. To strip off the fraction we use another mathematic function called INT. INT returns only the integer portion of a numeric value. The final step is to add one to the solution to shift the result from 0 through 5 up to 1 through 6. The equation looks like this:

DesiredValue = INT(RND(0) * 6) + 1

Our next step then, according to the flow chart is to select a random value between 1 and 6 (inclusive). Based on our discussion above, the code that accomplishes this should be no surprise.

'get a random number between 1 and 6
number = int(rnd(1)*6) + 1

Now as we study the flow chart we will see that we will be making several comparisons and displaying certain results depending on the outcome of those comparisons. The flow chart shows each of these comparisons (or decision points) as diamonds, and the text says something like RND = 1 or RND = 2, etc. These each represent a block IF-THEN-END IF statement. Each is formatted almost identically. They say if number (our random value) is equal to a specific value, then perform the following steps - in our case, print something to the screen and go to a place to gather more user input.

Below is five of the IF-THEN-END IF statements. One for each of the possible values that the random function could have returned - except six. There is no evaluation for the sixth condition. Do you know why? We will look at that in a moment, but first the five IF-THEN-END IF statements:

if number = 1 then
   print "MAYBE..."
   goto [playagain]
end if

if number = 2 then
   print "NO! - Never - Don't ask again!"
   goto [playagain]
end if

if number = 3 then
   print "Its not clear now."
   goto [playagain]
end if

if number = 4 then
   print "Yes"
   goto [playagain]
end if

if number = 5 then
   print "Probably not..."
   goto [playagain]
end if

So, why isn't there a sixth IF-THEN-END IF statement? Well there could have been. It would not have ruined anything, but it was not necessary. If you look closely at each of the previous five block IF's you will notice that the program is directed to GOTO a label called [playagain] after the answer has been printed. By the time the program has evaluated the five IF-THEN-END IF statements, there it has captured all the 1's, 2's, 3's, 4's and 5's that were generated. There are no other values that number could be equal to other than six! So why test for what you certainly have? You know all values by the end of the fifth block IF must be a six.

So the last statement is just a simple print statement to satisfy the last case, the sixth case:

print "You can count on it!"

So that brings us to the last major block of the flow chart. Another decision point where we ask the user if they want to pay again. This is accomplished much the same way all the other interaction has been accomplished - via PRINT statements and the INPUT statement. After the user input is received, we test it using an IF-THEN-END IF statement to see if the user typed the correct response to play again. I rarely test for empty string in this type of question, assuming that if they have entered anything but the affirmative response to play again, that they intend to quit. Here is the code that wraps up the game:

[playagain]
  'ask if they want to play again
  print ""
  print "Do you want to play again - (y = yes)";
  input answer$
  if answer$ = "y" or answer$ = "Y" then
     cls
     goto [loop]
  end if

print "Thanks for playing"

The complete program listing is located in appendix A.