Classic Computer Magazine Archive ANTIC VOL. 3, NO. 4 / AUGUST 1984

LOGIC ACCORDING TO BOOLE

Use it to program more efficiently

By DONALD B. WILCOX

SYSNOPSIS
George Boole, the founder of modern logic, developed Boolean algebra during the mid-19th century.  Since then, extensive development of his original concepts, which use the symbolism of algebra in logic, has given Boolean algebra an extremely important role in computer science.

Boolean operations-those that yield true or false results-provide useful proramming shortcuts.  Use of Boolean operations can make your BASIC programs run faster and occupy less space in memory. operations also can be used to monitor joystick position, provide screen boundary limits, set flags, select values, and replace successive IF/THEN statements.

READING A JOYSTICK
A joystick can be placed in any one of nine positions, each of which returns a unique value to the BASIC program.  The following diagram represents these values.  For example, a joystick pushed forward and to the left returns a value of 10, while a neutral joystick returns 15.
  A BASIC routine similar to the one below is a common method of reading joystick motion.  In the following examples, S is the value returned by the joystick:

10 S=STICK(O):IF S=15 THEN 10
20 IF S=7 THEN X=X+l
30 IF S=ll THEN X=X-1
40 IF S=13 THEN Y=Y+l
50 IF S=14 THEN Y=Y-1
60 IF S=6 THEN X=X+1:Y=Y-1
70 IF S=5 THEN X=X+l:Y=Y+l
80 IF S=10 THEN X=X-1:Y=Y-1
90 IF S=9 THEN X=X-1:Y=Y+l

In this routine, X represents the horizontal position and Y the vertical position of the character or player on your screen.  If we take advantage of the joystick's numbering pattern, we can use Boolean operations to modify the BASIC code.
  All movements to the right involve joystick readings that are less than eight.  All movements to the left involve values that are greater than eight, but less than 13.  Even numbers denote upward motion, and any even number divided by two gives an integer (or whole number).  We check for even numbers by comparing the value of a number divided by two with the INTeger function value of the number divided by two.
Joystick position values
Compare INT(S/2) with S/2.  The result of the expression: (S/2 - INT(S/2)) is zero if S is even, and greater than zero if S is odd.  If you want to see how the two values compare, type in the following program line and RUN it.  Type any number and [RETURN] at the input prompt (?), and the program will print out the two values.

0 INPUT S:?  INT(S/2),S/2: GOTO 0

Note that when the values of downward joystick movements are divided by four, the remainder is always one.  You can detect such downward motion with the following BASIC statement:

INT(S/4)*4=S-1

This statement is only true when the joystick has made a downward motion.  To see how these two values compare, type in the following sample program line and RUN it.  Type any number and [RETURN] at the input prompt (?), and the program will print out the two values.

0 INPUT S:?INT(S/4)*4, S-1:GOTO 0

We can summarize these modifications into a new BASIC routine:

10 S=STICK(0)-.IF S=15 THEN 10
20 IF S<8 THEN X=X+l            :REM JOYSTICK
                                PUSHED RIGHT
30 IF S>8 AND S<13 THEN X=X-1   :REM JOYSTICK
                                PUSHED LEFT
40 IF INT(S/2)=S/2 THEN Y=Y-1   :REM JOYSTICK
                                PUSHED FORWARD
50 IF INT(S/4)*4=S-1 THEN Y=Y+l : REM JOYSTICK
                                PULLED BACK

   BASIC assigns a value of one to an expression which is logically true.  A zero is assigned to logically false statements.  Consider the following statements:

10 A=5
20 X=(A=5)
30 PRINT X

