|★ CODING ★ 11. PROGRAMMING TECHNIQUE ★|
|Writing Adventure Games on the Amstrad - 00 - Contents||Writing Adventure Games on the Amstrad - 11 - Programming technique|
1. PROCEDURAL APPROACH
The problem tackled by AKS has been divided into several subproblems and each of these divided into sub-problems and so on until each sub-problem becomes trivial. These trivial sub-problems are then coded as Basic Subroutines. It is important that the interaction between these subroutines is tightly controlled and made clear in the listing. To this end, the assignment of a value to a variable which is to be used in another subroutine is made on the same line as the ‘GOSUB' statement (e.g. 'loc=0:GOSUB 1230:REM *isobjatloc*'). If a subroutine returns a value in a variable then where possible any testing of that value, or any use of that value is performed immediately after returning from that routine.
2. SENSIBLE VARIABLE USAGE
The most obvious point here is the use of meaningful variable names to increase readability. Amstrad Basic allows multi-character variable names for this reason. In addition to enhancing readability, the use of long variable names reduces the chance of conflicting use of a variables (i.e. attempting to use the same variable for different things at the same time). All variable names are in lower case to make them stand out from the upper case Basic keywords.
AKS initialises several constants at the start of the program (e.g. the number of scenario locations is set by 'rnaxloc =30'). As their name suggests these ‘variables' are not changed anywhere else in the program, even though it is strictly possible to do so. This has two effects. Firstly, it increases readability and secondly, it makes it easy to modify the program because the value need only be changed in one place.
Comments are used in an orderly and consistent way. Lines containing just a colon are used extensively to space the program out and divide it into logical blocks. In the main part of the program a logical block is a group of instructions with a similar function. For the rest of the program, a logical block is a subroutine. In addition, every subroutine is headed by two ‘REM' statements. The first of these has the name adopted throughout AKS for that routine bracketed by three asterisks (e.g. 'REM *** resetflags ***'). The second is just a blank 'REM' statement to highlight the routine title.
Any subroutine call is followed by a comment containing the name of the routine bracketed by single asterisks (e.g. 'GOSUB 5000:REM *resetflags*'). To maintain this standard some 'IF condition THEN gosubsomewhere ELSE gosubsomewhereelse' statements have been split into two statements (i.e. ‘IF condition THEN gosubsomewhere' and 'IF NOT (condition) THEN gosubsomewhereelse') to allow the 'GOSUB's to be followed by a comment.
Although the game is written to run in the 40 column MODE 4, the commenting has been written for viewing in the 80 column MODE 2. Where possible, comments about the operation of program lines are on the same line and use the single quote character instead of ':REM . . .' to start the comment. This helps to distinguish normal comments from subroutine labels on ‘GOSUB's. Should the comment be too long to fit on the same screen line or if it is syntactically invalid to have a comment on the same line as that type of statement then the comment is placed, where possible, on the line preceding the statement. In this case a normal ‘REM' is used instead of a single quote to make the comment stand out from the Basic statements. Unless emphasising something, comments are in lower case to make the upper case Amstrad Basic keywords easy to see.
4. CAREFUL CONTROL OF FLOW
Something which explicitly controls the flow of a program is potentially very dangerous. Apart from having the potential to make a program totally unreadable, incorrect use of flow controlling instructions can result in corruption of the Basic stacks. The most obvious control flow instruction is 'GOTO'. Much has been written about the use and misuse of 'GOTO', but few will deny that it is difficult to program in Basic without it. Amstrad Basic goes some way towards removing the need to use 'GOTO' by allowing the use of 'WHILE..WEND' loops as well as the normal ‘FOR..NEXT' loops. AKS makes much use of the 'WHILE..WEND' construction. Another common use of ‘GOTO' is to implement multiline ‘IF..THEN..ELSE..' statements. AKS avoids using ‘GOTO' for this by the use of multistatement lines instead. However, AKS does make use of GOTO' as a quit instruction to skip over the rest of a ‘WHILE' loop's instructions and go directly to the 'WEND'. This technique of jumping to 'WEND' is used to terminate the loop without corrupting the Basic stack. When AKS does this, a comment is used to identify the 'GOTO' as a quit instruction.
Another frequently misused control flow instruction is ‘GOSUB'. To make a subroutine easily understandable, a subroutine should have only one entry point. In the AKS listing the entry point to each subroutine is the line immediately following the title ‘REM'. It is a good idea not to 'GOSUB' or 'GOTO' a 'REM' statement, as these are often removed from the runtime version of the program; thereby causing a 'line does not exist' error. The last instruction in every AKS subroutine is a 'RETURN'. The practice of using 'GOTO' to jump in and out of subroutines is avoided. However, it is often desirable to skip the remaining instructions in a subroutine. This could be done using ‘GOTO' to jump to the ‘RETURN' instruction. A cleaner solution is to use another 'RETURN' instruction instead of the 'GOTO'. Even here, AKS comments the premature subroutine exits as quits.
Examination of the first few lines of the AKS listing will reveal that everything is not perfect. To implement AKS in Amstrad Basic a significant problem must be overcome. AKS works by interpreting a scenario database specified in ‘DATA' statements at the end of the program. Each statement occupies one ‘DATA' line and AKS must be able to find the start of any given statement. Unfortunately, Amstrad Basic does not allow use of the ‘RESTORE' statement with a variable line number (i.e. 'RESTORE fred' is illegal). Instead, it insists on a literal line number (e.g. 'RESTORE 500'). Totally legitimate use of 'RESTORE' in AKS would require a ridiculously time consuming search from the first 'DATA' statement, reading a string (not a line) at a time, until the desired line is found. Therefore, AKS resorts to a 'dirty technique' which 'POKE'S the value of a variable into the space occupied by the literal line number part of a 'RESTORE' statement IN THE BASIC PROGRAM. This explains the existence of the first few lines of the program. For example, to ‘RESTORE' to line 370, AKS would perform ‘lin =370:GOSUB 20:REM ‘restorelin*'. This fudge routine is placed at the front of the program along with comments giving a warning of the dangers inherent in this technique. Obviously, changing this routine will result in the wrong part of the program being altered and may corrupt the code. Things are further complicated by the fact that the ‘RESTORE' statement's line number must be set to a non-existent line number before attempting to 'RENUM'ber the program. The small 'ENTER' key is programmed to do this. AKS requires the 'DATA' statements in the scenario to be numbered in increments of the constant ‘lineinc'. The normal value of 'lineinc' will be 10 — which is the default line number increment used by Basic 'RENUM' and 'AUTO'.
In addition to knowing the line number increment, AKS must know the line number of the first ‘DATA' statement of the scenario definition. It is unreasonable to expect a programmer working on AKS to find this out and set a variable to the value everytime he adds a new line of Basic. For this reason, a second ‘dirty technique' is used. To find this value, AKS jumps to a purposely included invalid program line that immediately precedes the first ‘DATA' statement of the scenario definition. AKS traps the error generated using ‘ON ERROR..' and assigns ‘datastart' the line number of the line after the invalid line (i.e. ‘ERL + lineinc1) Although not as dangerous as the first ‘dirty technique', this technique is also heavily commented.