Graphical Golf

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Game

Graphical Golf is a full 18-hole golf simulation that renders a bird’s-eye view of each hole using color attributes and user-defined graphics to represent terrain features including rough, fairway, bunkers, water hazards, trees, the green, the pin, and the tee. Players select from a set of clubs (driver through 9-iron, with iron alternatives that allow percentage-swing input for accuracy), input a shot angle in degrees, and the program applies randomized dispersion scaled by handicap. Terrain landing detection is performed via the ATTR function, which reads the color attributes of screen cells to determine whether the ball has landed on fairway, rough, water, a bunker, or trees, each carrying different club restrictions and distance coefficients. A separate putting phase uses a scrolling graphical display with a simulated green speed variable and distance-from-pin tracking, rolling the ball incrementally across the screen. The program supports either a fixed 18-hole standard course (stored in DATA at line 4620) or a seeded random course generator producing up to 65,535 distinct layouts, with a handicap adjustment system that lowers the player’s handicap based on net score at the end of the round.


Program Structure

The program is organized as a main loop (lines 10–130) iterating over 18 holes, with all major logic delegated to subroutines. The top-level flow is:

  1. Initialization: GO SUB 150 — sets up UDGs, course data, and handicap.
  2. Per-hole display: GO SUB 630 — draws rough, fairway, water, green, trees, bunkers, and tee.
  3. Shot play: GO SUB 1490 — club/angle input loop until ball reaches the green.
  4. Putting: GO SUB 2430 — separate graphical putting phase.
  5. Scoring: GO SUB 3060 — stores score, comments, and optionally displays a scorecard.
  6. End of round: GO SUB 3520 — final summary, handicap adjustment, play-again prompt.

User-Defined Graphics

Seven UDGs (A through G) are defined at startup by reading 56 bytes from DATA at line 4510 and POKEing them into USR "[UDG-A]" onwards. The comment at line 4580 maps each UDG to its terrain role:

UDGTerrain
ARough
BBunker
CPin flag
DWater
ETree
FDivot marker (ball flash)
GGolf ball (putting display)

The rough string r$ is prebuilt at line 530–550 as 32 repetitions of UDG-A, used to fill screen rows efficiently with a single PRINT per row.

Terrain Detection via ATTR

The central technique for determining what the ball lands on is reading the screen attribute at the ball’s row/column with ATTR (vp,hp) (lines 1880–2260). Each terrain type is assigned a distinct PAPER/INK combination when drawn, so the attribute byte uniquely identifies the surface. The constants defined at lines 570–590 map terrain names to their attribute values:

VariableValueTerrain
rough38Rough (PAPER 4, INK 6)
water47Water (PAPER 5, INK 7)
fairway6Fairway (PAPER 0, INK 6)
green4Green (PAPER 0, INK 4)

Bunker (attribute 39, PAPER 4 INK 7) and trees (attribute 32, PAPER 4 INK 0) are detected by their literal values at lines 2080 and 2180.

Shot Calculation

Club selection uses a coded numbering system: woods are 1–4, irons are 11–19 (standard) or 21–29 (percentage-swing variants). Lines 1780–1800 normalize all club codes to an effective integer 1–16 by subtracting offsets. The displacement formulas at lines 1810–1820 compute horizontal and vertical components:

  • hs = INT((ci*(12+INT(RND*3))+38)*ps*COS(as)*rc/20+.5)
  • vs = INT((ci*(12+INT(RND*3))+38)*ps*SIN(as)*rc/20+.5)

Here ci is the normalized club power (1–16), ps is the percentage swing (1.0 or a user fraction), as is the angle in radians, and rc is a terrain distance coefficient reduced by rough, bunkers, or trees. The random term INT(RND*3) adds natural variation. Angle dispersion based on handicap is applied at line 1700: a random offset up to ±(22+ha) degrees is added before converting to radians.

Course Generation

The standard course uses DATA at line 4620 providing length and par for all 18 holes. The random course generator (lines 320–380) produces hole lengths in the range 140–550 yards using INT(RND+411)+140 — note this expression is equivalent to INT(RND*1)+551 only approximately; RND+411 gives a value in [411,412), so INT always yields 411, meaning l(h) is always fixed at 551. This is almost certainly a bug: the intended expression was likely INT(RND*411)+140, which would give the described range of 140–550. Par is then derived from length thresholds: par 3 for ≤240 yards, par 4 for 241–449, par 5 for ≥450. A re-roll condition at line 360 discards non-par-4 holes with 60% probability, biasing the course toward par 4s.

Putting Phase

On reaching the green, a separate full-screen putting display is drawn (lines 2530–2720), showing a stylized hole graphic with a flagstick. Distance from pin dp is computed as a Euclidean pixel distance (line 2440) scaled to feet. A green speed variable tg (2=slow, 3=medium, 4=fast) is randomly selected. The player inputs a putt strength 1–30; each unit advances the ball by 1+INT(RND*tg) feet per iteration (line 2870), accumulating until the sign of dp reverses or the ball falls within 1 unit of the hole. The ball rolls graphically across the screen using hbp (horizontal ball position) mapped from dp at line 2900, with per-step PAUSE scaled by green speed and distance.

