Chapter 7 PAGE 1 STARTREK THE COMPUTER PROGRAM CHAPTER 7 7.1 The ENDGAME Routine Moving the Enterprise around in space uses fuel or energy. There is thus a probability that the Enterprise will exhaust its supply and that condition must be taken care of before the move subroutine is added to the program. There are five different ways in which the game can end. They are as follows. 1 The player resigns and ends the game voluntarily. 2 The Enterprise is destroyed by enemy action. 3 The Enterprise runs out of energy before the mission is completed. 4 The allotted time for the game is over before the mission is completed. 5 All the enemy ships are destroyed by the player. This is the only case in which the player actually 'wins' the game. The main loop of the program is performed as long as the 'game over flag' (F9) remains equal to zero. It is however set to a non-zero condition when one of the five conditions for ending the game is encountered. When the flag is set, the program flow branches away from the main loop to the 'End of the game' sequence. The flowchart for the End of the game sequence is shown in figure 7.1. Various routines not yet discussed set up some value in F9 when one of the conditions to end the game is encountered. The End of the game sequence tests to see which of them was set up and displays messages accordingly. The player's score at the instant the game ended is then displayed, and some dialog ensures as the computer asks the player to decide if another game is desired. If another game is desired, the computer first prompts the player to standby, then re-initializes various variables and flags. Lastly, the mission message is displayed that tells the player how many enemy ships have to be destroyed in how much time, and the program flow picks up again at the main command loop. If the player does not want another game, the program ends and control is returned to the BASIC command level. A BASIC language implementation of the End of the game sequence is shown in figure 7.2. It begins at line 9000 with the usual REMark statement. Line 9010 first does a 'PRINT' statement to move the cursor down one line. At this time, the 'End of the game flag' contains one of five different values between 1 and 5. The statement ON F9 GOTO 9020,9040,9080,9130,9160 routes the program flow to the correct line corresponding to the value in F9. You will remember that the 'ON' statement is Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 2 STARTREK THE COMPUTER PROGRAM equivalent to a sequence of 'IF/THEN' statements. In this case the equivalent statements would be 9011 IF F9=1 THEN 9020 9012 IF F9=2 THEN 9040 9013 IF F9=3 THEN 9080 9014 IF F9=4 THEN 9130 9015 IF F9=5 THEN 9160 When F9=1, the player has voluntarily resigned from the game. The Resignation ending begins at line 9020. Nothing is displayed here because it was all taken care of in the dialog that was part of the still to be described Resignation command. The line thus only contains a 'REM' statement and the next line, line 9030 jumps the program flow forward to line 9180. When F9=2, the Enterprise has been destroyed by the Klingons. This ending begins at line 9040 with the usual 'REM' statement. Line 9050 then displays a message to the effect that the Enterprise has been destroyed. Line 9060 displays a sarcastic message about the quality of the player's ability as a Captain and line 9070 jumps the program flow forward to line 9180. When F9=3 the player has run out of energy in the middle of the mission. Line 9080 starts that sequence with the usual REMark. Line 9090 displays a message telling the player that the Enterprise has indeed run out of energy. The 'PRINT' statement at the end of the line advances the cursor down one line, or inserts a blank line between what was just displayed and what comes next. Line 9100 and 9110 display a sarcastic comment telling the player that the Captain, the ship and the crew have just been condemned to a horrible, lingering and un-necessary death as the life support systems on-board the Enterprise fail one by one due to the lack of energy. There is no hope of rescue, because without energy, there is no way to get in touch with any potential rescuers. Line 9120 then advances the program counter to line 9180. When F9=4 the player has run out of time. That sequence picks up at line 9130 with the usual REMark statement. Line 9104 tells the player in no uncertain terms why the game has ended, and line 9150 jumps the program counter forward to line 9180. When F9=5 the player has destroyed all the enemy vessels within the allotted amount of time. This sequence picks up at line 9160 with the customary REMark statement. Line 9170 displays a message congratulating the player on winning the game, and the program counter falls through to line 9180. Line 9180 uses a 'PRINT' statement to generate a blank line at the cursor and then calls the subroutine starting at line 170 to display the player's score at the instant the game ended. The line continues with the dialog to determine if the player wants Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 3 STARTREK THE COMPUTER PROGRAM another game. The player is prompted for an input using the 'INPUT' statement. The format of the expected reply is also given as part of the prompt, ie. the (Yes/No) part. Notice also the space before the last quotation mark. The reply is assigned to the dialog string variable A$ (Answer$). The last statement on the line tests the answer in A$ to see if it is at least one character long. The 'LEN(A$)' function is used to determine how many characters have been put into A$. If the answer is zero, then none have been put into the string, ie. the player pushed the 'carriage return' or 'enter' key without first entering the correct response. If that condition is in effect, the program counter is reset to line 9180 which displays the score once more, and and repeats the question. Line 9190 tests the first characters in A$ to see if it is an "N". If it is, the program flow jumps to line 9230. Line 9200 tests the first character of the string to make sure that it is not equal to a "Y". If the character is not equal to a "Y", the the player has not answered the question correctly and the program flows back to line 9180 to repeat the dialog. The 'LEFT$(A$,Z)' statement picks out the first character of the string. In that way, answers such as 'Y', 'YES'. 'YEP' or 'YUP' will all generate the same correct response to a 'YES' condition, while 'N', 'NO, NOPE' or even 'NO THANKYOU' will all cause the 'NO' sequence to be performed. This is a neat technique for allowing the player freedom in replying while at the same time minimizing the amount of program required to detect and verify that the reply is valid and desired. A length test must always be performed before using the 'LEFT$(A$)', 'RIGHT$(A$)' or MID$(A$,N,L) functions or an error will be generated when the function tries to operate on a zero length string. In a zero length string, the first character does not exist and so the computer does not know what to do and generates an "ERROR" message and terminates the program. In dialects of BASIC that allow error trapping, that error can be caught and compensated for. It is better however to get into the habit of writing programs that trap potential erroneous inputs when they are generated, rather than when they are processed. You may forget later that an erroneous entry needs to be trapped, not find it in debugging because you didn't test for it, and only later when the program is published do you get many irate letters from readers who used your program, entered lots of data into it, only to lose them all when the program abruptly terminated due to such an error. Look at articles and listings in magazines. You will see many that include the sequence INPUT "PROMPT OF SOME KIND";A$ : IF LEFT(A$,1)= . Sloppy! The sequence to start a new game begins at line 9210 with the usual REMark statement. Line 9220 clears the screen by outputting a control character in an identical manner to that performed in line 10. If you made a change in line 10 to implement the 'clear screen/home cursor' function, make it here Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 4 STARTREK THE COMPUTER PROGRAM as well. As a reminder, the 'PRINT CHR$(26)' does the job for the OSBORNE 1 computer; the TRS-80 wants 'CLS' and the APPLE II needs 'HOME' to perform the identical operation. The cursor is then moved down one line by the 'PRINT' statement. A "WAIT FOR IT" message is then displayed to tell the player that something is going on and the subroutine starting at line 4660 is called to re-initialize the assorted variables and flags (including F9). The program counter is then reset to line 30 to pick up the main game sequence. It program counter could not have been reset to lines 10 or 20, because of the 'DIM' statement in line 4520, which is part of the subroutine beginning at line 4500 called in line 20. A 'DIM' statement on any particular array can only be carried out once in any one program. Arrays cannot be redimensioned during the execution of the program which is what the computer would think you were trying to do if the statement at the end of line 9220 directed the program counter to 'GOTO' lines 10 or 20. This is the reason that the initialization procedure is split into two parts. The first which begins at line 4500 initializes the parameters (such as Z) and defines all the constants and strings. The second subroutine starting at line 4660 then initializes all the variables and flags. The 'WAIT A MINUTE' prompt at the start of the re- initialization sequence performs an important ergonomic function. Studies on large time-sharing computer systems have shown that people lose interest if the response time of the computer is greater than two seconds. That means if they don't get a response from the computer within two seconds of entering something, they tend to lose interest or get annoyed with the machine. It is thus good practice to display a message telling the user that some routine or other is going to take a while. That way, the user will expect the delay and not wonder if the computer has gone off into some never never land and left the user completely alone. The game ends in line 9230 with the 'END' statement. In most dialects of BASIC, the program ends automatically when the program line after the highest line number is performed. In this case, line 9230 is reached by a branch statement in line 9190. If line 9230 is the last line of the program, You could replace it with a program line that displays a message thanking the player for playing and indicating the hope that the game was enjoyable. At this time however it is not, because the 10000 series of temporary lines are still in it. so the 'END' statement is a requirement. Carefully copy lines 9000 to 9230 into your program and save them. Then 'RUN' the program and debug these lines. Since nothing has yet been written that sets F9, break the program using the ^C character and manually set the contents of F9 to a value between 1 and 5 inclusive. You can do that by entering F9 = 1 or some other value. When you then run the program, you should see the different endings. Try all 5 possible endings, Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 5 STARTREK THE COMPUTER PROGRAM and answer the question posed by line 9180 in different ways to test it. Then when you are satisfied with the performance of the End of the game sequence, update line 10 and save the program once more. We are now ready to go on and examine the 'MOV' command. 7.2 The MOVe Command The Move function is used to navigate the Enterprise around the galaxy. The Enterprise is permitted to go outside the galaxy but in that event, something will be damaged as the starship crosses the Galactic Barrier. The properties of faster than light travel are that it will take about one stardate to get anywhere when traveling at warp speed, but the amount of energy used is a function of the warp factor. the faster the ship goes the more energy is used. The function is also not linear. That means that there is no direct correspondence between warp factor and energy used. For example, you can cross the galaxy at warp factor eight using an enormous amount of energy in one stardate. You can also take two days to do it at warp factor four and use about a quarter of the energy that the warp eight journey required. Travel is thus a trade off between time and energy. Travel inside a quadrant is performed under Impulse Power. Using the impulse engines however is a slow way to travel. It takes 0.1 stardates to cross a sector. Thus if you want to travel across seven sectors, you will use up .7 stardates. The choice of warp or impulse power is automatic. If the player specifies a fractional warp factor, the impulse engines are automatically invoked. Since this is a static game, the Enterprise is always brought to rest at its destination. Several things may happen when traveling as follows. 1 Klingon Space Mines The Enterprise may hit a Klingon Space Mine. This is an energy weapon that functions much like a Phaser hit. It takes energy out of the shields. Make sure you travel with your shields up (with some energy in them). 2 Space Warps The Enterprise may be caught in a gravitational anomaly and be physically hurled across the galaxy in zero time. There is no way to detect these gravitational anomalies ahead of time. 3 Ion Storms Ion Storms also occur pretty much at random. If the Enterprise passes through such a storm, there is a good probability that the ship will suffer some damage. Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 6 STARTREK THE COMPUTER PROGRAM 4 Mr. Spok At Work As you already know, Mr. Spok is a marvel. He is always at work on the ship. From time to time, if he has nothing more urgent pending, he may assist the repair section and perform some special repair action to fix a damaged sub-system in ultra fast time. Now when the starship moves, it can collide with objects in other sectors. If you collide with a starbase, you will receive a nasty message via sub-space radio. If you hit a Klingon, you will probably damage both vessels, however you cannot destroy a Klingon by constantly colliding with it. If you hit a star then one of two things may happen. You may either go into a space warp condition due to the gravitational stresses close to the sun, or if the crew can shut down the engines in time, you will come to rest in space after an emergency engine shut down. It will then take half a stardate to start the matter/anti matter engines again. Consider the flow chart for the Move function as shown in figure 7.3. It begins with some dialog to determine first the course and then the warp factor. If the warp factor entered is equal to or less than zero, nothing happens. You could put some kind of message here reminding the player that those inputs are not allowed. If the desired warp speed is greater than eight, a message stating that the speed is beyond the capabilities of the engines. Assuming an allowable warp factor, the next thing to test is if that warp factor was greater than one. Faster than light travel cannot take place if the engines are damaged. If it was, a further test is performed to determine if the engines are themselves damaged. If they are, an "ENGINES DAMAGED" massage is displayed to the player. and no further action can take place until an allowable warp factor is chosen. If the warp factor is greater than one, faster than light travel is invoked. Once the Enterprise begins to move the enemy first get a chance to fire. A test thus has to be performed to see if they destroyed the Enterprise during that attack. If they did, the rest of the subroutine can be skipped. The Enterprise then moves to a new sector. If the sector is occupied a collision occurs. If the sector is vacant, the Enterprise will either pass through it or stop in it depending on the warp factor. If the Enterprise moves out of the quadrant, it is then transferred to the new quadrant. If the time for the random event occurs, it takes place. The energy used up in moving is computed and as long as there is some energy left on the ship, the state of repair of all the ship's on-board sub-systems is updated, the condition of the Enterprise is then determined, and the subroutine ends. The flowchart of figure 7.3 described some complex Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 7 STARTREK THE COMPUTER PROGRAM operations in one or two words. Some of these operations must themselves be described by flowcharts to fully understand their operations} The COLLISION is itself a complex event. It may be expanded into the flow chart shown in figure 7.4. The function tests to see what was hit. If a star was hit there is a forty percent probability that if there is also no starbase in the quadrant that a space warp will occur. Space warps occur due to gravitational anomalies, and Starbases are not normally located near such dangerous phenomena. If the Enterprise does not enter a gravitational anomaly the Engine Room will perform an emergency engine shut down. It will then take half a stardate to start up the matter/anti-matter reaction. If the Enterprise does come to a halt before the star, it has to be backed up one sector If the Enterprise has hit a Klingon, a message is displayed, the Enterprise is backed up and one sub-system is damaged. The Klingon does not apparently suffer any damage that affects its fighting capability due to the collision. The only other thing that the Enterprise can hit in a sector is a Starbase. If the Enterprise has hit a Starbase, then it is first backed up one sector. A message is displayed stating the fact. The message can take one of two forms. If there are Klingons in the quadrant, the Enterprise comes to a halt. If there are no Klingons in the quadrant, the starbase sends out a tractor beam to stop the Enterprise. The docking procedure will then take place in the usual manner. If there are Klingons in the quadrant, the Base cannot lower its shields to allow the Enterprise to dock, so the Enterprise comes to a hard stop with a suitable message being displayed. The second complex function in the MOVE command is the MOVE.TO.NEW.QUADRANT function shown in figure 7.5. It begins by computing the co-ordinates of the new quadrant the elapsed time. The new co-ordinates and the old ones are then compared to see if the Galactic Boundary Barrier has been crossed. If it has, one of the on-board sub-systems is damaged. The algorithm to test for crossing the galactic barrier is as follows. The first test is to determine if the new position of the Enterprise is inside the galaxy, If it is, we test to see if the previous position of the Enterprise before it moved was also inside the galaxy. If it was, no damage occurs. If it wasn't, the ship crossed the barrier and something gets damaged. A similar test is performed if the new position of the Enterprise is outside the galaxy and the old one wasn't. In that instance damage also occurs when the barrier is crossed. The contents of the new sector are then set up and the function ends. The remaining complex function is the DAMAGE.SOMETHING function shown in figure 7.6. A subsystem is selected at random. Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 8 STARTREK THE COMPUTER PROGRAM An amount of time is selected also at random and the sub-system is damaged (The estimated time to repair (ETR) is updated to that value. A message is then displayed stating that damage has occurred (but not how much) to a particular subsystem. The BASIC language implementation (excluding the SHOOT.BACK function) of the MOVE command could take the form shown in figure 7.7 which begins in line 1300 with the usual REMark statement. The player dialog setting the direction of travel takes place in line 1310. The player is asked for and at the same time prompted to give a valid response by the statement INPUT "DIRECTION PLEASE (1-9) ";C The program has told the player what it wants and also the valid response limits. The compass directions used in the game are shown in figure 7.8. The input number is assigned to the variable 'C'. The second part of the line tests it to see if it is valid. As you can see from the compass, the direction must lie between 1 and 9. The usual 'IF/THEN' statement is employed and tests both conditions by including the 'OR' statement in the test. If the value of C is less than 1 or is greater than 9, it is not valid by definition and the program line counter is reset to the beginning of the line so the player can respond again to the question. Line 1320 asks the player to input the desired Warp Factor, which is assigned to the variable 'W'. The 'INPUT' statement is again employed for that purpose. The last part of the line tests the value of 'W' to ensure that it is a positive value. If the player entered a zero or a negative warp factor then the program counter is advanced to line 1810 by the 'THEN 1750 part of the line, and bypasses the rest of the MOV subroutine. Line 1330 tests the desired warp factor to see if the wanted speed is faster than the engines can supply. The enterprise has a maximum speed of warp factor 8. If the player has entered a warp factor greater than eight, a message to the effect that the Enterprise cannot go that fast is displayed, and the program counter is then reset to line 1320 to ask the player for a valid warp factor. Notice that the message in line 1330 is displayed in a scottish accent simulating the voice of Mr. Scott. Line 1340 tests the state of the engines to see if they are working. If they are, the value in the damage control array 'D(I)' is zero and the program counter is advanced to line 1360. Line 1350 is only reached if the engines are damaged. If they are, the maximum speed is less than warp factor one. The line thus begins with a test to determine if the desired warp factor is greater or equal to one. If it is, a message is displayed stating that the engines are damaged and the program counter is set back to line 1320. If the test at the beginning of the line fails, the desired warp factor was less than one, and the program counter is advanced to the next line. Line 1360 contains a 'REM' statement documenting the fact that at this time Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 9 STARTREK THE COMPUTER PROGRAM the Enterprise begins to move. It is useful to put comments in programs in the middle of subroutines as well as at their beginnings if the module is complex, and this is one of the most complicated modules in the whole game. The Enterprise truly begins to move at line 1370. The contents of the sector occupied by the Enterprise is first reset to a blank value. This is done by the statement 'S(S1,S2)=Z' which assigns the value one (represented by the parameter 'Z') to the contents of the sector defined by the co-ordinates of the Enterprise. Remember, the S(I,J) array stores the contents of the sectors, and, the variables S1 and S2 contain the sector co- ordinates of the Enterprise. The time remaining before the move takes place is saved in the temporary time variable (T1) by using the implied 'LET' statement T1=T. If the warp factor is greater than or equal to one, the Enterprise is by definition, about to leave the quadrant. In that case, if there are any Klingons in the quadrant they are given a chance to fire at the Enterprise by the statement IF K>0 AND W>=Z THEN GOSUB 600. If the enemy have had a chance to shoot at the Enterprise, the possibility exists, that they have been able to destroy the ship. The last part of the line tests the value of the game over flag (F9). If it is greater than zero, something has happened to the Enterprise, so the program counter is advanced to line 1750 bypassing the remainder of the routine. Line 1370 contains two 'IF' statements in series. It may make it clearer if the statements were written as IF (1) K>0 AND W>=Z THEN (1) GOSUB 600 IF (2) F9>0 THEN (2) 1750 ELSE (2) ELSE (1). If the test (1) fails, namely either there are no Klingons in the quadrant, or the warp factor is less than one, the program counter picks up after the 'ELSE (1)' statement. If the test is true, the subroutine starting at line 600 is invoked and the second test performed. The correlation between the 'IF/THEN/ELSE' statement and the 'YES/NO/THEN' of the flow chart is LOGIC POINT FLOWCHART BASIC ---------------------------------------- TEST STATEMENT =? IF RESULT IS TRUE YES THEN RESULT IS FALSE NO ELSE PICK UP POINT THEN following line. In BASIC there is then no clear point where the two logical flows merge again, unlike the flow chart. That is probably the reason Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 10 STARTREK THE COMPUTER PROGRAM why various dialects of BASIC treat the 'IF/THEN' statement differently, and cause major problems in converting programs that run on one machine to run on an other even though they both use "BASIC". Line 1380 loads the move variables. The move operation inside the quadrant is performed half a sector at a time because later on, we will be dealing with integer sector values. Y1 is set to the S1 co-ordinate (plus half a sector), X1 is similarly set to the S2 co-ordinate. Y is set to an angle in radians by using a conversion constant. If you are mathematically inclined, remember that the game uses directions as compass positions. They have to be converted to an angle in order to compute the movement of the ship. BASIC contains built in trigonometric functions that operate on angles represented in radians not in degrees. Conversion factors exist. X and Y are set to the vector of the desired direction expressed along the row and column directions. If you understand trigonometry you will follow what is happening here. if not, don't worry about it. The loop that actually moves the Enterprise begins in line 1390. It is expressed on the form of a 'FOR/NEXT' loop from zero to the integer of the warp factor multiplied by eight (number of sectors horizontally or vertically in a quadrant). This loop thus moves the Enterprise up to the edge of the quadrant if the warp factor was greater than one. If it was less than one, the ship will move the correct number of sectors within the quadrant. It may also go over the edge. For each sector, the temporary position co-ordinates are then (Y1 and X1) updated. These co- ordinates are then converted to integers as two more temporary variables (Y2 and X2) so that they can be used to test the contents of the Sector array S(X,Y). Line 1400 first tests to see if the Enterprise has moved out of the quadrant. Remember that the Enterprise will be outside the quadrant if either Y2 or X2 are less than 0 or greater than 7. If any of them are, the program flow is skipped forward to line 1490. Line 1410 uses the 'ON' statement to test the state of the sector that the Enterprise has been moved to. The correspondence between the contents of the sector and the 'GOTO' is as follows SECTOR GOTO LINE 1 1480 2 1420 3 1480 4 1440 5 1450. If we remember the convention used to set up the contents of the sector, and the letters used to represent them we can generate the following Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 11 STARTREK THE COMPUTER PROGRAM SECTOR CONTENTS LETTER GOTO LINE 1 BLANK . 1480 2 STAR * 1420 3 ENTERPRISE E 1480 4 KLINGON K 1440 5 STARBASE B 1450. Thus the 'ON' statement directs the program to process the move as a function of what is in the sector. If there is a star in the sector, the value of S(X2,Y2) will be 2 and the program picks up at line 1420 which first displays a warning message "STAR DEAD AHEAD". If there are no starbases in the quadrant, there is then a random probability of 40% that a gravitational anomaly has been intercepted as the ship came to close to the star, and a space warp is entered. This is achieved in BASIC by the statement 'IF RND(Z)>.6 AND B=0 THEN 1640' which directs the program to branch forward to line 1640 if a random number is greater than 0.6 and the value of B (the number of starbases in the quadrant) is zero. If the Enterprise does not go into a Space Warp, the program continues at line 1430 (the next line number in sequence by default). An "EMERGENCY ENGINE SHUT DOWN" message is displayed, The engines are then damaged by adding 0.5 stardates to the estimated repair time. This is done by the 'D(0)=D(0)+.5' statement which adds 0.5 to whatever value is stored in the element of the damage control array associated with the engines (ie. D(0) ). The subroutine beginning at line 1780 is then invoked to back the Enterprise up one sector to the last unoccupied sector and lastly, the program is advanced to line 1720. The collision with the Klingon is catered for in line 1440. The cursor is advanced one line by the 'PRINT' statement. A warning message is then displayed by the 'PRINT "STAND BY FOR COLLISION WITH KLINGON" 'statement. The backing up subroutine of line 1780 is then invoked. The subroutine starting at line 110 is called. Remember that when the Enterprise collides with a Klingon, it suffers damage to the on board sub-system closest to the point of collision. Since there is no way to establish which way the Enterprise is facing, the random damage function is used to simulate the event. When all this is done, the program counter is advanced to line 1720. Line 1450 takes care of the situation wherein there is a collision with a Starbase. For the sake of variety the order of the events is changed. Thus the backing up subroutine of line 1780 is invoked first. The message is displayed second, and lastly if there are Klingons in the quadrant, a sarcastic message is displayed and the program counter is advanced to line 1720 as usual. Thus if there are Klingons in the quadrant, the Enterprise cannot dock at a Starbase by colliding with it. If there are no Klingons in the quadrant, the program picks up at Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 12 STARTREK THE COMPUTER PROGRAM line 1460, which displays a warning message. Line 1470 then uses a 'GOTO' statement to advance the program counter to line 1720. There is real no reason why line 1460 could not have read 1460 PRINT "ENTERPRISE CAUGHT IN TRACTOR BEAM BEFORE COLLISION" : GOTO 1720 The in-sector move loop terminates at line 1480. If the loop is still in process when the loop times out, the Enterprise is still inside the quadrant and must be conditioned accordingly. Look back to line 1410 at this time and consider what happened on the various values of S(I,J) or the contents of the quadrants that the Enterprise passes through as it travels across the quadrant. We stated before that line 1410 uses the 'ON' statement to test the state of the sector that the Enterprise has been moved to. If we remember the convention used to set up the contents of the sector, and the letters used to represent them we can generate the following SECTOR CONTENTS LETTER GOTO LINE 1 BLANK . 1480 2 STAR * 1420 3 ENTERPRISE E 1480 4 KLINGON K 1440 5 STARBASE B 1450. Thus line 1480 is always invoked when the Enterprise passes through a blank or empty quadrant. The condition S(I,J) = 3 should not occur, because if it does, the Enterprise will be passing through a sector that contains itself. There does however have to be an entry in the implied GOTO list of the 'ON' states corresponding to the S(I,J) = 3 condition. The entry chosen here is to advance the program counter to line 1480 as if the Sector was vacant. You could put an error trapping message display here, but that would confuse the player. This way, the program ignores hopefully the condition and passes on to the next sector. The first item in line 1480 is the 'NEXT' statement which increments the loop counter and sets up another iteration of the loop if the loop counter does not time out. If the loop counter does time out, the Enterprise is still inside the same quadrant. The internal co-ordinates (S1 and S2) are then set up, and the value of the sector occupied by the Enterprise is set to 3 by the 'S(Y2,X2)=3' statement. This sets the value of the element in the S(I,J) array to 3 where I = Y2 and J = X2. The last element on the line points the program counter to line 1580 bypassing the section of code which deals with the out-of-sector condition. The out of sector section of the subroutine begins at line 1490 with a REM statement. There is no reason why REM statements cannot be used inside a subroutine as well as at the beginning of one. Use them anytime you wish to remember which line of code does what. Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 13 STARTREK THE COMPUTER PROGRAM Line 1510 tests the new co-ordinates of the starship to see if it inside the Galaxy. Remember that for the Enterprise to be inside the galaxy, the row and column quadrant co-ordinates must lie between 0 and 7. The new values of Q1 and Q2 are thus tested by the now familiar ' IF Q1<0 OR Q1>7 OR Q2<0 OR Q2>7 THEN' statement. If the test is true, namely one or more of the co- ordinates show that the Enterprise is outside the galaxy, then the program counter is advanced to line 1550. Line 1520 contains a REMark to the effect, that the section of the program dealing with the Enterprise taking up a new position inside the Galaxy. The first thing line 1530 does is to test the value of the variable G9 used as a flag to indicate if the previous position of the Enterprise was inside or outside the Galaxy. If the value of G9 was one (Z) then the Enterprise was outside the galaxy and is now inside it. The subroutine starting at line 1760 is invoked which takes care of the events that occur when the Enterprise crosses the Galactic boundary barrier. The value of G9 is then set to zero. Line 1540 then positions the program counter to line 1570. Line 1550 is invoked if the Enterprise is outside the Galaxy. Now, if the Enterprise was previously inside the galaxy, ie the value of G9 is 0, then the boundary crossing subroutine of line 1760 is invoked before setting the value of G9 to one (Z). Note that the value of G9 is only adjusted if it changes. Thus in lines 1530 and 1550, the value of G9 is only changed if the tests pass. The section of the program that introduces a random probability of something happening during the move begins at line 1580. A random integer number is generated by the ' I=INT(RND(Z)*100) ' statement. This is a complex statement made up of the following statements. I = RND(Z) : I = I*100 : I = INT(I). The resultant value of I is then tested to see if it zero or greater than 4. If it is, the program counter is advanced to line 1720, bypassing the random event routines. Note, thus the very low probability of a random event, because given a random value between 0 and 99, a random event only occurs if the value of I (the random number) is either 1 or 2 or 3 or 4. The statements on the line could alternatively have been written as I=INT(RND(Z)*100)+Z : IF I>4 THEN 1720. Here the I=0 condition would never arise because the value of I is always set to one by the '+Z' part of the statement. Thus there is no need to test for the I=0 condition in the second statement. Both versions of the line are correct and work. Each one however will have a different execution speed. In practice the actual difference is so small that it can be ignored. Line 1590 tests the value of the G9 flag. If it is set (ie G9 = 1), then the program counter is advanced to line 1680. Of the four random events that occur during a move operation, only one is beneficial to the player. The sections of the program Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 14 STARTREK THE COMPUTER PROGRAM serving that one, begin at line 1680. LIne 1590 thus inhibits the harmful random events from occurring while the Enterprise is outside the galaxy. From line 1600 on, the Enterprise is inside the Galaxy. A 'PRINT' statement is invoked to move the display cursor down one line. Then a statement tests the quadrant to see if it contains a starbase. If it does, the random events are once more by- passed by the statement 'IF B>0 THEN 1720'. Allowing a harmful event to occur when the player is crawling back to a starbase with a badly damaged ship, constitutes cruel and unusual punishment. Allowing Mr. Spok to effect a repair when the starbase can do it just as well or even better also serves no purpose. For these reasons the random events are bypasses in this situation. You could argue that if the engines are damaged, Mr. Spok could be allowed to repair them so the ship can get to the base quicker, or if the Short Range Sensors are out, he could be allowed to fix them since the range of the Visual sensors are limited. You may be right, and can readily implement that function by changing the line number following the 'GOTO' from 1720 to 1680. I have taken the stand that if the bad thins are inhibited, the good ones will be as well. The four random events are associated with the following line numbers. 1620 KLINGON SPACE MINE 1640 SPACE WARP 1670 ION STORM 1680 Mr. Spok at work. The choice of which event occurs is made on line 1610 by the statement 'ON I GOTO 1620,1640,1670,1680' which sets the program counter depending on the value of I. Let us now consider the programs associated with each event. Line 1620 kicks off with the first event, namely the Klingon Space Mine. A visual and audible warning message is generated by the statement PRINT CHR$(7);"KLINGON SPACE MINE ". CHR$(7) is the ASCII character used by a standard terminal to sound the bell tone. Try typing PRINT CHR$(7) when in the BASIC command mode to illustrate this fact to yourself. BASIC is in the command mode when you are typing in programs or have broken the execution of a program with a ^C character and are entering values directly to memory. A random value between 0 and 399 for the energy contained in the hit (H) is generated by the 'H=RND(Z)*400' statement. The subroutine starting at line 130 is then invoked to cause some damage to the Enterprise and the last statement on the line tests the state of the End of the Game Flag (F9). If it is greater than zero, the Enterprise was destroyed in the subroutine beginning at line 130. The most likely cause was that the amount of energy in the Space MIne hit was greater than the amount of Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 15 STARTREK THE COMPUTER PROGRAM energy in the shields. That will however be discussed below. If the ship has been destroyed, the program counter is advanced to line 1750 which contains the statement that terminates the subroutine. If the Enterprise is still operational, line 1630 displays a message telling the player how much energy is left in the shields, and then skips the remaining random events part of the sub-routine by advancing the program line counter to line 1720. The 'PRINT' statement here mixes ASCII text and the contents of the variable E1 and uses the semi-colon to format the display. The lines of code implementing the Space Warp function begin at line 1640 by displaying a message telling the player that a space warp has been encountered. The Ion Storm function is contained on line 1670. An audible and visual warning message is generated by the first statement in the line. The nested subroutine at line 110 is then invoked to damage one of the on-board subsystems, and lastly the program counter is advanced to line 1720 bypassing the remainder of the random events. The subroutines associated with the move function begin at line 1760. The first one is a one line subroutine that performs the galactic boundary crossing. The first part of the line displays a message telling the player that the Enterprise is crossing galactic boundary barrier. A nested subroutine starting at line 110 is then invoked and the line terminates with a 'RETURN' statement closing the subroutine. Crossing the barrier at the edge of the galaxy is a traumatic event. The subroutine starting at line 110 will cause one of the on-board sub-systems to be damaged. This is in line with the model of the galaxy as described by the TV. series. Note that line 1760 could also have been written as 1760 PRINT "CROSSING BARRIER at GALACTIC BOUNDARY" : GOTO 110 which does the same job, because the 'RETURN' from the subroutine starting at line 110 would take the program counter back directly to the statement following the one that called the galactic barrier crossing routine. The two options can be demonstrated as follows. The method used in the listing requires two 'RETURN' statements because the subroutines are nested, namely CALLING LINE GOSUB 1760 GOSUB 110 RETURN RETURN the alternative method only uses one 'RETURN' statement because the subroutines are not actually nested, the 'GOTO' statement joins them together as one, as follows. Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 16 STARTREK THE COMPUTER PROGRAM CALLING LINE GOSUB 1760 GOTO 110 RETURN The method used in the program is the more structured version, because it is easy to follow what is happening. The second or alternative technique uses less memory and is marginally faster in execution (fewer instructions are being performed) but is more difficult to follow when searching the listing to figure out what is happening. Both methods however work as well as each other. Line 1780 contains the REMark statement for the single line subroutine of line 1790 which backs the Enterprise up one sector after a collision. The values of S1 and S2 (the in-sector co- ordinates of the starship are reset back to their previous values by subtracting the last increment (Y or X) from the current value at the sector of collision (Y1 or X1) using the statements 'S1=INT(Y1-Y) : S2=INT(X1-X)'. The value of the sector that the Enterprise has backed into represented in the sector array (S(I,J)) by S(S1,S2) is then set to 3, ie. the value that shows that the Enterprise is in the sector, and the 'RETURN' statement at the end of the line closes out the subroutine. The subroutine that performs on board repairs to the starship as time passes begins at line 1800. It can be best described with reference to the flow chart of figure 7.9 The Damage Something flowchart of figure 7.10 can be implemented in BASIC in a number of ways. The method chosen here was listed in figure 7.11. The damage something subroutine begins at line 110 with the usual REMark. Line 120 performs the action. The variable Y is set to a random value between 1 and whatever warp factor was last used (represented by the variable 'W'). The variable X is then set to an integer value equal to one of the damageable on-board sub- system. They are defined as C1-C2, where C1 is the total number of Commands or sub-systems in the game, and C2, the number that cannot be damaged. For example, the VISual sensor cannot be damaged by definition. These two variables are dummy values used to pass the random numbers to the next statement D(Y)=X+D(Y) which adds the time represented by the random number 'Y' to the state of repair of the subsystem represented in the damage control array by the value in the 'Y' th element or d(Y). The damage done message is then displayed by the 'PRINT' statement, and the 'RETURN' instruction terminates both the line and the subroutine. The ENERGYHIT routine can be written in basic as shown in figure 7.12. Delete lines the temporary Move function lines 1605 to 1625 Copyright (c) Joe Kasser 1989 Chapter 7 PAGE 17 STARTREK THE COMPUTER PROGRAM and carefully enter lines 1600 to 2170 and lines 120 to 180. For debug purposes change line 1870 from 1870 I = INT(RND(Z)*100) : IF I = 0 OR I>4 THEN 2020 to 1870 I = INT(RND(Z)*5) : IF I = 0 OR I>4 THEN 2020 changing the 100 to 5 will vastly speed up the occurrences of random events allowing you to test all the functions. Then when you are satisfied with the operation of the random event generator change the line back. Debug the code by executing all possible conditions. See what happens if you try to move at warp 10, or warp 0 as well as legal warp speeds. Try traveling at less than warp one. Do you end up in the right place. Are messages printed out when they should be. What happens when you cross the galactic boundary barrier? Something should get damaged. Does the repair subroutine work correctly? What happens when the Enterprise runs out of Energy or the shields are beaten down to below zero. If you get fed up running out of energy during this debugging phase, stop the program (Control - C) and enter E = 99999999 or E1 = 99999, then continue. Follow the listing and test every branch condition both ways. Make sure that every piece of code on every line is exercised at least once. If you don't have the patience to move around a lot you can cheat and dummy up a quadrant. If for example,you are currently residing at quadrant 3,1, break the program and enter Q(3,1) = 717. This will set up Quadrant 3,1 to seven Klingons, one Starbase and seven stars. Then continue the program and move at warp 1.4 in direction 8, which will move you into the dummied up quadrant. Now move around inside it. Collide with what you like and test what happens when a collision occurs. Debug the routine and then save the program. Copyright (c) Joe Kasser 1989