Classic Computer Magazine Archive Article from Compute! magazine

PROGRAMMING THE TI

C. Regena

Programming Without A
Math Background

"Computer literacy," a required class in many high schools and colleges, is often little more than a class in elementary programming. Programming, however, is really only a small part of computing. Equally odd is the fact that many of these computer literacy classes require courses in algebra, calculus, or some other form of advanced mathematics as a prerequisite. In what way would knowing the calculus help someone learn BASIC?
    Why are so many young people (often younger than 15) good programmers even if they've never taken algebra? Clearly, advanced mathematics has little to do with programming. Of course, you do need to know a little about numbers., You need to know how to count. In a BASIC program the lines are numbered, so you must know the order in which the lines will be executed. Nevertheless, if you think logically, you can even use NUM to automatically number your lines as you are typing and you won't even have to worry about the line numbers.
    If you like to program graphics, you should also learn something about basic coordinate geometry. That's just a mathematical term for using a grid. There are 24 rows and 32 columns on a TI-99/4A screen. If you want to place a character in a certain position, you have to tell the computer which row and column.
    You'll also encounter numbers in the form of codes. For example, each color on a TI is given a number from 1 to 16. In any CALL SCREEN or CALL COLOR statement where you need a color number, you can look on the color chart to see which number represents which color. There are also codes for color sets, sounds, and characters. But beyond that, the most basic knowledge of addition, subtraction, multiplication, and division will be all you'll need in most cases.

Using Numbers Efficiently
Some skill at recognizing number patterns will help make your programs more efficient. Remember, however, that as long as your program works, it is "correct." There are many ways to accomplish the same task.
    For instance, if you can recognize a pattern in your programming statements or among the numbers, quite often you can reduce the number of statements required. Suppose you want to draw seven horizontal lines across the screen. The lines are to be in rows 4, 7, 10, 13, 16, 19, and 22. You could use seven CALL HCHAR statements. Notice, though, that the numbers are each separated by 3. If you start with row 4 and add 3 each time until you get to 22, you'll have the lines you want. A FOR-NEXT loop could draw these same lines in only three statements:

200 FOR ROW=4 TO 22 STEP 3
210 CALL HCHAR(ROW,1,95,32)
220 NEXT ROW

    Here's another problem. Suppose you want to draw a flower in several places on the screen, and each flower takes five characters, two on top of three others. The flowers are scattered randomly, so there's no pattern to their placement. In this case, a subroutine to draw the flower would be appropriate. Before you enter the subroutine, you could specify the row and column positions in the variables R and C. In the subroutine, the CALL HCHAR statements (or CALL VCHAR) need to be expressed in terms of R and C. If the upper-left corner of the flower is in position R,C then the next square would be R,C+1. Below R,C is R+1,C and next to it would be R+1,C+1 then R+1,C+2. The subroutine would look like this:

500 CALL HCHAR(R,C,112)
510 CALL HCHAR(R,C+1,113)
520 CALL HCHAR(R+1,C,114)
530 CALL HCHAR(R+1,C+1,115)
540 CALL HCHAR(R+1,C+2,116)
550 RETURN

And each time you need a flower, you would call the subroutine like this:

700 R=3
710 C=8
720 GOSUB 500

Streamlining Your Code
Now let's say you're drawing snakes instead of flowers. The snake still takes five characters, but all in a horizontal line. The subroutine might look like this:

500 CALL HCHAR(R,C,112)
510 CALL HCHAR(R,C+1,113)
520 CALL HCHAR(R,C+2,114)
530 CALL HCHAR(R,C+3,115)
540 CALL HCHAR(R,C+4,116)
550 RETURN

    Notice that there is a pattern among the numbers. In each statement the column number increases by 1 and so does the character number. The five CALL HCHAR statements can be changed to:

500 FOR A=0 TO 4
510 CALL HCHAR(R,C+A,112+A)
520 NEXT A

    A young friend came to me with a program in which he was randomly choosing five words, then printing them on rows 5, 7, 9, 11, and 13. He had to keep track of the words, their placement (order), and the answers. One solution was to DIMension arrays of W$ and ANS$ where the element specified was also the row number-so he had W$(R) and ANS$(R), where R was 5, 7, 9, 11, and 13. This method is easy to understand and worked well, but we were running into memory problems. Those arrays were taking up space because we weren't really using all the elements.
    Notice that there is a pattern to the numbers:

Word 1-Row 5
Word 2-Row 7
Word 3-Row 9
Word 4-Row 11
Word 5-Row 13

    The row numbers increase by 2. If you multiply each word number by 2, they become 2, 4, 6, 8, 10. Now compare these numbers with 5, 7, 9, 11, 13. Each of the word numbers (multiplied by 2) is 3 less than the row numbers. Therefore, if we have a word number N, the row number would be 2*N+3.
    Later in the program, if we know the row number R and want to find the word number, we need to relate 5, 7, 9, 11, 13 to 1, 2, 3, 4, 5. First subtract 3 from the row number, then notice that the result is 2 times the word number. Given the row number R, the word number is (R-3)/2.
    Quite often, if you line up a group of numbers you can see a relationship or a pattern. You can usually use standard arithmetic operations to get from one column of numbers to the next. If there is a progression of numbers, you can use a FOR-NEXT loop with a certain STEP size to get the right series of numbers.

Programming A Reflection
In this month's example program, we'll see how numbers can be manipulated to simulate reflections in graphics. The program takes a design you draw in the upper-left quadrant of the screen and creates reflections in the other three quadrants. We don't want the pattern simply repeated (as in the "Quilt Squares" program), rather, we want to actually reverse the image.
    First, you draw a design in an area defined by rows 2 through 12 and columns 6 through 16. For example, the drawing starts in row 12 and column 16. This particular square reflects onto the other quadrants in squares (12,17), (13,16), and (13,17). The top-left square of the drawing quadrant is (2,6), or row 2 and column 6. The corresponding squares in the other quadrants are (2,27), (23,6), and (23,27).
    In general, for a certain row R and column C, the corresponding square in the upper-right quadrant would be on the same row R and the column number would be 17 (the quadrant starts in the seventeenth column) plus (16-C). The first quadrant ends in column 16, and you subtract the first quadrant's column number to get its distance from the center. The result is 33-C. Another way to look at it is that the column number will be the same distance from the last column as the original square is from the first column-thus 32-C+1 or 33-C.
    The corresponding square in the lower-left quadrant will have the same column number C as the original square, but the row will be 12+13-R or 24+R-1, which is 25-R. The lower-right quadrant has the same row as the lower-left quadrant and the same column as the upper-right quadrant. Thus the three corresponding squares are (R,33-C) and (25-R,C) and (25-R,33-C). Lines 620-640 and 1000-1020 use these relationships.