Variable A has been assigned a value of 5. Variable x is assigned a value of either one or zero, depending on whether the expression within parentheses (A = 5) is true (1) or false (0).
   Remember that the " = " sign does not mean "equals" in BASIC.  Rather, it assigns the value of the expression on the right side of the statement to the variable named on the statement's left side.  In this routine, the expression on the right side of line 20 (A = 5) is a true (1) statement.  Therefore, variable X on the left side is assigned the value one.
   The "Greater Than," "Less Than" and "Not Equal To" symbols, as well as the "Greater Than or Equal To" and "Less Than or Equal To" symbols, can also be used in Boolean operations.
   Change the BASIC code as follows:

10 A=5
20 X=(A=2)
30 PRINT X

Variable X is assigned the value zero because the expression (A = 2) is false.  Variable A was assigned the value five in line 10. How does the computer recognize that line 10 is an assignment for A, and line 20 is a check on the truth or falsity of the expression in parentheses?  The format in line 20 is standard for this type of Boolean operation.  The variable on the left side of the statement is assigned the logical value (true (1) or false (0)) of the expression in parenthesis on the right side of the statement.
   These statements would monitor joystick movements to the right:

10 S=STICK(0):IF S=15 THEN 10
20 X=X+(S<8)

The value (S<8) in line 20 is either one or zero, depending on the position of the joystick.  If the joystick is pressed to the right (S = 5, 6 or 7; see Fig. 1), the value of (S<8) will be one; otherwise, it will be zero.  If (S<8) is a true statement, the value of X will be increased by one.  If (S<8) is false, X will not change.
   Let's rewrite our original BASIC routine using these additional Boolean techniques:

10 S=STICK(O):IF S=15 THEN 10
20 X=X+(S<8)-(S>8 AND S<13)
30 Y=Y+(INT(S/4)*4=S-l)-(INT(S/2)=S/2)

   Line 20 increments X if the value of S is less than eight (Joystick is pushed to the right), and decrements X if S is greater than eight, but less than 13 (Joystick is pushed to the left).  Similarly, line 30 decrements Y when S is equal to an even number (Joystick is pushed forward), and increments Y when S is divisible by four with a remainder of one (Joystick is pulled downward).
   Note that the BASIC routine remains at line 10 until the joystick is moved away from the center position.  Reassign S after each move in your program, because S will retain the value of the last move until it is reset to 15.  This is an additional purpose of line 10.

CHECKING BOUNDARIES
This brings us to a second situation: the handling of screen boundaries to prevent the cursor from going out of bounds.  First, we must determine the size, or grid coordinates of the screen.  These limits vary with the graphics mode chosen.  Graphics Mode 3 has 40 columns (numbered 0 to 39) and 20 rows.  Thus, if X represents the horizontal position of the cursor, X must be greater than or equal to zero and less than 39 for the cursor to remain in bounds.  If Y represents the cursor's vertical position, Y must be greater than or equal to zero and less than 19.
   Other graphics modes have different grid sizes.  See the inside back page of your BASIC Reference Manual for the grid limits of your screen.
   Let's begin with a simple example.  Consider the following BASIC routine, written for Graphics Mode 3, which prevents the cursor from moving off the right side of the screen:

10 S=STICK(0):IF S= 15 THEN 10
20 X= X+(S<8) * (X<39)

   If the joystick is pressed to the right, the Boolean expression (S<8) is true and is assigned a value of one.  If X, the horizontal position of a point on the screen, is less than 39, the value of (X<39) is true, and also is assigned a value of one.  In this situation, X is incremented by one, the product of the two Boolean values.  When X is greater than or equal to 39, the Boolean expression (X<39) is false, and is assigned a value of zero.
   Similarly, when S is greater than or equal to eight, the Boolean expression (S<8) is false, and also is assigned a value of zero.  Since X is incremented by the product of these two Boolean values, X will be left unchanged if either value is zero.  For example, if (S<8) is true and (X<39) is false, the computer evaluates line 20 as follows:

X=X+(l)*(0) [or]
X=X+0 [i.e. no change in X.]