Scorecard Display

The scorecard (lines 3390–3500) uses color-coded TAB printing: scores below par are shown with PAPER 2 (red), on par with PAPER 7, and over par with PAPER 1 (blue). The instruction text at line 4450 incorrectly states “below par in red, over par in blue” — the actual colors are red for under par and blue for over par, which matches the code but is the reverse of traditional scorecard convention.

Input Validation

A shared string legality checker at lines 3830–3860 (GO SUB 3830) validates that the string d$ contains only digits, a decimal point, or a minus sign, setting flag OK accordingly. This is called before every VAL d$ operation throughout the program to prevent errors from non-numeric input. An additional allowance at line 1670 replaces a leading “j” or “J” with “-” as a keyboard convenience for entering negative angles.

Notable Bugs and Anomalies

  • Line 320: INT(RND+411)+140 always produces 551 (as noted above); the intended expression was almost certainly INT(RND*411)+140.
  • Line 2130: In the bunker lie calculation for bker=1, the code writes LET cm=26+(RND>.5) instead of LET mc=..., leaving mc unchanged — the maximum club restriction is silently skipped for an “O.K.” bunker lie.
  • Line 3590: ts-hs subtracts hs (horizontal shot displacement from the last shot) rather than the handicap variable ha, producing a meaningless “NET” shot count.
  • Lines 3770/3780: The play-again prompt uses LET A$= INKEY$ (uppercase A$) for the PAUSE loop but then compares a$ (lowercase) at line 3780, which on this platform are the same variable — no bug in practice, but inconsistent casing throughout the scoring section.
  • Line 4520 and others in the DATA block use the variable h (which holds the current hole number) as a data value, meaning the UDG patterns change depending on which hole was last played when the DATA is READ at initialization. This is almost certainly unintentional — the DATA values were likely meant to be specific byte constants.

Key BASIC Idioms

  • PAUSE NOT PI is used throughout as a zero-duration pause (since NOT PI = 0) immediately followed by INKEY$ to wait for a keypress without blocking — the standard efficient keypress idiom.
  • VAL d$ with GO SUB 3830 guard is the consistent pattern for all numeric input.
  • Boolean arithmetic appears at line 2220: ("VERY BAD" AND TRS=0)+("BAD" AND TRS=1)+("LUCKY" AND TRS=2) selects a string by condition, a common Spectrum BASIC technique for conditional string output without IF branches.
  • Line 1180: VAL "i- INT ((4+ RND*3)*(tre>.5))+ INT ((4+ RND*3)*(tre <=.5))" uses string-form VAL to evaluate an expression containing a live variable, a technique that allows dynamic expression construction.

Image Gallery