Electronic Snowflake
When I was a child I liked to fold paper, cut a design, then unfold the paper to see what it looked like. Sometimes we would fold the paper to get a six-sided snowflake. Other times we would fanfold the paper. We also used different variations of simply folding the paper into rectangles.
    This "Snowflake" program is the computerized version of cutting paper snowflakes (with no scraps of paper to clean up). Suppose you have a square piece of paper. Fold it in half to make a rectangle, then fold the rectangle in half to make a square. Now cut a design in that square. Unfold the paper and you have a foursided snowflake.
    When you run this program, you will see a large square outlined. You can draw in the upperleft square only. Use the arrow keys to move the cursor, press F to fill the cursor position with color, and press the space bar to preserve the background color (or to erase a previously filled position). When your design is complete, press ENTER. The computer starts at the center and moves outward to reflect your pattern on the other quadrants of the larger square.
    When the design is complete, you can press M to modify, S to start a new pattern, P to print the pattern if you have a printer, and ENTER to end the program. If you press M to modify, the cursor starts blinking again and you can resume drawing. But this time your changes appear immediately in the rest of the design. When you're finished, you can press ENTER again. If you press S to start a new pattern, the screen clears and you can start over.
    To use the printer option, the printer must be attached and switched on (don't forget the RS-232 interface). Line 800 contains the printer configurations; modify it if necessary. The hard copy printout is elongated but shows the pattern you drew. Filled squares are represented by asterisks and the blanks by dots. If you want, you could even use this pattern for counted crossstitching or needlepoint.

Program Explanation
Lines 110-200 clear the screen and print the title and instructions. Lines 210-270 define characters used as graphics. Characters 96-99 are used to outline the large square and the drawing quadrant. Character 104 is the filled square, and character 105 is the cursor used in drawing. Character 112 is the yellow dot used to indicate the ENTER key after the snowflake is complete. Lines 280-290 define the colors for the snowflake and the ENTER key symbol. If you wish to use different colors for the snowflake, change the color number 5 in line 280 and the screen color in line 430.
    Lines 300-390 wait for you to press ENTER, then continue the instructions. Lines 400-410 wait for you to press any key to start. Lines 420-490 clear the screen, change the screen color to cyan (light blue), then outline the large square and the upper-right quadrant.
    Lines 500-510 define the starting row X and column Y for the drawing cursor. Lines 520-540 call the subroutine that is the procedure for moving and filling in squares until the ENTER key is pressed.
    When you press ENTER, lines 550-570 make a beeping sound, then erase the lines for the quadrant. Lines 580-660 look at each square in the upper-right quadrant. If they find a filled square, they draw a square in the other quadrants in the corresponding position. This happens in loops, starting with the center square and moving outward (by columns C) and upward (by rows R). When the process is complete, line 670 sounds another beep.
    Lines 680-730 print the options to press M for modify, S to start over, P to print, or ENTER to end. Lines 740-780 detect the key pressed and branch accordingly.
    Lines 790-920 contain the printing option. You must have a printer connected, and your printer configuration must be specified in line 800. The computer looks at each row from 2 to 23 and each column from 6 to 27 using CALL GCHAR, and then prints a period for a space and an asterisk for a filled square. After the printing is complete, the program branches back to the options of M, S, P, and ENTER.
    Lines 930-1030 contain the modify option. First the options at the right of the square are cleared. Then the drawing cursor reappears. Design changes instantly appear in the other three quadrants. When you press ENTER, the program branches back to the options of M, S, P, and ENTER.
    Lines 1040-1320 contain the subroutine for the drawing procedure. CALL GCHAR checks to see what character is in position X,Y and calls that character number (G). Lines 1060-1080 blink the cursor while waiting for a keypress. Lines 1090-1300 are the branching statements executed when certain keys are pressed. Line 1310 draws the new character if it is a space or a filled square.
    Lines 1330-1340 clear the screen, then end the program.
    If you wish to save typing, you can receive a copy of this program by sending a blank cassette or disk, a stamped, self-addressed mailer, and $3 to:

C. Regena
P.O. Box 1502
Cedar City, UT 84720

    Please be sure to specify that you need the TI version of Snowflake.

Snowflake

Refer to "COMPUTE!'s Guide To Typing In Programs" before entering this listing.

100 REM SNOWFLAKE
110 CALL CLEAR
120 PRINT TAB(9);"SNOWFLAKE":::
130 PRINT "USE THE ARROW KEYS TO DR
    AW"
140 PRINT :"IN THE UPPER LEFT OUADR
    ANT."
150 PRINT :"PRESS 'F' TO FILL A SQU
    ARE."
160 PRINT :"PRESS SPACE BAR TO ERAS
    E."
170 PRINT :"PRESS <ENTER> WHEN YOU"
180 PRINT :"ARE FINISHED DRAWING."
190 PRINT ::"THE COMPUTER WILL COMP
    LETE"
200 PRINT :"THE SNOWFLAKE."
210 CALL CHAR(96,"00000000000000FF")
220 CALL CHAR(97,"898989898989898")
230 CALL CHAR(98,"FF")
240 CALL CHAR(99,"0101010101010101")
250 CALL CHAR(104,"FFFFFFFFFFFFFFFF
    ")
260 CALL CHAR(105,"FF818181818181FF
    ")
270 CALL CHAR(112,"3C7EFFFFFFFF7E3C
    ")
280 CALL COLOR(10,5,1)
290 CALL COLOR(11,12,1)
300 PRINT ::"PRESS <ENTER>."
310 CALL KEY(0,K,S)
320 IF K<>13 THEN 319
330 CALL CLEAR
340 PRINT "AFTER SNOWFLAKE IS COMPL
    ETE,"
350 PRINT :"PRESS <M> TO MODIFY PAT
    TERN"
360 PRINT :"PRESS <S> TO START OVER"
370 PRINT :"PRESS <P> TO PRINT COPY"
380 PRINT :"PRESS <ENTER> TO END."
390 PRINT :::::"PRESS ANY KEY NOW T
    O START."
400 CALL KEY(0,K,S)
410 IF S<1 THEN 400
420 CALL CLEAR
430 CALL SCREEN(8)
440 CALL HCHAR(1,6,96,22)
450 CALL VCHAR(2,28,97,22)
460 CALL HCHAR(24,6,98,22)
470 CALL VCHAR(2,5,99,22)
480 CALL VCHAR(2,17,97,11)
490 CALL HCHAR(13,6,98,11)
500 X=12
510 Y=16
520 CALL SOUND(150,1397,2)
530 GOSUB 1050
540 IF K<>13 THEN 530
550 CALL SOUND(100,1497,2)
560 CALL HCHAR (13,6,32,11)
570 CALL VCHAR(2,17,32,11)
580 FOR R=12 TO 2 STEP -1
590 FOR C=16 TO 6 STEP -1
600 CALL GCHAR(R,C,H)
610 IF H=32 THEN 659
620 CALL HCHAR(R,33-C,H)
630 CALL HCHAR(25-R,C,H)
640 CALL HCHAR(25-R,33-C,H)
650 NEXT C
660 NEXT R
670 CALL SOUND(100,440,2)
680 CALL VCHAR(8,29,60,4)
690 CALL VCHAR(8,31,62,4)
700 CALL HCHAR(8,30,77)
710 CALL HCHAR(9,30,83)
720 CALL HCHAR(10,30,80)
730 CALL HCHAR(11,30,112)
740 CALL KEY(0,K,S)
750 IF S<1 THEN 740
760 IF K=83 THEN 420
770 IF K=13 THEN 1330
780 IF K<>80 THEN 930
790 REM PRINTER CONFIGURATION
800 OPEN #1:"RS232.BA=600"
810 FOR R=2 TO 23
820 FOR C=6 TO 27
830 CALL GCHAR(R,C,H)
840 IF H<>32 THEN 879
850 PRINT #1:".";
860 GOTO 880
870 PRINT #1:"*";
880 NEXT C
890 PRINT #1:CHR$(13)
900 NEXT R
910 CLOSE #1
920 GOTO 670
930 IF K<>77 THEN 740
940 CALL VCHAR(8,29,32,4)
950 CALL VCHAR(8,30,32,4)
960 CALL VCHAR(8,31,32,4)
970 CALL SOUND(150,1397,2)
980 GOSUB 1050
990 IF K=13 THEN 670
1000 CALL HCHAR(X,33-Y,G1)
1010 CALL HCHAR(25-X,Y,G1)
1020 CALL HCHAR(25-X,33-Y,G1)
1030 GOTO 970
1040 REM SUB TO DRAW
1050 CALL GCHAR(X,Y,G)
1060 CALL KEY(0,K,S)
1070 CALL HCHAR(X,Y,105)
1080 CALL HCHAR(X,Y,G)
1090 IF K=13 THEN 1320
1100 IF K=70 THEN 1300
1110 IF K=32 THEN 1280
1120 IF K<>88 THEN 1160
1130 IF X=12 THEN 1060
1140 X=X+1
1150 GOTO 1050
1160 IF K<>83 THEN 1200
1170 IF Y=6 THEN 1060
1180 Y=Y-1
1190 GOTO 1050
1200 IF k<>68 THEN 1240
1210 IF Y=16 THEN 1060
1220 Y=Y+1
1230 GOTO 1050
1240 IF K<>69 THEN 1060
1250 IF X=2 THEN 1060
1260 X=X-1
1270 GOTO 1050
1280 G1=32
1290 GOTO 1310
1300 G1=104
1310 CALL HCHAR(X,Y,Gl)
1320 RETURN
1330 CALL CLEAR
1340 END