We can apply the same logic to the truth or falsity of (S>8 and S< 13) * (X> 1) to prevent the cursor from moving off the left side of the screen.  Similarly, line 30 controls the screen's upper and lower boundaries as Y is changed.
   Not only can we rewrite our original joystick-controlled program to move a spot on the screen, but now we can also prevent the cursor from exceeding the screen's boundaries with the following routine:

10 S=STICK(0):IF S=15 THEN 10
20 X=X+(S<8) * (X<39)-(S>S AND S<13) * (X>0)
30 Y=Y+(INT(S/4)*4=S-1)*(Y<19)-(INT(S/2)=S/2)-
   (Y>0))

   Line 20 increments and decrements X, and keeps the cursor from moving off the right or left edges of the screen.  Line 30 increments and decrements Y, and keeps the cursor from moving past the screen's top or bottom edges.

SETTING FLAGS
Use a routine similar to this one to allow a user to print information from your program:

10 DIM A$(l)
20 PRINT "DO YOU WANT TO USE THE PRINTER?"
30 PRINT "ANSWER Y OR N"
40 INPUT A$
50 IF A$="Y" THEN PRINTER=1
60 IF A$="N" THEN PRINTER=0

   This program also can be written using a Boolean approach.  Simply change the lines shown below.  The program's other lines remain the same.

50 PRINTER=(A$="Y")
60 deleted

If the user's response is "Y," the value of PRINTER will be one.  If the response is "N," PRINTER will be equal to zero.  You can also use a Boolean approach to read the red joystick button:

10 BUTTON=(STRIG(0)=0)

   When the button is pressed, the variable BUTTON will have the value one; otherwise, it will have the value zero.

SELECTING A VALUE
We can use a series of IF/THEN statements to select the value of one variable based on the value of another.  This is illustrated in the following routine:

10 IF P=5 THEN X=1
20 IF P=ll THEN X=2
30 IF P=13 THEN X=7

   Note that these instructions can be compressed into one line using a Boolean approach:

10 X=(P=5) + 2*(P=ll) + 7*(P=13)

   If P = 5, the expression would be equal to: (1 + 2 * (0) + 7 * (0)), or one.
   If P = 11, the expression would be equal to: (O + 2 (1) + 7 * (0)), or two.
   If P = 13, the expression would be equal to: (O + 2 (0) + 7 * (1)), or seven.
   And if P were equal to any other value, the expression would be equal to: (O + 2 * (0) + 7 * (0)), or zero.

REPLACING IF/THEN STATEMENTS
We'll use the same approach to replace IF/THEN statements.  Begin with this code:

10 IF P=l THEN GOTO 100
20 IF P=3 THEN GOTO 200
30 IF P=7 THEN GOTO 300
40 IF P=ll THEN GOTO 400
50 IF P=13 THEN GOTO 500
60 IF P=17 THEN GOTO 600

   Compare this routine with the following routine using Boolean operations:

10 K=(P=1)+2*(P=3)+3*(P=7)+ 4*(P=ll)+5*(P=13)+6*(P=17)
20 ON K GOTO 100, 200, 300, 400, 500, 600

   For example, if P = 11, K would be equal to: (0) + 2 * (0)+ 3 * (0) + 4 * (1) + 5 * (0) + 6 * (0), or four.
   Line 20 would then branch to line 400.  Note that when K = 0, the computer ignores line 20 and drops to the next line.
   With practice, you'll discover many creative ways to use Boolean operators to enhance your own code. (You have to pay for these enhancements, though; the resulting code is much more difficult to debug.  If you're having difficulty, let the computer help you.  You can always print out intermediate results, try shorter statements and experiment. -ANTIC ED)

Donald R Wilcox is an Assistant Professor in the Accounting Information Systems Department at the University of Wisconsin (Milwaukee).  He's a member of the Milwaukee Atari Users' Group, and owns four Atari computers.  Donald is currently doing consulting work on a project that uses a single Atari 800 to monitor and control 30,000 remote devices