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
STRWind 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