Source Code

   10 REM "GOLF"   Main Loop
   20 GO SUB 150
   30 FOR h=1 TO 18
   40 RANDOMIZE :LET sh=0:LET a$="T":LET pap=3:LET ink=7
   50 GO SUB 630:REM DISPLAY
   60 GO SUB 1490:REM THE SHOT
   70 PAUSE 75
   80 GO SUB 2430:REM ON GREEN
   90 GO SUB 3060:REM KEEP SCORE
  100 NEXT h
  110 GO SUB 3520:REM END DISP.
  120 IF playagain THEN GO TO 20
  130 STOP 
  140 REM INITIALIZE SUBROUTINE   
  150 GO SUB 490:REM INIT.VARS.
  160 GO SUB 3880:REM INSTRUCTS.
  170 PRINT "Random or normal course?(r/n)"
  180 PAUSE NOT PI:LET a$= INKEY$
  190 IF a$ <>"n" AND a$ <>"r" THEN GO TO 180
  200 REM Par,length,score
  210 DIM p(18):DIM l(18):DIM s(18)
  220 IF a$="r" THEN GO TO 270
  230 RESTORE 4620
  240 FOR h=1 TO 18
  250 READ l(h):READ p(h):NEXT h
  260 GO TO 440:REM HANDICAP
  270 PRINT "Course no? ENTER if not bothered"
  280 INPUT  LINE d$
  290 IF d$="" THEN RANDOMIZE :GO TO 320
  300 GO SUB 3830:IF NOT OK THEN GO SUB 610:GO TO 280
  310 RANDOMIZE (VAL d$)
  320 LET par=0
  330 FOR h=1 TO 18
  340 LET l(h)= INT (RND+411)+140
  350 LET p(h)=3+(l(h)>240)+(l(h)>449)
  360 IF p(h) <>4 AND RND<.6 THEN GO TO 340
  370 LET par=par+p(h)
  380 NEXT h:PRINT "par=";par
  390 PRINT "O.K?"
  400 PAUSE NOT PI:LET a$= INKEY$
  410 IF a$ <>"y" AND a$ <>"n" THEN GO TO 400
  420 IF a$="n" THEN GO TO 270
  430 REM    GET HANDICAP
  440 PRINT '"**INPUT**your handicap,(0-25)"
  450 INPUT  LINE d$:GO SUB 3830:IF NOT OK THEN GO SUB 610:GO TO 450
  460 LET ha= VAL d$:IF ha<0 OR ha>28 THEN GO TO 460
  470 RETURN 
  480 REM    REST OF VAR.DEC.
  490 RESTORE 4510
  500 FOR i=0 TO 55
  510 READ h:POKE USR "[UDG-A]"+i,h:NEXT i
  520 REM    ROUGH,SPACES
  530 LET r$=""
  540 FOR i=1 TO 32
  550 LET r$=r$+"[UDG-A]":NEXT i
  560 REM   VAL$ FOR ATTRIBUTES
  570 LET rough=38:LET water=47
  580 LET fairway=6:LET green=4
  590 LET rc=1:LET mc=0
  600 LET ts=mc:LET pr=ts:RETURN 
  610 BEEP .4,20:BEEP .2,20:RETURN 
  620 REM   DRAW DISPLAY
  630 GO SUB 750 :REM   ROUGH 
  640 GO SUB 810:REM  FAIRWAYS
  650 GO SUB 920:REM   WATER
  660 GO SUB 1010:REM GREEN+PIN
  670 GO SUB 1120:REM   TREES
  680 GO SUB 1240:REM  BUNKERS
  690 GO SUB 1450:REM    TEE
  700 RETURN 
  710 REM    CLEAR BOT. 2 LINES
  720 PAPER 7
  730 PRINT AT 20,0,,,,:RETURN 
  740 REM      ROUGH
  750 PAPER 4:INK 6:CLS 
  760 FOR i=1 TO 19
  770 PRINT r$:NEXT i
  780 PRINT TAB 4; PAPER 7; INK 1;"Hole ";h;",Length ";l(h);",Par ";p(h)
  790 GO SUB 720:RETURN 
  800 REM   DRAW FAIRWAY
  810 PAPER NOT PI:INK 6:LET vp=3+ INT (RND*13)
  820 LET vp1=vp:LET hp= INT (l(h)/20)
  830 FOR a=1 TO hp
  840 FOR b=-1-(RND>.5) TO 1+(RND>.5)
  850 PRINT AT vp+b,a-1;"█"
  860 NEXT b
  870 LET vp=vp+(RND>.5)-(RND>.5)
  880 LET vp=vp-(vp>16)+(vp<2)
  890 NEXT a
  900 LET vp2=vp:RETURN 
  910 REM     WATER
  920 IF RND>.25 THEN RETURN 
  930 PAPER 5:INK 7
  940 LET hp= INT (l(h)/40)
  950 FOR a=0 TO 18
  960 PRINT AT a,hp;"[UDG-D]"
  970 LET hp=hp+(RND>.5)-(RND>.5)
  980 LET hp=hp-(hp >= INT (l(h)/20-2))+(hp<2)
  990 NEXT a:RETURN 
 1000 REM   GREEN & PIN
 1010 PAPER NOT PI:INK 4:LET vp=vp2
 1020 LET hp= INT (l(h)/20)-1
 1030 FOR a=-1-(RND>.5) TO 1+ INT (RND>.5)
 1040 FOR b=-1-(RND>.5) TO 1+ INT (RND>.5)
 1050 PRINT AT vp+b,hp+a;"█"
 1060 NEXT b:NEXT a
 1070 REM    PIN
 1080 PRINT PAPER 7; INK NOT PI; AT vp,hp;"[UDG-C]"
 1090 LET hpf=hp:LET vpf=vp
 1100 RETURN 
 1110 REM     TREES
 1120 IF RND>.9 THEN RETURN 
 1130 RESTORE 4600:FOR k=1 TO 3+(RND>.7)+(RND>.7): READ not:LET i=0
 1140 IF ATTR (i,vp)=fairway OR ATTR (i,vp)=green THEN GO TO 1170:REM   PLACE TREES
 1150 LET i=i+1:IF i=19 THEN GO TO 1220:REM   NO TREES
 1160 GO TO 1140
 1170 LET i=i+2
 1180 FOR j=1 TO not:LET tre= RND
 1190 LET i1= VAL "i- INT ((4+ RND*3)*(tre>.5))+ INT ((4+ RND*3)*(tre <=.5))"
 1200 IF ATTR (i1,vp)=rough THEN PRINT AT i1,vp; PAPER 4; INK NOT PI;"[UDG-E]"
 1210 NEXT j
 1220 NEXT k:RETURN 
 1230 REM     BUNKERS
 1240 PAPER 4:INK 7:LET vp=vpf
 1250 LET zz=-4+ INT (RND*9):LET yy= ATTR (vp+zz,hp)
 1260 IF yy <>rough AND yy <>fairway THEN GO TO 1250
 1270 PRINT AT vp+zz,hp;"[UDG-B]"
 1280 FOR a=1 TO 2+(RND*3):LET xx=-3+ INT (RND*7)
 1290 LET zz=-3- INT (RND*3):LET xx=-3+ INT (RND*7)
 1300 LET yy= ATTR (vp+xx,hp+zz)
 1310 IF yy <>rough AND yy <>fairway THEN GO TO 1290
 1320 PRINT AT vp+xx,hp+zz;"[UDG-B]":NEXT a
 1330 IF p(h)<4 THEN RETURN 
 1340 LET hp=10:GO SUB 1380
 1350 IF p(h)<5 THEN RETURN 
 1360 LET hp=17:GO SUB 1380
 1370 RETURN 
 1380 FOR a=1 TO 2+(RND>.4)
 1390 LET zz=hp+ INT (RND*4):FOR b=0 TO 18
 1400 IF ATTR (b,zz) <>fairway THEN GO TO 1420
 1410 PRINT AT b,zz;"[UDG-B]":GO TO 1430
 1420 NEXT b
 1430 NEXT a:RETURN 
 1440 REM      TEE
 1450 LET vp=vp1:LET hp=0
 1460 PAPER PI:INK 7
 1470 PRINT AT vp,hp;"[UDG-T]":RETURN  
 1480 REM   PLAY ONTO THE GREEN   
 1490 GO SUB 1580:REM CLUB,ANGLE
 1500 LET ps=1:IF ci >=21 THEN GO SUB 1730:REM % swing
 1510 IF sh >=1 THEN GO SUB 2400:REM   RESTORE DIVOT
 1520 GO SUB 1780:REM CALC.DISPL
 1530 LET sh=sh+1:PRINT PAPER 7; INK NOT PI; AT 0,0; CHR$ (48+sh)
 1540 LET rc=1:LET mc=0
 1550 GO TO 1850:REM LAND.POS+
 1560 RETURN 
 1570 REM GET CLUB & ANGLE
 1580 PAPER 7:INK 1
 1590 PRINT AT 21,0;"Input club(";
 1600 IF mc=0 THEN PRINT "1-4,11-19,21-29)"
 1610 IF mc=11 THEN PRINT "11-19,21-29)    "
 1620 IF mc=29 THEN PRINT "29)"
 1630 IF mc>20 AND mc <>29  THEN PRINT mc;"-29)"
 1640 INPUT  LINE d$:GO SUB 3830:IF NOT OK  THEN GO SUB 610:GO TO 1640
 1650 LET ci= VAL d$:IF (ci<1 OR ci>29) OR (ci>4 AND ci<11) OR ci=20 OR ci<mc OR ci <> INT ci THEN GO TO 1650
 1660 PRINT AT 21,0;"Angle of shot(-180 TO 180)"
 1670 INPUT  LINE d$:IF d$ <>"" THEN IF d$(1)="j" OR d$(1)="J" THEN LET d$(1)="-"
 1680 GO SUB 3830:IF NOT OK  THEN GO SUB 610:GO TO 1670
 1690 LET as= VAL d$:IF as<-180 OR as>180 THEN GO TO 1690
 1700 LET as=as+ INT (RND*(22+ha))- INT (RND*(22+ha))
 1710 LET as=as* PI/180
 1720 PRINT #0;as:RETURN 
 1730 PRINT AT 21,0;"Input percentage swing(10-100)"
 1740 INPUT  LINE d$:GO SUB 3830:IF NOT OK  THEN GO SUB 610:GO TO 1740
 1750 LET ps= VAL d$:IF ps<10 OR ps>100 THEN GO TO 1750
 1760 LET ps=ps/100:RETURN       
 1770 REM     CALC.DISPL'MT
 1780 IF ci>20 THEN LET ci=ci-10
 1790 IF ci>10 THEN LET ci=ci-6
 1800 LET ci=16-ci
 1810 LET hs= INT ((ci*(12+ INT (RND*3))+38)*ps* COS (as)*rc/20+.5)
 1820 LET vs= INT ((ci*(12+ INT (RND*3))+38)*ps* SIN (as)*rc/20+.5)
 1830 RETURN 
 1840 REM   LANDING POS.ONWARDS
 1850 GO SUB 720:PAPER 7:INK 2
 1860 IF hp+hs>31 OR hp+hs<0 OR vp+vs>18 OR vp+vs<0 THEN GO TO 1950:REM 0.0.B.
 1870 LET hp=hp+hs:LET vp=vp+vs
 1880 LET yy= ATTR (vp,hp)
 1890 IF yy <>water THEN GO TO 1970
 1900 REM   IN WATER
 1910 PRINT AT 20,0;"SPLASH-IN WATER,PENALTY 1 STROKE"
 1920 LET b$=a$:LET pap1=pap:LET ink1=ink:LET a$="[UDG-D]":LET pap=5:LET ink=7:GO SUB 2330:GO SUB 2400
 1930 LET sh=sh+1:LET hp=hp-hs:LET vp=vp-vs:LET a$=b$:LET pap=pap1:LET ink=ink1:GO SUB 2330:GO TO 1490
 1940 REM   OUT OF BOUNDS
 1950 PRINT AT 20,0;"OUT OF BOUNDS,PENALTY 1 STROKE"
 1960 LET sh=sh+1:GO SUB 2330:GO TO 1490
 1970 IF yy <>green THEN GO TO 2010
 1980 REM   ON THE GREEN
 1990 PRINT AT 20,0;"ON THE GREEN IN ";sh;" SHOT(S)"
 2000 LET a$="█":LET pap=0:LET ink=4:GO SUB 2330:RETURN 
 2010 IF yy <>rough THEN GO TO 2080
 2020 REM     IN THE ROUGH
 2030 LET rgh= RND
 2040 LET mc=11:PRINT AT 20,0;"YOU'RE IN ";
 2050 IF rgh>.5 THEN PRINT "HEAVY ROUGH":LET rc=.5+ RND/4
 2060 IF rgh <=.5 THEN PRINT "LIGHT ROUGH":LET rc=.75+ RND/4
 2070 LET a$="[UDG-A]":LET pap=4:LET ink=6:GO SUB 2330:GO TO 1490
 2080 IF yy <>39 THEN GO TO 2180
 2090 REM    BUNKERED
 2100 PRINT AT 20,0;"BUNKERED-LIE IS ";
 2110 LET bker= INT (RND*3)
 2120 IF bker=0 THEN LET mc=24+(RND>.5):PRINT "GOOD";
 2130 IF bker=1 THEN LET cm=26+(RND>.5):PRINT "O.K.";
 2140 IF bker=2 THEN LET mc=28+(RND>.5):PRINT "BAD";
 2150 PRINT "-MAX CLUB ";mc
 2160 LET rc=.7-bker*.1+ RND/5
 2170 LET a$="[UDG-B]":LET pap=4:LET ink=7:GO SUB 2330:GO TO 1490
 2180 IF yy <>32 THEN GO TO 2260
 2190 REM    IN TREES
 2200 PRINT AT 20,0;"IN TREES-";
 2210 LET trs= INT (RND*3):LET rc=.5+ RND/4
 2220 PRINT ("VERY BAD" AND TRS=0)+("BAD" AND TRS=1)+("LUCKY" AND TRS=2);
 2230 LET mc=29-trs -(RND>.8):PRINT " LIE MAX. CLUB ";mc
 2240 LET a$="[UDG-E]":LET pap=4:LET ink=0:GO SUB 2330:GO TO 1490
 2250 REM     ON FAIRWAY
 2260 IF yy <>fairway THEN GO TO 2300
 2270 PRINT  AT 20,0;"YOU ARE ON THE FAIRWAY"
 2280 LET a$="█":LET pap=0:LET ink=6:GO SUB 2330:GO TO 1490
 2290 REM     ON FLAG
 2300 PRINT AT 20,0;"ON THE GREEN IN ";sh;"-AND CLOSE."
 2310 LET a$="[UDG-C]":LET pap=7:LET ink=0:GO SUB 2330:RETURN 
 2320 REM   FLASH BALL ON & OFF
 2330 FOR i=1 TO 6
 2340 PAPER pap:INK ink
 2350 PRINT AT vp,hp;a$:PAUSE 15
 2360 PAPER 7:INK 2
 2370 PRINT AT vp,hp;"[UDG-F]":PAUSE 15
 2380 NEXT i:RETURN 
 2390 REM    RESTORE DIVOT
 2400 PAPER pap:INK ink
 2410 PRINT AT vp,hp;a$:RETURN   
 2420 REM     PUTTING
 2430 GO SUB 2530:REM   DISPLAY
 2440 LET dp= INT (SQR ((hpf-hp)*(hpf-hp)+(vpf-vp)*(vpf-vp))*15+1+ RND*15)
 2450 LET hbp=19:GO SUB 2900
 2460 IF ABS dp <=1 THEN GO TO 2730:REM     IN HOLE
 2470 PRINT AT 9,19-hbp; PAPER 5; INK 7;"[UDG-G]"
 2480 GO SUB 2780:REM PUTT IN PUTT
 2490 GO SUB 2850:REM  NEW DIST.
 2500 GO SUB 2900:REM BALL ROLL
 2510 GO TO 2460
 2520 REM DRAW PUTTING DISPLAY
 2530 PAPER 5:CLS 
 2540 PAPER 7:FOR i=12 TO 21:PRINT AT i,0,,:NEXT i:PAPER 5
 2550 IF h <=9 THEN LET ink=1
 2560 IF h >=10 THEN LET ink=2
 2570 PRINT AT 0,17; PAPER 5; INK ink;"▄▄▄▄"
 2580 PRINT TAB 17; PAPER 5; INK ink;" ███▐"
 2590 PRINT TAB 17; PAPER 5; INK ink;"▀▀▀▐"
 2600 INK ink:LET msig= INT (h/10)
 2610 LET lsig=h-msig*10
 2620 IF msig <>0 THEN PRINT AT 1,18; PAPER 7;"";msig
 2630 PRINT AT 1,19; PAPER 7;"";lsig
 2640 INK NOT PI:PAPER 5
 2650 FOR i=0 TO 6:PRINT AT 3+i,20;"▐":NEXT i
 2660 FOR i=1 TO 2:PRINT INK 4;"███████████████████"; INK NOT PI;"██"; INK 4;"███████████"
 2670 NEXT i
 2680 PAPER 7:INK NOT PI:PRINT '"  -FEET-FROM THE PIN "
 2690 LET tg=2+ INT (RND*3)
 2700 PAPER 5:INK NOT PI:PRINT AT 0,0;
 2710 PRINT ("slow" AND tg=2)+("medium" AND tg=3)+("fast" AND tg=4);
 2720 REM BALL DROPS IN HOLE
 2730 PRINT AT 9,19; PAPER 5;" ":PRINT AT 10,19; PAPER NOT PI; INK 7;"[UDG-G]":PAUSE 10
 2740 PRINT AT 10,19; PAPER NOT PI;" "
 2750 PRINT AT 11,19; PAPER NOT PI; INK 7;"[UDG-G]":PAUSE 100
 2760 RETURN 
 2770 REM  GET PUTT STRENGTH
 2780 PAPER 7:INK NOT PI:PRINT AT 13,0; ABS dp
 2790 PRINT AT 15,0;"input your putt strength (1-30)"
 2800 INPUT  LINE d$:GO SUB 3830:IF NOT OK THEN GO SUB 610:GO TO 2800
 2810 LET ps= VAL d$:IF ps<1 OR ps>30 THEN GO TO 2810
 2820 PRINT AT 15,0,,:PRINT AT 13,0;"  "
 2830 LET sh=sh+1:RETURN 
 2840 REM GETNEW POS. FROM PIN
 2850 IF dp<0 THEN LET dir=1
 2860 IF dp>0 THEN LET dir=-1
 2870 FOR i=1 TO ps:LET dp=dp+dir*(1+ INT (RND*tg)):NEXT i
 2880 RETURN 
 2890 REM   ROLL THE BALL
 2900 LET nhbp= INT ((dp+1)/3)
 2910 LET nhbp=nhbp-(nhbp=-1)
 2920 IF nhbp<-12 THEN LET nhbp=-12
 2930 IF nhbp>19 THEN LET nhbp=19
 2940 IF nhbp >=hbp THEN LET step=1
 2950 IF nhbp<hbp THEN LET step=-1
 2960 LET pause=10+5*(tg=4)-5*(tg=2)- ABS (nhbp-hbp):IF pause-1< ABS hbp-30 THEN LET pause= ABS hbp-29
 2970 FOR i=hbp TO nhbp STEP step
 2980 PRINT AT 9,19-i; PAPER 5; INK 7;"[UDG-G]"
 2990 PAUSE pause+30- ABS i
 3000 IF i=-1 THEN PRINT AT 9,20; PAPER 5; INK NOT PI;"▐"
 3010 IF i <>-1 THEN PRINT AT 9,19-i; PAPER 5;"  "
 3020 NEXT i
 3030 LET hbp=nhbp:RETURN 
 3040 REM   KEEP SCORE
 3050 :
 3060 GO SUB 3110:REM KEEP SCORE
 3070 GO SUB 3140:REM   COMMENT
 3080 GO SUB 3340:REM  SCORECARD
 3090 RETURN 
 3100 REM   STORE CARD
 3110 LET s(h)=sh:LET ts=ts+sh
 3120 LET pr=pr+p(h):RETURN 
 3130 REM   COMMENT ON SCORE
 3140 PAPER 7:INK PI:CLS 
 3150 PRINT "YOU HOLED OUT IN ";sh;" SHOTS"
 3160 LET zz=sh-p(h)
 3170 PRINT 
 3180 IF zz=-3 AND p(h) <>4 THEN PRINT ;"EXCELLENT,AN ALBATROSS"
 3190 IF (zz=-3 AND p(h)=4) OR (zz=-2 AND p(h)=3) THEN PRINT "UNBELIEVABLE YOU MADE A HOLE IN ONE"
 3200 IF zz=-2 AND p(h) <>3 THEN PRINT "GREAT YOU MADE AN EAGLE!!"
 3210 IF zz=-1 THEN PRINT "WUNDERBAR,YOU MADE A BIRDIE"
 3220 IF zz=0 THEN PRINT "WELL DONE, A PAR"
 3230 IF zz=1 THEN PRINT "HMMMMM, A BOGEY"
 3240 IF zz=2 THEN PRINT "OOOOPS, LORRAINE, A DOUBLE BOGEY"
 3250 IF zz>2 THEN PRINT "KEEP YOUR HEAD DOWN"
 3260 PRINT :PRINT 
 3270 LET zz=ts-pr
 3280 PRINT "YOU ARE NOW ";
 3290 IF zz<0 THEN PRINT ABS zz;" UNDER ";
 3300 IF zz=0 THEN PRINT " LEVEL ";
 3310 IF zz>0 THEN PRINT zz;"OVER ";
 3320 PRINT "PAR(GROSS)":RETURN 
 3330 REM     SCORECARD
 3340 PRINT "DO YOU WISH TO SEE A SCORECARD?"
 3350 PAUSE NOT PI:LET A$= INKEY$
 3360 IF a$ <>"y" AND a$ <>"n" THEN GO TO 3350
 3370 CLS :IF a$="n" THEN RETURN 
 3380 REM   PRINT SCORECARD
 3390 PRINT TAB 12; PAPER 5; INK 1;"SCORECARD"
 3400 PRINT PAPER 7; INK 2;"   HOLE    DIST.   PAR    SHOTS "
 3410 FOR i=1 TO 18
 3420 PRINT PAPER 7; INK 4; TAB 4;i; TAB 12; TAB 20;p(i);
 3430 IF s(i)=0 THEN GO TO 3470
 3440 IF s(i)-p(i)<0 THEN PRINT TAB 28; PAPER 2; INK 7;s(i)
 3450 IF s(i)-p(i)=0 THEN PRINT TAB 28; PAPER 7; INK NOT PI;s(i)
 3460 IF s(i)-p(i)>0 THEN PRINT TAB 28; PAPER 1; INK 7;s(i)
 3470 NEXT i
 3480 PRINT TAB 19; PAPER 7; INK 3;pr; TAB 27;ts
 3490 PRINT PAPER 5; INK 1;"ANY KEY TO CONTINUE"
 3500 PAUSE NOT PI:CLS :RETURN  
 3510 REM    END OF ROUND
 3520 GO SUB 3570:REM  FINAL SCORE
 3530 IF ha>0 THEN GO SUB 3680:REM   HANDICAP
 3540 GO SUB 3760:REM PLAY AGAIN?
 3550 RETURN 
 3560 REM FINAL SCORE & COMMENT
 3570 GO SUB 3390:PAPER 7:INK NOT PI
 3580 PRINT "YOU TOOK ";ts;" SHOTS"
 3590 PRINT "(NET ";ts-hs;" SHOTS)"
 3600 LET zz=ts-pr-ha
 3610 PRINT 
 3620 PRINT "THAT WAS "
 3630 IF zz<0 THEN PRINT ABS zz;" UNDER";
 3640 IF zz=0 THEN PRINT "LEVAL ";
 3650 IF zz>0 THEN PRINT zz;"OVER ";
 3660 PRINT "PAR(NET)":PRINT :RETURN 
 3670 REM     HANDICAP CHANGE
 3680 IF zz<0 THEN LET pd= INT (ABS (zz/2)+.5)*(zz<0):IF pd>ha THEN LET pd=ha
 3690 IF zz >=0 THEN LET pd=0
 3700 PRINT "AS A RESULT:"
 3710 PRINT "YOUR HANDICAP "
 3720 IF pd=0 THEN PRINT "REMAINS AT ";ha
 3730 IF pd>0 THEN PRINT "IS DOWN ";pd;" SHOT(S)","(TO ";ha-pd;"SHOT(S))"
 3740 PRINT :RETURN 
 3750 REM ANOTHER GAME??
 3760 PRINT "LORRAINE, ARE READY FOR ANOTHER ROUND???"
 3770 PAUSE NOT PI:LET A$= INKEY$
 3780 IF A$ <>"y" AND a$ <>"n" THEN GO TO 3770
 3790 IF a$="y" THEN LET playagain=1
 3800 IF a$="n" THEN LET playagain=0
 3810 RETURN 
 3820 REM string legality check
 3830 LET OK=1:IF d$="" THEN LET OK=0:RETURN 
 3840 FOR i=1 TO LEN d$
 3850 IF NOT (d$(i) >="0" AND d$(i) <="9" OR d$(i)="." OR d$(i)="-") THEN LET OK=0
 3860 NEXT i:RETURN 
 3870 REM INSTRUCTION SUBROUTINE  
 3880 LET DP=0:LET H=7:GO SUB 2530:LET HBP=19:GO SUB 2900:GO SUB 2730:REM   init.displ.
 3890 PAPER 2:INK 7:PRINT AT 14,0,,
 3900 PRINT AT 15,0;"      GRAPHICAL GOLF            "
 3910 PRINT ,,
 3920 PRINT "DO YOU NEED INSTRUCTION?",
 3930 PAUSE NOT PI:LET a$= INKEY$
 3940 IF a$ <>"y" AND a$ <>"n" THEN GO TO 3930
 3950 IF a$="n" THEN CLS :RETURN 
 3960 PAPER 7:INK NOT PI:CLS :PRINT "THIS IS A FULL 18 HOLE (NO 19th)GOLF SIMULATION, AT THE START,   YOU WILL BE ASKED WHETHER YOU   PREFER A STANDARD OR RANDOM     COURSE"
 3970 PRINT "THE STANDARD IS CONSIDERED"'"YOUR 'HOME' COURSE (BASIS FOR   YOUR HANDICAP"
 3980 PRINT "RANDOM OPTION OFFERS YOU A"'"CHOICE OF 65535 COURSES, INPUT ANUMBER -1 TO 65535. REPLAY IS   POSSIBLE, INPUT SAME NUMBER"
 3990 GO SUB 4490
 4000 PRINT "THE RANDOM COURSE MAY NOT HAVE  PAR 72"''"YOU WILL INPUT YOUR HANDICAP..  BEGINNERS START AT 28, IF YOU   PLAY WELL COMPUTER WILL LOWER   YOUR HANDICAP AT END OF   ROUND"
 4010 GO SUB 4490:LET d$="          "
 4020 PRINT "PLAY ONTO THE GREEN"''"COMPUTER WILL ALLOW A BIRDSEYE  VIEW OF  THE HOLE...THE VARIOUS SYMBOLS  REPRESENT:"
 4030 PRINT 'd$; PAPER 4; INK 6;"[UDG-A]";:PRINT "  -ROUGH"
 4040 PRINT 'd$; PAPER 6;" ";:PRINT "  -FAIRWAY"
 4050 PRINT 'd$; PAPER 4;" ";:PRINT "  -GREEN"
 4060 PRINT 'd$; PAPER 4; INK 7;"[UDG-B]";:PRINT "  -BUNKER"
 4070 PRINT 'd$; PAPER 4; INK NOT PI;"[UDG-E]";:PRINT "  -A TREE "
 4080 PRINT 'd$; PAPER 5; INK 7;"[UDG-D]";:PRINT "  -WATER  "
 4090 PRINT 'd$; PAPER 7; INK NOT PI;"[UDG-C]";:PRINT "  -THE Pin"
 4100 PRINT 'd$; PAPER PI; INK 7;"[UDG-T]";:PRINT "  -THE TEE"
 4110 GO SUB 4490
 4120 PRINT "PLAY CONSISTS OF SELECTING A    CLUB, AN ANGLE,AN OPTIONAL SWING"''"THE FOLLOWING ARE YOUR CLUBS AND APPROXIMATE YARDAGES"
 4130 PRINT '"CLUB        NAME       YARDAGES"
 4140 PRINT "DRIVER","1      0    233"  
 4150 PRINT "2-WOOD","2           220" 
 4160 PRINT "3-WOOD","3           207" 
 4170 PRINT "4-WOOD","4           197" 
 4180 PRINT "1-IRON        11/21         181"
 4190 PRINT "2-IRON        12/22         168"  
 4200 PRINT "3-IRON        13/23         155"
 4210 PRINT "4-IRON        14/24         142"
 4220 PRINT "5-IRON        15/25         129"
 4230 PRINT "6-IRON        16/26         116"
 4240 PRINT "7-IRON        17/27         103"
 4250 PRINT "8-IRON        18/28          90"
 4260 PRINT "9-IRON        19/29          77"  
 4270 GO SUB 4490
 4280 PRINT "THERE ARE TWO CHOICES FOR IRONS,UNDER 'NAME'--OPTION 2 ALLOWS   YOU TO INPUT A PERCENTAGE SWING FOR GREATER ACCURACY"
 4290 PRINT "YOU ARE ASKED TO INPUT AN ANGLE OF SHOT BASED ON FOLLOWING CHART"
 4300 PRINT ' TAB 12;"-90"; TAB 8;"-135 ! -45   - FOR UP"
 4310 PRINT TAB 12;"\!/"; TAB 8;"180--G-- 0"
 4320 PRINT TAB 12;"/!\"; TAB 9;"135 ! 45    +FOR DOWN"
 4330 PRINT TAB 13;"90"
 4340 PRINT '"(ANY INTERMEDIATE ANGLE IS      ALLOWED ,eg -22.5.)":GO SUB 4490
 4350 PRINT "PLAY ON THE GREEN"
 4360 PRINT '"PUTTING CONSISTS OF TYPING A"'"PUTT STRENGTH DEPENDANT UPON"'"THE GREEN SPEED + DISTANCE FROM CUP.   USE FOLLOWING APPROX."'"DISTANCES LISTED BELOW"
 4370 PRINT '"     SLOW GREEN...=1.5 FT/NO."
 4380 PRINT "     MEDIUM GREEN...=2 FT/NO."
 4390 PRINT "     FAST GREEN...=2.5 FT/NO."
 4400 PRINT '"eg, A 10' PUTT ON A MED.GREEN   WOULD REQUIRE A STRENGTH OF 5 ."
 4410 PRINT "eg, 20' ON A FAST GREEN WOULD   NEED 8"
 4420 GO SUB 4490
 4430 PRINT "MORE DETAILS BELOW"
 4440 PRINT "1)SCALE ON THE BIRDS EYE VIEW IS 20 YDS TO 1 SQUARE"
 4450 PRINT "2)OPTION TO SEE SCORECARD AFTER EACH HOLE, BELOW PAR IN RED,"'"OVER PAR IN BLUE"
 4460 PRINT "3)LEGAL CLUB CHOICE IS MADE ON  CLUB PROMPT"
 4470 PRINT #0;"PRESS ANY KEY TO BEGIN"
 4480 PAUSE NOT PI:CLS :RETURN 
 4490 PRINT #0;"PRESS ANY KEY TO CONTINUE ":PAUSE NOT PI:CLS :RETURN 
 4500 REM   DATA FOR UD GRAF.
 4510 DATA 255,0,255,0,255,0,255,0
 4520 DATA 56,124,254,127,63,h,126,56
 4530 DATA 8,24,56,8,h,h,h,28
 4540 DATA 16,32,16,8,4,2,4,8
 4550 DATA 8,28,h,62,127,h,8,h
 4560 DATA 0,h,h,24,h,0,h,h
 4570 DATA 0,h,60,126,h,h,h,60
 4580 REM a=[UDG-A] b=[UDG-B] c=[UDG-C] d=[UDG-D] e=[UDG-E] f=[UDG-F] g=[UDG-G]
 4590 REM DATA for tree placment
 4600 DATA 10,4,11,8,12,12,13,8,24,4
 4610 REM lengths of holes,etc
 4620 DATA 361,4,389,4,206,3,500,5,408,4,359,4,424,4,388,4,196,3,408,4,560,5,132,3,357,4,294,4,475,5,375,4,180,3,550,5
 4630 SAVE "Golf" LINE 10

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.