(This is the "Dungeon Designs" column from the September 1988 issue of the Eamon Adventurer's Guild newsletter. Copyright 1988 Eamon Adventurer's Guild, 7625 Hawkhaven Dr., Clemmons, NC 27012-9408. You may reproduce this freely as long as this credit remains attached to the article.) ====================================================== Dungeon Designs ------------------------------------------------------ Programming efficiently for space and speed. *** VARIABLES Real ARRAY variables use 5 bytes each, while Integer ARRAY variables use only 2. Thus DIM AD%(x,x) consumes 2000 bytes of memory, but DIM AD(x,x) uses 5000 bytes! Always use Integer for large arrays. Real SIMPLE variables use LESS memory than Integer variables, and execute faster, too. ALWAYS use Simple Real variables. Applesoft only 'sees' the first two characters of a variable name. It can't tell a difference between DIE and DIS, which can cause you some real trouble. Short names also save memory. Use short variable names. *** LOOPS Consider the following routine: 7420 FOR A = 1 TO NA: IF AD%(A,4) < > ROOM OR AD%(A,2) < 2 OR AD%(A,2) > 3 THEN 7440 7430 PRINT MN$(OF);" PICKS UP";AN$(A):(other statements):RETURN 7440 NEXT:RETURN This routine has 3 serious problems: 1)Applesoft finds GOTO lines by going to the beginning of the program and checking EVERY line number until it finds it. You have all seen times when a monster broke its weapon during a fight, there were no weapons lying about the room, and things slowed down a LOT each time that monster's turn to fight came up. The above code is responsible. 2)Line 7420 does 3 comparisons for EACH artifact tested, even if the artifact isn't in the room. 3)Line 7430 does a RETURN, leaving an OPEN LOOP. This leaves all of the loop's 'housekeeping' on the program stack, which is only 256 bytes long. If we use up the stack, eventually it 'overflows', and the program crashes with an OUT OF MEMORY error. Note that the program is not really out of memory. This is the cause of Eamon's OUT OF MEMORY problem. Now look at this routine: 7420 FOR A = 1 TO NA: IF AD%(A,4) < > RO THEN NEXT: RETURN 7425 IF AD%(A,2) < 2 OR AD%(A,2) > 3 THEN NEXT: RETURN 7430 PRINT MN$(OF);" PICKS UP";AN$(A):(other statements):A = 999 7440 NEXT: RETURN 1)Line 7420 avoids doing the time-consuming GOTOs by doing its own NEXT. If it has examined all of the artifacts, the NEXT 'falls through', and the RETURN is executed. This is a huge timesaver. 2)Line 7420 only checks to see if the artifact is in the room This way we avoid doing unnecessary comparisons. 3)Line 7430 sets 'A' to a number that is greater than NA. Thus when line 7440 is executed, the NEXT statement 'closes the loop', clearing the program stack. The above listing was to illustrate some points. Here is the optimum listing: 7420 FOR A = 1 TO NA: IF AD%(A,4) = RO THEN IF AD%(A,2) = 2 OR AD%(A,2) = 3 THEN PRINT MN$(OF)" PICKS UP"AN$(A):(other statements):A = 999 7430 NEXT: RETURN *** MINIMIZING COMPARISONS Examine the following example: 510 IF RO = 17 AND MD%(5,5) = RO AND PW < 5 AND RND(1) < .5 THEN GOSUB 30000 In this line, all 4 comparisons are ALWAYS done, even if you are not in room 17. Now look at this: 510 IF RO = 17 THEN IF MD%(5,5) = RO AND PW < 5 AND RND(1) < .5 THEN GOSUB 30000 See how this line reduces the comparisons to just one. *** EXITING SUBROUTINES NEVER use GOTO to exit from a subroutine! This is a VERY fast road to a stack overflow OUT OF MEMORY crash. Always use RETURN or POP:GOTO to exit from subroutines, so that the stack is cleared. This tutorial must be brief due to space limitations. If you have further questions, drop me a line.This is a VERY fast road to a stack overflow OUT OF MEMORY crash. Always use RETURN or POP:GOTO to exit from subroutines, so that the stack is cleared. This tutorial must be brief due to space limitations. If you have further questions, drop me a line