25
Cape Horn
This is another action game, but one that will appeal more to thinkers, for it simulates the problems of taking a sailing ship east to west around Cape Horn, against the prevailing winds. The title page asks the user to choose a difficulty level from 1 to 6:
Level 1. At this level the wind is steady in both strength and direction and round the Horn is simply a matter of tacking once or twice. |
Level 2. For this level, the wind stays constant in force, but changes direction randomly, veering or backing a few degrees at a time. |
Level 3. Now the wind also changes velocity, from Force 1 on the Beaufort scale to Force 12 (hurricane). |
Level 4. As above, but the Antarctic pack ice encroaches on the sea lane a little, reducing the space for manoeuvre. |
Level 5. As above, but more so. |
Level 6. As above, but in addition icebergs are scattered randomly. |
After the user has given his or her choice of difficulty level, a very brief message on the lines of the explanations above is given to remind him of what to expect. Pressing RETURN moves the program on.
The screen clears and in its place is given a map of Cape Horn from about 49 degrees South to just above the South Shetland Islands, and from 67 West to 77 West, taking in the Falkland Islands. The map is of course only a representation, with the main channel of the Straits of Magellan indicated. The west coast here is a maze of small islands and no attempt has been made to indicate this.
On the mainland two compass roses are shown. One indicates the wind direction and the other the ship's course. There is a numeric indication of wind strength, but for the sake of simplicity the ship's speed is constant.
The ship appears as a small flashing dot somewhere north of the Falklands and the player's task is to manoeuvre it to the upper left of the screen and off the edge. The program will not allow the dot to disappear off right or left, and if it is brought up against these edges it will stay there. On the other hand, if the ship is taken off the bottom of the screen, it is assumed lost in the pack ice.
The player has only two controls, the P and S keys (short for Port and Starboard). All other keys are ignored. Note that port and starboard apply when facing forward on the ship, so that if the ship's course is south, port is on the player's right as he views the screen, whereas if the ship is going north, port is on the player's left. To operate, simply hold down the key for as long as desired. Course adjustments are in increments of 10 degrees.
The wind compass-rose indicator shows the direction of the wind in the same way that a burgee (a long narrow flag) would; by indicating the compass direction to which the wind is blowing. It used to be said that a finely rigged ship could sail within a few degrees of the wind on either tack, but of course as the wind rose, conditions on board would become more and more intolerable and almost suicidal. In high winds, reaching (or sailing at 90 degrees to the wind) would also be dangerous because of the possibility of being swamped by the sea, while in gales or hurricanes ships could do little but run before the wind.
These conditions have been simplified for the game in the following way. (a) Where the wind strength is 8 or less, the ship can be steered to within 45 degrees of the wind. (b) For a wind strength of 9, 90 degrees is the closest that one may reach. (c) For a strength of 10 or 11, the ship must run before the wind, with a 10 degree latitude. (d) With a wind strength of 12 the latitude is reduced to 5 degrees (see the diagram).
The mean strength of the wind is 6, with variations between 12 and 2. If - or when - it does to 2 or less, watch out! It will return a moment later with increased force and from a totally different location. Getting your ship round the Horn is not easy!
The program will not allow you to sail closer to the wind than specified, but there are problems. Normally, while sailing close to the wind, if one wished to proceed on the other tack one would turn the bows through the eye of the wind, swing the boom over and proceed. Since in this game the wind can change direction, it is possible that while sailing close-hauled, one suddenly finds that one has changed tack unwittingly. This is a natural result of the above: the wind has changed a few degrees, forcing the computer to change the ship's heading. As with any new simulation, it's all quite logical when you get to know it.
The initial conditions are established in lines 110 to 130, with the wind strength = 6, direction = 80, desired course = 170 and the ship's position randomly determined within certain limits. PROCSETCOURSE determines the ship's actual course (as distinct from desired) and then the map is drawn in PROCMAP. It does this with a judicious mix of DRAWing and PLOTting from DATA statements, drawing a series of various triangles north to south, adding triangles for a few islands, and then drawing the Magellan Straits as another series of triangles from west to east. Calls to PROCCIRC draw the compass roses. They are labelled and then the indicator needles are drawn. Finally, PROCMAP draws in a jagged series of triangles to represent icebergs, if the difficulty level requires it.
Back at line 150, a call to PROCSEA sets in train a continuing sound of crashing waves and howling wind. These are both interesting; the former because of the interesting shape of the ENVELOPE, and the fact that the driving channel 1 is not sounded. That is to say, the ENVELOPE affects channel 1 silently, but in turn it affects the noise channel 0. Channels 2 and 3 are slightly off-key with each other - and out of synchronisation with channel 1 - so the perceived tone has that mournful hollow sound one associates with wind.
In the game loop, at each pass the wind is adjusted for strength and direction, and if the strength jumps abruptly (line 250), a brief beep warns the user. Line 330 calls PROCSETCOURSE, which is a very complex procedure that adjusts the vessel's actual course, bearing in mind the wind direction and strength, and desired course. Readers are warned to copy this procedure very carefully, as it is naturally the very heart of the program and the slightest error will affect the correct operation of the program.
Line 350 adjusts the compass-rose pointers and then lines 400 to 430 calculate the ship's new position. Line 470 checks the colour of the point on the screen, calling PROCDONE if necessary. This procedure tells the user what has happened to his ship, or congratulates him on winning.
If the game is not over, line 560 accepts the user's input and adjusts the desired course or not as appropriate.
Variables
LVL% | Difficulty level |
WIND% | Wind direction |
DESCS% | Desired course, 0 to 360 |
SX% | X co-ordinate of ship's position |
SY% | Y co-ordinate of ship's position |
T% | Turns since last wind change |
STR | Wind strength |
W% | Wind direction - copy |
S% | Wind strength - copy |
C% | Copy of COURSE% |
COURSE% | Current ship's heading, 0 to 360 |
NX% | Ship's next X co-ordinate |
NY% | Ship's next Y co-ordinate |
CX%, CY% | Looking further ahead |
Q% | Colour of next point |
I% | Player's input |
G% | Dummy |
D% | Course deviation allowed |
F% | Course deviation desired |
D1%, D2% | Permitted window |
10 MODE7:PROCTITLE("CAPE HORN")
20 PRINT'';"Difficulty 1-6? ";
30 REPEAT:LVL%=GET-48
40 UNTIL LVL%>=1 AND LVL%<=6:PRINTLVL%
50 PRINTTAB(0,13);:ONLVL%GOTO60,70,80,90,90,100
60 PRINT"Wind steady throughout.":GOTO110
70 PRINT"Wind changing in direction.":GOTO110
80 PRINT"Wind increasing/decreasing, changing.":GOTO110
90 PRINT"Ice pack encroaching on sea lane.":GOTO110
100 PRINT"Watch out for icebergs!"
110 WIND%=80:DESCS%=170:SX%=800+RND(400)
120 SY%=800+RND(200):T%=0:STR=6
140 PROCSETCOURSE
150 PROCRET:MODE1:PROCMAP:PROCSEA
160 VDU26,5:MOVESX%,SY%:PRINT"."
170 VDU19,3,8,0,0,0
180
190 REM - Game loop
200
210 W%=WIND%:S%=STR
220 IFLVL%>=2WIND%=WIND%+(RND(3)-2)*4
230 T%=T%+1:IF LVL%<3 OR T%<5 GOTO330
240 T%=0:IFSTR>2 GOTO260
250 STR=RND(6)+6:PROCWARN:WIND%=RND(360):GOTO290
260 IF RND(1)<=(0.95-LVL%/60) GOTO280
270 STR=STR+RND(8):PROCWARN:GOTO290
280 IFSTR<7 STR=STR+RND(3)-2 ELSE STR=STR-1
290 IFSTR>12 STR=10
300
310 REM - ADJUST DISPLAY
320
330 C%=COURSE%:PROCSETCOURSE
340 IFW%=WIND%GOTO360
350 PROCPT(450,650,W%):PROCPT(450,650,WIND%)
360 IFC%=COURSE%GOTO380
370 PROCPT(450,900,C%):PROCPT(450,900,COURSE%)
380 VDU26:IF S%=STR GOTO400
390 MOVE570,720:PRINT;S%:MOVE570,720:PRINT;INT(STR)
400 NX%=SX%+SIN(RAD(COURSE%))*6
410 CX%=SX%+SIN(RAD(COURSE%))*12
420 CY%=SY%+COS(RAD(COURSE%))*12
430 NY%=SY%+COS(RAD(COURSE%))*6
440
450 REM - CHECK FOR END
460
470 Q%=POINT(CX%+12,CY%-24):IF Q%=0 GOTO520
480 PROCDONE:IF FLAG%=0 GOTO560
490 MODE7:PROCDBL(0,5,131,Q$):Q%=INKEY(100)
500 *FX15,0
510 END
520 VDU26:MOVESX%,SY%:PRINT"."
530 MOVENX%,NY%:PRINT".":SX%=NX%:SY%=NY%
540
550 REM - PLAYER'S ADJUSTMENT
560 I%=INKEY(0):*FX15,1
570 IF I%=80 DESCS%=(DESCS%+350)MOD360:GOTO590
580 IFI%=83 DESCS%=(DESCS%+10)MOD360
590 G%=INKEY(100):GOTO210
600
610 REM - PROCEDURES BEGIN
620
630 DEFPROCSETCOURSE
640 LOCALD1%,D2%,F%
650 IFSTR<=8D%=135:GOTO670
660 IFSTR=9D%=90ELSEIFSTR=10D%=45ELSED%=15
670 F%=ABS(DESCS%-WIND%)
680 D1%=360-F%:IF D1%<F% F%=D1%
690 IF F%<D% COURSE%=DESCS%:GOTO800
700 IFSTR<=8GOTO740
710 IFABS(DESCS%-D1%)<ABS(DESCS%-D2%)COURSE%=WIND%+D%:GOTO730
720 COURSE%=WIND%-D%
730 GOTO800
740 IFI%<>80 AND I%<>83 GOTO780
750 IFI%=80COURSE%=(WIND%+F%-5)MOD360:GOTO800
760 IFI%=83COURSE%=(WIND%-F%+365)MOD360
770 GOTO800
780 IF RND(1)>.5 I%=80 ELSE I%=83
790 GOTO670
800 DESCS%=COURSE%
810 ENDPROC
820
830 DEFPROCTITLE(X$)
840 PRINTCHR$132;STRING$(19,"Oo")
850 PROCDBL((36-LEN(X$))/2,4,131,X$)
860 PRINTCHR$132;STRING$(19,"Oo")
870 ENDPROC
880
890 DEFPROCDBL(X%,Y%,C%,X$)
900 PRINTTAB(X%,Y%);CHR$141;CHR$C%;X$
910 PRINTTAB(X%,Y%+1);CHR$141;CHR$C%;X$:ENDPROC
920
930 DEFPROCRET
940 PRINTTAB(5,19);CHR$131;"Press";
950 PRINTCHR$132;CHR$157;CHR$129;"RETURN ";CHR$156;
960 G$=GET$:ENDPROC
970
980 DEFPROCMAP
990 VDU19,0,132,0,0,0,16:GCOL0,2
1000 MOVE800,1023:MOVE230,1023
1010 FORY=950TO300STEP-50:READA,B
1020 PLOT85,A,Y:PLOT85,B,Y
1030 NEXT
1040 PLOT85,700,270:MOVE870,320:MOVE900,300
1050 PLOT85,940,300:MOVE1100,640:MOVE1200,640
1060 PLOT85,1130,600:PLOT85,1110,550
1070 PLOT85,1100,570:MOVE1160,560
1080 MOVE1210,640:PLOT85,1260,600
1090 GCOL0,0:MOVE320,520:MOVE320,500
1100 FOR I%=340TO680STEP20:READJ%:PLOT85,I%,J%:NEXT
1110 MOVE520,400:MOVE620,400:PLOT85,600,440
1120 PLOT85,540,460:MOVE540,480:PLOT85,600,500:PLOT85,660,520
1130 GCOL0,0:VDU5
1140 PROCCIRC(450,900):PROCCIRC(450,650)
1150 VDU26:MOVE 560,950:PRINT"Course"
1160 MOVE 530,760:PRINT;"Wind"
1170 GCOL4,0:MOVE 570,720:PRINT;INT(STR)
1180 PROCPT(450,900,COURSE%):PROCPT(450,650,WIND%)
1190 IFLVL%<4 ENDPROC
1200 VDU26:GCOL0,2:MOVE0,0
1210 FORX%=0TO1279STEP10:PLOT85,X%,RND(50):NEXT
1220 IFLVL%<5 GOTO1300
1230 MOVE0,50:MOVE0,100
1240 FORX%=0TO1279STEP10:PLOT85,X%,RND(70)+50:NEXT
1250 IFLVL%<6 GOTO1300
1260 FORF%=1 TO RND(8)+12
1270 VDU29,RND(1279);RND(150)+100;
1280 MOVE0,0:MOVE0,0
1290 FORG%=1TORND(10):PLOT85,G%*10,RND(50):NEXT:NEXT
1300 GCOL4,0:ENDPROC
1310
1320 DATA810,230,800,230,780,250,720,240,700,250,690
1330 DATA270,620,280,620,290,620,310,670,340,670,370
1340 DATA700,400,760,500,860,600,510,500,500,470,480
1350 DATA460,470,420,420,400,416,400,500,500,500,500,540,480
1360
1370 DEFPROCCIRC(I%,J%)
1380 VDU29,I%;J%;:MOVE100,0
1390 FORP=0TORAD360STEPRAD15
1400 X%=100*COSP:Y%=100*SINP
1410 PLOT5,X%,Y%:NEXT
1420 FORP=0TORAD360STEPRAD45
1430 X%=80*COSP:Y%=80*SINP
1440 MOVEX%,Y%
1450 MOVE 100*COS(P-RAD22),100*SIN(P-RAD22)
1460 PLOT85,100*COS(P+RAD22),100*SIN(P+RAD22)
1470 NEXT:ENDPROC
1480
1490 DEFPROCPT(I%,J%,P%)
1500 VDU29,I%;J%;
1510 MOVE80*SIN(RADP%),80*COS(RADP%):DRAW0,0:ENDPROC
1520
1530 DEFPROCDONE
1540 FLAG%=0:IFQ%<>-1GOTO1580
1550 IF SY%<50 Q$="Lost in the Antarctic ice!":GOTO1630
1560 IF(SY%>200 AND X%>300)OR(SX%<12 AND SY%>900)ENDPROC
1570 Q$="You win!":FLAG%=1:ENDPROC
1580 IFSX%>1000Q$="Wrecked on the Falkland Islands!":GOTO1630
1590 IFSY%<300 Q$="Struck an ice floe!":GOTO1630
1600 IF SY%<500 Q$="Wrecked on Tierra del Fuego!":GOTO1630
1610 IFSX%<500 Q$="Wrecked on the coast of chile!":GOTO1630
1620 Q$="Wrecked on the coast of Argentina!"
1630 FLAG%=-1:ENDPROC
1640
1650 DEFPROCSEA
1660 ENVELOPE1,4,2,-2,-1,255,100,255,0,0,0,0,0,0
1670 ENVELOPE2,6,1,-1,0,80,80,20,12,-27,0,-12,50,50
1680 ENVELOPE3,6,1,-1,0,80,80,20,12,-27,0,-12,50,50
1690 SOUND1,1,255,255:SOUND0,-12,7,255
1700 SOUND2,2,20,255:SOUND3,3,54,255
1710 ENDPROC
1720
1730 DEFPROCWARN
1740 *FX15,0
1750 VDU7:SOUND1,,1,255,255:SOUND0,-12,7,255
1760 SOUND2,2,20,255:SOUND3,3,54,255:ENDPROC