BASIC Training

by Tom Hudson


In this issue's BASIC Training, we'll continue looking at concepts that will help BASIC game programmers. The first topic is a return to issue 18's vector routines, and the second is an easy way to speed up your BASIC games.

Both of this issue's topics were taken from a letter I received from Harold L. Reed.

Vectors revisited

Mr. Reed's letter begins:

Dear Tom,

I enjoyed your BASIC Training segment in the April issue of ANALOG. The follower routines you presented were very interesting, but as you said in your article, the routine that produces the best results (Figure 6) has the drawback of being slow until the follower gets near the target. This occurs because the routine in Line 160, which determines the step size for X and Y, accomplishes the task by finding the total X and Y distances between the two points and dividing by 2 repeatedly, until both DELTAX and DELTAY are less than or equal to 1. So, when the points are far apart, the distances have to be divided by 2 many times in order to make them less than or equal to 1. The closer the points come to each other, the less times the dividing loop has to be repeated, and the faster the results appear.

This can easily be solved. Since the objective is to scale both DELTAX and DELTAY so that the larger of them equals 1, simply determine which one is larger, divide the smaller by the larger, then set the larger equal to 1. This can be done by replacing Line 160 with the following:

160 IF DELTAX>DELTAY THEN DELTAY=DELTA
Y/DELTAX:DELTAX=1:GOTO 170
165 DELTAX=DELTAX/DELTAY:DELTAY=1

This speeds up the operation considerably, since only one calculation is now needed. However, it also generates an error when the follower and target come together. This occurs because the program doesn't check to see if it should stop until it calculates its next move. So, if the points are right on top of each other and the routine tries to calculate the next position of the follower, it ends up dividing by zero, which generates the error.

This can be corrected by moving Line 190 to Line 225. The end point check, which was formerly done after the next set of calculations was completed, is now done after each move is completed. The routine is now very fast.

Is my face red! When I originally wrote the algorithm for this follower routine, I was working with assembly language, which does not have true division. I translated the routine into BASIC too literally, and didn't stop to think that BASIC had a faster solution. In any case, Figure 1 shows the new, improved "FOLLOWER (VECTOR 1)" routine, courtesy of Harold J. Reed.

Figure 1

BTRAIN.LST is available in ATASCII format.

10 REM *** FOLLOWER (VECTOR 1) ***
20 REM 
30 GRAPHICS 6:COLOR 1
40 DIM XS(15),YS(15):FOR I=1 TO 15:REA
D X,Y:XS(I)=X:YS(I)=Y:NEXT I
50 DATA 0,0,0,0,0,0,0,0,1,1,1,-1,1,0,0
,0,-1,1,-1,-1,-1,0,0,0,0,1,0,-1,0,0
60 FX=0:FY=0
70 TX=80:TY=40
80 STIK=STICK(0)
90 TX=TX+XS(STIK)
100 TY=TY+YS(STIK)
110 PLOT TX,TY
120 XD=SGN(TX-FX)
130 YD=SGN(TY-FY)
140 DELTAX=ABS(TX-FX)
150 DELTAY=ABS(TY-FY)
160 IF DELTAX>DELTAY THEN DELTAY=DELTA
Y/DELTAX:DELTAX=1:GOTO 170
165 DELTAX=DELTAX/DELTAY:DELTAY=1
170 XV=DELTAX*XD
180 YV=DELTAY*YD
200 FX=FX+XV
210 FY=FY+YV
220 PLOT FX,FY
225 IF INT(FX)=INT(TX) AND INT(FY)=INT
(TY) THEN 240
230 GOTO 80
240 ? "GOTCHA!":END
Checksum Data
10 DATA 420,253,28,350,327,808,992,514
,642,729,181,329,339,185,196,6293
160 DATA 146,886,580,589,820,828,130,7
65,505,441,5690

Faster execution made easy

Continuing with our special "Harold J. Reed" installment of BASIC Training, here's something simple you can do that can increase the execution speed of your BASIC programs. Harold writes:

I once developed a rather large program and then developed a title screen to go with it. To avoid running the entire program as the title screen was being debugged, I worked on it separately. I used a FOR/NEXT loop to slow down my plotting routine to the desired speed. But then, when it was just right and I added it to my main program, it ran much slower! If BASIC interprets one line of a program at a time, why would the length of the program have any effect on the speed of execution?

This is a very good question, and one which most programmers don't think about or even realize. But the fact is: code placed at the end of a BASIC program executes slower than code at the beginning! Let's find out why.

When a program is sitting in the computer's memory, BASIC only knows where the first line is located. In order to find the second line, BASIC goes to the first line and gets the pointer to the next line.

If BASIC needs to find the tenth line of a program, it must get the first line and find the pointer to the second line. It then looks at the second line for the pointer to the third line, and so on until it gets the line it's looking for. Imagine how much time is wasted looking for, say, the 400th line of a program!

Just so I could see how much time is lost when code is placed at the end of a program, I put a FOR-NEXT loop at the beginning of the BASIC code for Retrofire, which is roughly 225 lines long. When executed, the loop took about 24 seconds.

I then placed the loop at the end of the Retrofire program and executed it. This time, it took 99 seconds, over four times as long as it did at the beginning of the program!

A program will be slowed down any time code near the end is referenced by line number. For example, the statements GOTO 1000, GOSUB 1000, RESTORE 1000, etc. would all slow down the program if the line number referenced was at the end of the program. FOR/NEXT loops are also affected, since internally BASIC keeps track of the line containing the FOR statement.

If you write games in BASIC, it's a good idea to place one-time initialization routines or title screens at the end of the program. Keep often-used subroutines and the main control code at the beginning of the program. Remember, simply by organizing your code more carefully, you can increase the programs speed by several times!

Write on

I'd like to thank Mr. Reed for sharing his insights with all the ANALOG readers. If you've got a question or observation, scribble it down on a postcard and send it to BASIC Training. There's no such thing as a "stupid" question, and you could help potentially thousands of other readers with the same problem.

Until next time, see if you can improve the performance of your old BASIC games by reorganizing the code. You may be pleasantly surprised.


Previous | Contents | Next

Original text copyright 1984 by ANALOG Computing. Reprinted with permission by the Digital ANALOG Archive.