
An answer to every exercise in the course, each of them run on the machine. Yours does not have to match. If it does what the exercise asked, it is right.
Try the exercise first. A solution you have read is a great deal less use than one you have fought for.
Where an answer changes the game, only the lines added or changed are shown, numbered to fit the listing as it stands at the end of that section. Type them in on top of your saved game and they take their places.
3.1
PRINT "GAVIN"
prints GAVIN. Any name will do, as long as it is inside the quotes.
3.2
PRINT 2+2
PRINT "2+2"
4
2+2
Outside quotes BASIC works it out, and shows the number with a space in front. Inside quotes it copies.
3.3
PRINT "TWO";"WORDS"
PRINT 10/4
TWOWORDS
2.5
The semicolon joins the two with nothing in between. Division gives a fraction when there is one.
4.1
10 PRINT "GAVIN"
20 PRINT 7
30 PRINT 7*2
RUN
GAVIN
7
14
Ready
4.2
15 PRINT "MY FAVOURITE NUMBER IS"
LIST
10 PRINT "GAVIN"
15 PRINT "MY FAVOURITE NUMBER IS"
20 PRINT 7
30 PRINT 7*2
Ready
RUN
GAVIN
MY FAVOURITE NUMBER IS
7
14
Ready
Any number from 11 to 19 would have done. BASIC files it between 10 and 20.
4.3
5 PRINT "ONE"
6 PRINT "TWO"
7 PRINT "THREE"
8 PRINT "FOUR"
9 PRINT "FIVE"
It runs perfectly well, ONE to FIVE. What you have lost is room: there is no whole number between 5 and 6, so nothing can ever go between those lines without renumbering.
5.1 Type AUTO, and after each number BASIC offers, the rest of the line:
AUTO
10 PRINT "THE MOUSE"
20 PRINT "SAW"
30 PRINT "THE FAT CAT"
40 PRINT "AND RAN"
When it offers 50, press CTRL-X to clear it, then ENTER. LIST shows the four lines and no others.
5.2
RENUM 1000,10
LIST
1000 PRINT "THE MOUSE"
1010 PRINT "SAW"
1020 PRINT "THE FAT CAT"
1030 PRINT "AND RAN"
Ready
5.3 Press CTRL-L to clear the screen, then LIST. Line 1020 is three rows above the cursor. Press CTRL-K three times, then CTRL-D eighteen times, which puts the cursor on the F of FAT. Type BIG and press ENTER, then CTRL-L again. RUN now prints THE BIG CAT on its third line. Then:
DEL 1010,1020
LIST
1000 PRINT "THE MOUSE"
1030 PRINT "AND RAN"
Ready
6.1
10 PRINT "THIS IS GAVIN'S"
20 PRINT "AND IT CAME OFF THE DISC"
SAVE "GAVIN"
DIR
DIR shows it at the top, with a space where the disc's own files have a *:
Drive 0
:*XBAS .COM : GAVIN .XBS
Restart the Einstein, XBAS, and then:
LIST
Ready
LOAD "GAVIN"
Ready
LIST
10 PRINT "THIS IS GAVIN'S"
20 PRINT "AND IT CAME OFF THE DISC"
Ready
RUN
THIS IS GAVIN'S
AND IT CAME OFF THE DISC
Ready
The first LIST shows nothing: the program came back from the disc.
6.2 LOAD "DEMO", then LIST. The listing stops when the screen is full and waits: press SPACE for the next fifteen lines, or ESC to stop.
A line you can read already is line 370, PRINT on its own, which prints an empty line (S3). Something you would like explained might be line 340, DRAW 19,0 TO 0,0 TO 0,191 TO 50,191, which is S18, or the RST at the start of line 220, which S34 explains.
6.3 Press CAPS LOCK so that the name comes out in small letters, save, and press CAPS LOCK again:
10 PRINT "SMALL LETTERS"
SAVE "small"
Ready
NEW
Ready
LOAD "SMALL"
No File Error
Ready
LOAD "small"
Ready
LIST
10 PRINT "SMALL LETTERS"
Ready
DIR shows it as : small .XBS, in small letters. To BASIC, small and SMALL are two different names.
7.1
PRINT 3.14159*5*5
PRINT 2*3.14159*5
78.5397
31.4159
7.2
PRINT (50-32)*5/9
prints 10. Without the brackets, 50-32*5/9 would take away 32 times 5 over 9 from 50, which is not what you want.
7.3
PRINT 17 MOD 5
PRINT SQR(2)
PRINT SQR(-2)
2
1.41421
Qty Error
Qty Error means a number BASIC cannot do anything with. A negative number has no square root.
8.1
10 AGE=12
20 PRINT "AGE NOW:";AGE
30 PRINT "IN TEN YEARS:";AGE+10
AGE NOW: 12
IN TEN YEARS: 22
8.2
10 MX=10
20 MX=MX+4
30 PRINT "MOUSE AT";MX
40 MX=MX+4
50 PRINT "MOUSE AT";MX
60 MX=MX+4
70 PRINT "MOUSE AT";MX
MOUSE AT 14
MOUSE AT 18
MOUSE AT 22
S12's FOR will do this in three lines.
8.3
TIMER=7
Ready
PRINT TIMER
7
Ready
LENGTH=7
Syntax Error
Ready
MYSCORE=7
Syntax Error
Ready
PRINT MYSCORE
0
Ready
TIMER is yours. LENGTH begins with LEN, from S9. MYSCORE has OR in the middle: BASIC reads MYSC OR E, which is why PRINT MYSCORE gives 0 instead of an error.
9.1 The obvious name does not work:
FIRST$="GAVIN"
Syntax Error
FIRST$ has a keyword in it - RST, which S34 meets - so it fails S8's check. NAME$ passes it:
10 NAME$="GAVIN"
20 SNAME$="WATSON"
30 PRINT NAME$+" "+SNAME$
40 PRINT LEN(NAME$+SNAME$)
GAVIN WATSON
11
Line 40 joins the two names without the space, so only the letters are counted.
9.2
10 W$="MOUSETRAP"
20 PRINT LEFT$(W$,1)
30 PRINT MID$(W$,LEN(W$),1)
M
P
LEN(W$) is the position of the last letter, whatever the word. RIGHT$(W$,1) would do line 30's job too.
9.3 MID$("MOUSETRAP",1,5) is MOUSE: five letters starting from the first. RIGHT$("MOUSETRAP",4) is TRAP.
10.1
10 INPUT "FIRST NUMBER? ";A
20 INPUT "SECOND NUMBER? ";B
30 PRINT "TOTAL:";A+B
40 PRINT "DIFFERENCE:";A-B
50 PRINT "PRODUCT:";A*B
FIRST NUMBER? 12
SECOND NUMBER? 5
TOTAL: 17
DIFFERENCE: 7
PRODUCT: 60
10.2
10 INPUT "WHAT IS YOUR NAME? ";NAME$
20 PRINT NAME$
30 PRINT MUL$("-",LEN(NAME$))
WHAT IS YOUR NAME? GAVIN
GAVIN
-----
10.3
10 PRINT "PRESS A KEY"
20 K=INCH
30 PRINT "KEY: ";CHR$(K)
40 PRINT "CODE:";K
50 PRINT "FIVE ON: ";CHR$(K+5)
Pressing A:
PRESS A KEY
KEY: A
CODE: 65
FIVE ON: F
11.1
10 INPUT "A NUMBER? ";N
20 IF N>0 THEN PRINT "POSITIVE"
30 IF N<0 THEN PRINT "NEGATIVE"
40 IF N=0 THEN PRINT "ZERO"
Run three times, answering 5, -3 and 0, it prints POSITIVE, NEGATIVE and ZERO.
11.2
10 INPUT "PASSWORD? ";P$
20 IF P$="CHEESE" THEN PRINT "IN":ELSE PRINT "OUT"
CHEESE gets IN and CAT gets OUT. For two passwords:
20 IF P$="CHEESE" OR P$="MOUSE" THEN PRINT "IN":ELSE PRINT "OUT"
Now MOUSE gets IN as well. Mind the colon before ELSE.
11.3
10 INPUT "HOW OLD ARE YOU? ";AGE
20 IF AGE<1 OR AGE>120 THEN PRINT "THAT CAN'T BE RIGHT"
30 IF AGE>=18 AND AGE<=120 THEN PRINT "YOU CAN VOTE"
40 IF AGE>=1 AND AGE<18 THEN PRINT "NOT YET"
HOW OLD ARE YOU? 44
YOU CAN VOTE
HOW OLD ARE YOU? 12
NOT YET
HOW OLD ARE YOU? 150
THAT CAN'T BE RIGHT
HOW OLD ARE YOU? -5
THAT CAN'T BE RIGHT
HOW OLD ARE YOU? FRED
THAT CAN'T BE RIGHT
FRED is not a number, so INPUT makes AGE 0 - which is why line 20 tests for less than 1 rather than less than 0. Each IF has a line of its own, so no answer can get two messages.
12.1
10 FOR I=1 TO 12
20 PRINT 7;"X";I;"=";7*I
30 NEXT I
7 X 1 = 7
7 X 2 = 14
7 X 3 = 21
and so on to 7 X 12 = 84. The spaces come from the numbers.
12.2
10 FOR I=1 TO 20
20 PRINT "*";
30 NEXT I
40 PRINT
50 PRINT MUL$("*",20)
********************
********************
Line 50 says in one line what 10 to 40 take four to say.
12.3
10 FOR R=1 TO 5
20 FOR S=1 TO R
30 PRINT "*";
40 NEXT S
50 PRINT
60 NEXT R
*
**
***
****
*****
The inner loop runs to R, so each row is one longer than the last.
13.1
10 INPUT "A NUMBER FROM 1 TO 10? ";N
20 IF N<1 OR N>10 THEN 10
30 PRINT "THANK YOU:";N
A NUMBER FROM 1 TO 10? 0
A NUMBER FROM 1 TO 10? 15
A NUMBER FROM 1 TO 10? 7
THANK YOU: 7
It needs no KBD line because every time round it stops and waits for you, and you can always end it by typing a number that is in range.
13.2
10 N=0
20 N=N+1
30 IF N MOD 100=0 THEN PRINT N;
40 IF KBD<>0 THEN 60
50 GOTO 20
60 PRINT
70 PRINT "STOPPED AT";N
Held down after five seconds:
100 200 300 400 500 600
STOPPED AT 605
MOD comes before =, so line 30 asks whether the remainder is 0. Let go of the key quickly: one still held when the program stops goes on typing at the prompt.
13.3
10 GOSUB 500
20 PRINT "MOUSE IN A HOLE"
30 GOSUB 500
40 PRINT "BY GAVIN"
50 GOSUB 500
60 END
500 PRINT MUL$("-",30)
510 RETURN
------------------------------
MOUSE IN A HOLE
------------------------------
BY GAVIN
------------------------------
Without the END, the program would run on into line 500 and end with a Return Error.
14.1
10 DIM N(10)
20 FOR I=1 TO 10
30 N(I)=I
40 NEXT I
50 FOR I=10 TO 1 STEP -1
60 PRINT N(I);
70 NEXT I
80 PRINT
prints 10 9 8 7 6 5 4 3 2 1. The array is untouched; only the order it is read in changes.
14.2
10 DIM N(5)
20 FOR I=1 TO 5
30 INPUT "NUMBER? ";N(I)
40 NEXT I
50 BIG=N(1)
60 FOR I=2 TO 5
70 IF N(I)>BIG THEN BIG=N(I)
80 NEXT I
90 PRINT "THE LARGEST WAS";BIG
Answering 4, 19, 7, 12 and 3, it prints THE LARGEST WAS 19. INPUT can put an answer straight into an element of an array.
14.3
10 DIM T(3,3)
20 FOR R=1 TO 3
30 FOR C=1 TO 3
40 T(R,C)=R*C
50 NEXT C
60 NEXT R
70 FOR R=1 TO 3
80 FOR C=1 TO 3
90 PRINT T(R,C);
100 NEXT C
110 PRINT
120 NEXT R
1 2 3
2 4 6
3 6 9
15.1
10 FOR I=1 TO 12
20 READ M$
30 PRINT I;M$
40 NEXT I
50 DATA "JANUARY","FEBRUARY","MARCH","APRIL"
60 DATA "MAY","JUNE","JULY","AUGUST"
70 DATA "SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"
1 JANUARY
2 FEBRUARY
3 MARCH
and so on to 12 DECEMBER.
15.2
10 DIM MARK(5)
20 SUM=0
30 FOR I=1 TO 5
40 READ MARK(I)
50 SUM=SUM+MARK(I)
60 NEXT I
70 PRINT "TOTAL";SUM
80 PRINT "AVERAGE";SUM/5
90 DATA 12,15,9,18,14
TOTAL 68
AVERAGE 13.6
Not TOTAL for the variable: S8's list says why.
15.3
10 DIM C$(3)
20 DIM A$(3)
30 RESTORE 110
40 FOR I=1 TO 3:READ C$(I):NEXT I
50 RESTORE 100
60 FOR I=1 TO 3:READ A$(I):NEXT I
70 FOR I=1 TO 3
80 PRINT C$(I);" ";A$(I)
90 NEXT I
95 END
100 DATA "CAT","MOUSE","DOG"
110 DATA "RED","GREY","BROWN"
RED CAT
GREY MOUSE
BROWN DOG
The colours are read first although their DATA comes second: RESTORE 110 goes straight to them.
16.1
10 SEVENS=0
20 FOR I=1 TO 100
30 D1=RND(6)+1
40 D2=RND(6)+1
50 IF D1+D2=7 THEN SEVENS=SEVENS+1
60 NEXT I
70 PRINT "SEVENS IN 100 THROWS:";SEVENS
Three runs gave 26, 17 and 14. Yours will be different, and different every time.
16.2
10 DIM SAY$(6)
20 FOR I=1 TO 6
30 READ SAY$(I)
40 NEXT I
50 PRINT SAY$(RND(6)+1)
60 DATA "LOOK BEFORE YOU LEAP","MORE HASTE LESS SPEED"
70 DATA "WHEN THE CAT'S AWAY THE MICE WILL PLAY","WASTE NOT WANT NOT"
80 DATA "A STITCH IN TIME SAVES NINE","EVERY CLOUD HAS A SILVER LINING"
Four runs gave LOOK BEFORE YOU LEAP, A STITCH IN TIME SAVES NINE twice, and WASTE NOT WANT NOT. Chance repeats itself sometimes.
16.3
10 SECRET=RND(10)+1
20 INPUT "GUESS A NUMBER 1 TO 10? ";N
30 IF N<SECRET THEN PRINT "TOO LOW"
40 IF N>SECRET THEN PRINT "TOO HIGH"
50 IF N<>SECRET THEN 20
60 PRINT "RIGHT! IT WAS";SECRET
The end of one game:
GUESS A NUMBER 1 TO 10? 3
TOO LOW
GUESS A NUMBER 1 TO 10? 4
TOO LOW
GUESS A NUMBER 1 TO 10? 5
RIGHT! IT WAS 5
Like 13.1, it ends when you answer correctly, so it needs no KBD line.
17.1
10 BCOL 1
20 TCOL 15,1
30 CLS
40 FOR C=0 TO 15
50 TCOL C,1
60 PRINT @2,C+2;"COLOUR";C
70 NEXT C
80 K=INCH
On black, COLOUR 0 and COLOUR 1 cannot be seen at all: 1 is black on black, and 0 is transparent, so the black backdrop shows through the letters. Of the rest, dark blue, 4, is the hardest to read.
17.2
10 BCOL 1
20 TCOL 15,1
30 CLS
40 N$="GAVIN"
50 C=INT((40-LEN(N$))/2)
60 PRINT @C,11;MUL$("-",LEN(N$))
70 PRINT @C,12;N$
80 PRINT @C,13;MUL$("-",LEN(N$))
90 K=INCH
GAVIN lands at column 17 of row 12, with five dashes above and below. Line 50 works out the column, so any name is centred.
17.3
75 PRINT @15,2;"HI 500"
SCORE 0 HI 500 LIVES 3
TCOL 11,1 from line 50 is still in force, so it comes out yellow like the rest of the line.
18.1
10 BCOL 1
20 TCOL 15,1
30 CLS
40 GCOL 15,1
50 DRAW 78,46 TO 178,46 TO 178,146 TO 78,146 TO 78,46
60 K=INCH
The middle of the screen is 128,96. Fifty either way gives 78 to 178 across and 46 to 146 up.
18.2
10 BCOL 1
20 TCOL 15,1
30 CLS
40 GCOL 7,1
50 FOR S=0 TO 4
60 X=20+S*40
70 Y=10+S*25
80 DRAW X,Y TO X+40,Y TO X+40,Y+25
90 NEXT S
100 K=INCH
Each pass draws a tread and the riser at the end of it, starting where the last step finished.
18.3
10 BCOL 1
20 TCOL 15,1
30 CLS
80 GCOL 7,1
90 FOR Y=0 TO 5
100 DRAW 0,Y TO 255,Y
110 NEXT Y
112 FOR Y=0 TO 5
114 DRAW 110,Y TO 140,Y,1
116 NEXT Y
120 K=INCH
The floor has a clean gap from 110 to 140. The ,1 after the second point makes that line rub out instead of draw.
19.1
10 BCOL 1
20 TCOL 15,1
30 CLS
40 GCOL 15,1
50 ELLIPSE 128,40,30,1
60 ELLIPSE 128,90,20,1
70 ELLIPSE 128,124,14,1
80 K=INCH
The ,1 on each makes them round. Each centre is the one below's centre plus the two radii, so the circles just touch.
19.2
10 BCOL 1
20 TCOL 15,1
30 CLS
40 GCOL 7,1
50 FOR N=3 TO 6
60 POLY N,38+(N-3)*60,96,25,1
70 NEXT N
80 K=INCH
Four shapes in a row, all inside circles of the same size. POLY puts the first corner at 3 o'clock, so the triangle points right and the square stands on a corner like a diamond.
19.3
10 BCOL 1
20 TCOL 15,1
30 CLS
40 GCOL 11,1
50 DRAW 40,40 TO 100,40 TO 70,100 TO 40,40
60 FILL 70,60
70 K=INCH
80 DRAW 150,40 TO 179,40
90 DRAW 181,40 TO 210,40 TO 180,100 TO 150,40
100 K=INCH
110 FILL 180,60
120 K=INCH
Press a key after each stage. The first triangle fills solid yellow. The second has one pixel missing from its base, at 180,40, and its fill gets out through it and turns the whole screen yellow.
20.1
10 BCOL 1
20 TCOL 15,1
30 CLS
40 GCOL 7,1
50 ELLIPSE 128,96,40,1
60 FILL 128,96
70 N=0
80 FOR X=0 TO 255
90 IF POINT(X,96)=1 THEN N=N+1
100 NEXT X
110 TCOL 11,1
120 PRINT @0,0;"LIT ON ROW 96:";N
130 K=INCH
prints LIT ON ROW 96: 81 - the width of a circle of radius 40, edge to edge through the middle.
20.2
10 BCOL 1
20 TCOL 15,1
30 CLS
40 GCOL 7,1
50 DRAW 60,40 TO 200,40
60 GCOL 11,1
70 X=128:Y=180
80 PLOT X,Y
90 IF POINT(X,Y-1)<>0 THEN 130
100 DRAW X,Y TO X,Y,1
110 Y=Y-1
120 GOTO 80
130 TCOL 11,1
140 PRINT @0,0;"LANDED AT Y=";Y
150 K=INCH
The dot falls and stops on the line: LANDED AT Y= 41. Line 100 rubs the dot out before it moves, with S18's line type 1 on a line one point long. Line 90 tests for anything but 0, so the dot would stop at the bottom of the screen too, where POINT gives 255.
20.3
10 BCOL 1
20 TCOL 15,1
30 CLS
40 GCOL 7,1
50 DRAW 20,40 TO 110,40 TO 110,46 TO 20,46 TO 20,40
60 FILL 23,43
70 DRAW 150,40 TO 240,40 TO 240,46 TO 150,46 TO 150,40
80 FILL 153,43
90 X=0
100 IF POINT(X,43)=0 THEN X=X+1:GOTO 100
110 IF POINT(X,43)=1 THEN X=X+1:GOTO 110
120 G1=X
130 IF POINT(X,43)=0 THEN X=X+1:GOTO 130
140 G2=X-1
150 TCOL 11,1
160 PRINT @0,0;"THE GAP RUNS FROM X=";G1;" TO X=";G2
170 K=INCH
prints THE GAP RUNS FROM X= 111 TO X= 149. Walk across the empty space, across the first platform, then across the gap. Each loop is S20's falling test turned on its side.
21.1 Add to S21's listing:
25 N=131:GOSUB 900
75 SPRITE 1,124,120,7,131
1200 DATA "...##..."
1210 DATA "..####.."
1220 DATA ".######."
1230 DATA "########"
1240 DATA ".######."
1250 DATA "..####.."
1260 DATA "...##..."
1270 DATA "........"
A cyan gem stands beside the cheese. Line 25 reads the next eight rows of DATA, which are the gem's, because the cheese has already taken the first eight.
21.2
10 BCOL 1:TCOL 15,1:CLS
20 N=130:GOSUB 900
30 N=131:GOSUB 900
40 PRINT @2,4;CHR$(130);" ";CHR$(131)
50 END
with S21's subroutine at 890 to 1010, and:
1100 DATA "........"
1110 DATA "...#...."
1120 DATA "....#..."
1130 DATA "######.."
1140 DATA "....#..."
1150 DATA "...#...."
1160 DATA "........"
1170 DATA "........"
1200 DATA "........"
1210 DATA "..#....."
1220 DATA ".#......"
1230 DATA "######.."
1240 DATA ".#......"
1250 DATA "..#....."
1260 DATA "........"
1270 DATA "........"
Printed, a shape shows only its left six columns, so both arrows are drawn inside those six.
21.3
10 BCOL 1:TCOL 15,1:CLS
20 N=130:GOSUB 900
30 N=131:GOSUB 900
40 PRINT @2,20;"ANY KEY STOPS IT"
100 PRINT @18,10;CHR$(130)
110 FOR D=1 TO 200:NEXT D
120 PRINT @18,10;CHR$(131)
130 FOR D=1 TO 200:NEXT D
140 IF KBD=0 THEN 100
150 END
with the subroutine again, and a beetle with its legs apart, then together:
1100 DATA "........"
1110 DATA "..##...."
1120 DATA ".####..."
1130 DATA ".####..."
1140 DATA "..##...."
1150 DATA ".#..#..."
1160 DATA "#....#.."
1170 DATA "........"
1200 DATA "........"
1210 DATA "..##...."
1220 DATA ".####..."
1230 DATA ".####..."
1240 DATA "..##...."
1250 DATA "..##...."
1260 DATA "..##...."
1270 DATA "........"
The two pictures take turns in the same place, about a quarter of a second each, and the beetle scuttles on the spot. Line 140 is the way out.
22.1 Add to S22's listing:
35 N=136:GOSUB 900
125 SPRITE 1,150,83,8,136
1200 DATA "................","................","................","................"
1210 DATA "..#.....#.......","..##...##.......","..#######.......","..#.##.##......#"
1220 DATA "..#######......#","...#####......#.","....###########.","....###########."
1230 DATA "....###########.","....##.....##...","....##.....##...","....##.....##..."
A red cat with pointed ears and a tail stands on the platform facing the mouse. 136 is the next multiple of four after the mouse's 132, and its feet are on the bottom row, so it stands at the same y as the mouse.
22.2 Change S22's lines 100 and 210, and add four:
100 TCOL 11,1:PRINT @1,1;"Z X LEFT RIGHT I K UP DOWN"
162 IF K=73 THEN MY=MY+4:GOTO 180
164 IF K=75 THEN MY=MY-4:GOTO 180
192 IF MY<16 THEN MY=16
194 IF MY>192 THEN MY=192
210 PRINT @1,3;"STOPPED AT X=";MX;" Y=";MY
I goes up and K down. Held all the way down, the mouse stops with its feet on the bottom row of the screen: STOPPED AT X= 60 Y= 16. At the top, 192 puts its top row on the screen's top row.
22.3
10 BCOL 1:TCOL 15,1:CLS
20 DIM P$(16)
30 N=132:GOSUB 900
40 MAG 2
50 SPRITE OFF
60 TCOL 11,1:PRINT @1,1;"ANY KEY STOPS IT"
70 X=0:DX=3
80 SPRITE 0,X,100,14,132
90 X=X+DX
100 IF X<0 OR X>239 THEN DX=-DX:X=X+DX
110 SPRITE 0,X,100
120 IF KBD=0 THEN 90
130 PRINT @1,3;"STOPPED AT X=";X
140 END
with S22's subroutine and mouse DATA from line 890 on. The mouse crosses the screen, turns at each edge and comes back, until a key is pressed. Line 100 turns it round and takes back the step that went too far.
23.1
720 FOR P=1 TO 4
840 DATA 20,110,40,150,240,75,40,200,115,20,100,150
The other number is the 3 in line 720, which says how many platforms to read. The new one's top, at 156, is still below the text rows.
23.2
780 ELLIPSE 90,47,13,1,0,0,3.15
790 DRAW 77,47 TO 77,45:DRAW 103,47 TO 103,45
The left-hand platform's surface is at 46, so the arch stands at 47, and x=90 puts it near that platform's right-hand end. Two numbers change in line 780, but in line 790 all eight do: both legs move across and down.
23.3
100 SPRITE 1,CX1,CY1,2,136
110 SPRITE 2,CX2,CY2,12,136
Colours 2 and 12 are both dark greens, and on black the two cats look almost the same. Red and light red, 8 and 9, are nearly as bad. A pair is hard to tell apart when the two are close in shade and in brightness.
24.1
152 IF PEEK(&E041) AND 1 THEN MY=MY+3
154 IF PEEK(&E042) AND 1 THEN MY=MY-3
172 IF MY<22 THEN MY=22
174 IF MY>192 THEN MY=192
Line 130 has already called the key reader, so rows 1 and 2 are waiting at &E041 and &E042, and AND 1 keeps the one bit that is I or K. Holding I for ten seconds and then pressing Q, PRINT MX;MY gives 20 192, the top. Holding K brings the mouse back down to the floor, at 22, and no further.
24.2
135 S=6:IF PEEK(&E040) AND 64 THEN S=12
140 IF K=64 THEN MX=MX-S
150 IF K=32 THEN MX=MX+S
S is the size of a step: 6, or 12 while the space bar is down. Held for half a second from the start, X alone took the mouse from 20 to 86, and X with SPACE took it to 152: twice as far.
With KBD in place of the key reader, the loop would begin:
130 K=KBD
140 IF K=90 THEN MX=MX-6
150 IF K=88 THEN MX=MX+6
with 190 IF K=81 THEN 200 ELSE 130 for Q. There is nothing to write for the space bar: K is one key's code, never two. And holding X shows the rest. With the position printed on the score line (24.3), X held for three seconds moved the mouse just one step in the first second, then on to 122. With SPACE held as well, the mouse stopped dead at 128 and stayed there: while two keys are down, KBD reports neither of them.
24.3
185 PRINT @15,2;"X";MX;" ";
SCORE 0 X 239 LIVES 3
The spaces on the end rub out the last digits when the number gets shorter - walked back to the left-hand edge, it reads X 0 with nothing left over - and the semicolon keeps the cursor from moving on to the next line.
25.1
340 IF K=64 THEN VX=-4
341 IF K=32 THEN VX=4
342 MX=MX+VX:IF MX<0 THEN MX=0:VX=0
343 IF MX>239 THEN MX=239:VX=0
The air subroutine starts at line 340, so the two new lines go first, and the old lines 340 and 342 move down to 342 and 343. In the air, Z and X now set the sideways speed; let go, and the mouse keeps going the way it was. Jump straight up from the start and hold X for a moment on the way up: the mouse drifts right and lands on the first platform further along, and PRINT MX;MY gives 48 63. In the unchanged game the same keys land it at 20 63, straight above where it took off.
Steering is easier: a jump that is going wrong can be put right on the way. Without it, every jump is decided before the mouse leaves the ground, and the skill is in choosing where to jump from. Which is more of a game is yours to decide.
25.2
185 PRINT @15,2;"VY";VY;" ";
In a jump from open floor - walk out from under the first platform first - the score line showed VY 13, 11, 9, 7, 5, 3, 1, VY-1, -3, -5, -6, and then VY 0 on landing. The 15 of the take-off never shows: the air subroutine has taken 2 from it on the same pass, before line 185 prints it. It goes down in twos, from 1 straight to -1 at the top of the jump, stops getting faster at -6, and is 0 again on landing. A minus sign takes the place of the space in front of a number, so it reads VY-1.
25.3
346 MY=MY+VY:IF VY<0 THEN 350
348 IF POINT(MX+3,MY-5)=1 OR POINT(MX+10,MY-5)=1 THEN MY=MY-1:VY=0:GOTO 348
349 RETURN
A falling mouse still goes on to the landing at line 350; a rising one now goes to line 348. The mouse's picture has five empty rows above its head, so MY-5 is just above its ears. If that is inside something lit, move the mouse down until it is not, and stop it rising. On the next pass gravity takes over. Tried at the start, under the first platform: the mouse bumps its head and drops back to the floor. After Q, PRINT MX;MY gives 20 22, where before it would have landed on the platform, at 63.
26.1
65 DIM CHX(6),CHY(6),EATEN(6)
400 C=0:FOR I=1 TO 6:IF EATEN(I)=0 AND ABS(MX+8-CHX(I))<10 AND ABS(MY-12-CHY(I))<10 THEN C=I
855 FOR I=1 TO 6
870 DATA 70,6,200,6,90,47,210,82,80,122,130,6
The arrays need room for six (line 65), the search must look at six pieces (400), and the drawing must put out six (855). With the new piece on the floor at 130, walking right from the start to the far edge eats all three floor pieces: SCORE 30.
26.2
420 I=C:EATEN(I)=-1:PTS=PTS+10
422 IF CHY(I)>70 THEN PTS=PTS+10
424 IF CHY(I)>100 THEN PTS=PTS+10
The middle platform's piece is at a height of 82 and the top one's at 122, so the first gets one extra 10 and the second gets two. They are separate lines because a false IF skips the rest of its line. To try it quickly, start the mouse on a platform for a moment - 800 MX=50:MY=138:G=-1:VX=0:VY=0 for the top, 800 MX=160:MY=98:G=-1:VX=0:VY=0 for the middle - and walk right. The top piece scored SCORE 30 and the middle one SCORE 20.
26.3
420 I=C:EATEN(I)=-1:PTS=PTS+10:CL=CL-1
565 PRINT @15,2;"CHEESE";CL;" ";
852 CL=5
867 GOSUB 560
SCORE 0 CHEESE 5 LIVES 3
SCORE 10 CHEESE 4 LIVES 3
Line 867 shows the count as soon as the cheese is out. S8's check on CL first: CL=7, PRINT CL gives 7.
27.1
260 CX2=CX2+D2:IF CX2<=150 OR CX2>=222 THEN D2=-D2:SPRITE 2,CX2,CY2,13,138-D2
820 CX2=170:CY2=98:D2=-4
Four pixels a pass instead of two. The limit changes from 224 to 222 because the cat now moves in fours from 170: 150 is on its way and 224 is not. It would reach 226 before turning, and hang over the edge. Over the same minute of play, the magenta cat turned 46 times to the red cat's 22.
27.2
115 SPRITE 3,CX3,CY3,3,136
265 CX3=CX3+D3:IF CX3<=0 OR CX3>=240 THEN D3=-D3:SPRITE 3,CX3,CY3,3,138-D3
270 SPRITE 1,CX1,CY1:SPRITE 2,CX2,CY2:SPRITE 3,CX3,CY3
825 CX3=120:CY3=22:D3=2
A green cat paces the whole floor, turning at 0 and at 240. The rule cannot be broken: with the mouse and three cats the game has only four sprites, so no line can ever hold a fifth. On the floor the new cat shares its lines with nobody but the mouse anyway - the other cats are on their platforms, well above it.
27.3
255 IF MY<>CY1 OR MX<20 OR MX>94 THEN 260
256 IF MX>CX1 AND D1<0 THEN D1=2:SPRITE 1,CX1,CY1,8,136
257 IF MX<CX1 AND D1>0 THEN D1=-2:SPRITE 1,CX1,CY1,8,140
The mouse is on the red cat's platform when it is standing at the cat's height and within the cat's range. Then the cat turns to face it, and the new shape shows which way it is facing. With the mouse started on that platform at x=30 (800 MX=30:MY=63:G=-1:VX=0:VY=0:FC=132 for a moment), the cat turns straight round, walks to it, and then stays on it, turning to and fro. In the unchanged game it walks on to the far end first.
28.1
655 FOR F=1 TO 4:SPRITE OFF 0:FOR W=1 TO 50:NEXT W:SPRITE 0,MX,MY,14,FC:FOR W=1 TO 50:NEXT W:NEXT F
The mouse blinks four times where it was caught, then line 660 puts it back at the start. FC brings it back facing the way it was. To see it without waiting, start it in the red cat's path for a moment: 800 MX=100:MY=63:G=-1:VX=0:VY=0:FC=132.
28.2
445 IF PTS MOD 30=0 THEN LIVES=LIVES+1:PRINT @33,2;LIVES
Every third piece of cheese makes the score a multiple of 30. With three pieces put on the floor for a moment (870 DATA 70,6,200,6,130,6,210,82,80,122), a walk to the right ended:
SCORE 30 LIVES 4
28.3
650 IF LUCKY=0 THEN LUCKY=-1:PRINT @15,4;"LUCKY!":GOTO 660
655 LIVES=LIVES-1:TCOL 11,1:PRINT @33,2;LIVES
675 PRINT @15,4;" ";
The check has to be at line 650 itself, because that is where line 178's GOSUB goes in; a line numbered below 650 would never be reached. The lost life moves down to 655. LUCKY is 0 at the start of every run, so the first catch shows LUCKY!, keeps all three lives, and still sends the mouse back to the start. Line 675 rubs the message out after the pause. The second catch costs a life as usual: LIVES 2.
29.1
210 SPRITE OFF 0:PRINT @17,4;"HOME!":PTS=PTS+10*LIVES:GOSUB 560
Line 560 is the score subroutine from S26. Home with all five pieces and three lives:
SCORE 80 LIVES 3
HOME!
To test it without collecting the cheese, set 65 PTS=50:GOT=5:I=0 and 800 MX=100:MY=138:G=-1:VX=0:VY=0:FC=132 for a moment, and walk right.
29.2
445 IF GOT=5 THEN GCOL 15,1:ELLIPSE 175,122,13,1,0,0,3.15:DRAW 162,122 TO 162,120:DRAW 188,122 TO 188,120
When the fifth piece goes, the arch is drawn again in white over the yellow one. Line 445 comes after 420 has counted the piece.
29.3
220 GOSUB 1810:IF PTS>BEST THEN BEST=PTS
625 PRINT @15,2;"BEST";BEST
Both ways of ending arrive at line 220, so that is where a new best is noted. After a game that ate one piece, and then another go:
SCORE 0 BEST 10 LIVES 3
The line that must not reset it is 65: "another go" goes back to 60, and everything from there on runs again. BEST is never set there, so it keeps its value. RUN does clear it, as it clears every variable. S32 keeps a best on the disc for that reason.
30.1
440 GOSUB 500:GOSUB 560:P=40:IF GOT=5 THEN P=20
445 GOSUB 1310
Half the pitch number doubles the note: the last piece squeaks an octave higher than the others, and dies away just as quickly. GOT has already been counted by line 420. The GOSUB goes on a line of its own because a false IF skips the rest of its line.
30.2
210 SPRITE OFF 0:PRINT @17,4;"HOME!":TEMPO 6:MUSIC "C2E2G2E2G2+C4R2G2+C2+E2+G8R":TEMPO 4
C, E, G, E, G and a longer top C; a short rest; then G, C, E and a long G above, climbing to finish. It lasts about a second and a half. It still ends in R, so the last note stops.
30.3
1340 PSG 6,5:PSG 11,0:PSG 12,8:PSG 8,16:PSG 7,119:PSG 13,0
A smaller number in register 6 makes the hiss higher, and a smaller one in register 12 makes the envelope shorter. The hiss now dies away in less than half the time, and is higher.
31.1 Put lines 15 and 35 back as S30 had them, and delete line 16:
15 CLEAR &DFFF:GOSUB 1710
16
35 DIM CHX(5),CHY(5),EATEN(5)
Then, for the second timing, S31's line 15 again with only the arrays and the key reader left in line 16 (and line 35 deleted):
16 DIM EATEN(5),CHX(5),CHY(5):GOSUB 1710
Timed with S31's lines 130 and 189, three hundred passes:
| Lines 15 and 16 | Standing still | Holding X |
|---|---|---|
| as S30 had them | 27 s | 58 s |
| only line 15 changed | 23 s | 49 s |
| both, as S31 has them | 22 s | 48 s |
Line 15 does nearly all of it: four of the five seconds standing still, and nine of the ten with X held. Line 16's variables are worth about a second.
The variables that earn their place are the ones the loop uses on every pass. Standing still, that is the keys, G, CT and the red cat; taking MX, MY, VX, VY and FC out of line 15 made no difference standing still, still 23 s. With X held it went from 49 s to 55 s. The mouse's variables earn their place while the mouse moves, which is when the speed matters most.
31.2
10 TI$="000000"
20 FOR I=1 TO 1000:NEXT I
30 PRINT TI$
prints 000001 - one second, but the clock only counts whole seconds, so that is not very exact. With 10000 in line 20 it prints 000014: about 1.4 ms a pass.
31.3
10 TI$="000000"
20 FOR I=1 TO 1000
30 GOTO 600
100 REM
110 REM
and so on, a REM on every tenth line up to 590, then:
600 NEXT I
610 PRINT "TIME ";TI$
prints TIME 000005. Then DEL 100,590 and RUN again: TIME 000002. Three seconds over a thousand jumps is 3 ms a jump for fifty lines passed, the same 0.06 ms a line that GOSUB costs. GOTO finds its line the same way.
32.1
21 DIM BEST(3)
216 GOSUB 1610:IF H=1 THEN PRINT @12,5;"A NEW BEST TIME!"
1450 TCOL 11,1:FOR H=1 TO 3
1452 IF BEST(H) THEN PRINT @10,14+H;"BEST TIME";H;"-";BEST(H)
1454 NEXT H
1520 OPEN "BEST.DAT",FD$:INPUT #FD$:INPUT BEST(1):INPUT BEST(2):INPUT BEST(3):CLOSE:BT=BEST(1)
1560 CREATE "BEST.DAT",FD$:PRINT #FD$:PRINT BEST(1):PRINT BEST(2):PRINT BEST(3):PRINT #0:CLOSE
1600 REM -- PUT TS INTO THE BEST THREE --
1610 FOR H=1 TO 3
1620 IF BEST(H)=0 OR TS<BEST(H) THEN 1650
1630 NEXT H
1640 RETURN
1650 IF H<3 THEN BEST(3)=BEST(2)
1660 IF H<2 THEN BEST(2)=BEST(1)
1670 BEST(H)=TS:BT=BEST(1)
1680 GOSUB 1560:RETURN
Lines 1610 to 1630 find the first place the new time beats, or an empty place. Lines 1650 and 1660 move the slower times down one to make room. Nothing is moved when the new time goes third. That is why 1650 is an IF rather than a FOR: a FOR would run once even when there was nothing to do (S12). The counting variable is H, not J, because J is the space bar. BT is kept equal to the best, so the score line still works. BEST is dimensioned at 21 because line 22 reads the file before anything else. If you have a BEST.DAT from S32 with one time in it, ERA "BEST.DAT" first.
Four wins, in 25, 40, 32 and 50 seconds, and then RUN:
BEST TIME 1 - 25
BEST TIME 2 - 32
BEST TIME 3 - 40
32.2
186 PRINT @23,2;MID$(TI$,4,1);":";RIGHT$(TI$,2);
SCORE 0 0:30 LIVES 3
Timed standing still with S31's method, 300 passes took T=000028 against T=000022 without it: 20 ms a pass, which is a lot. Printing only when the seconds change brings it down to T=000026:
186 T$=RIGHT$(TI$,2):IF T$<>OT$ THEN OT$=T$:PRINT @23,2;MID$(TI$,4,1);":";T$;
32.3
216 IF BT=0 OR TS<BT THEN BT=TS:GOSUB 1580:GOSUB 1560:PRINT @12,5;"A NEW BEST TIME!"
1450 IF BT THEN TCOL 11,1:PRINT @10,15;"BEST TIME";BT;"BY ";WHO$
1520 OPEN "BEST.DAT",FD$:INPUT #FD$:INPUT BT:INPUT WHO$:CLOSE
1560 CREATE "BEST.DAT",FD$:PRINT #FD$:PRINT BT:PRINT WHO$:PRINT #0:CLOSE
1580 GOSUB 1810:PRINT @10,7;:INPUT "YOUR INITIALS? ";WHO$
1590 RETURN
The GOSUB 1810 in line 1580 matters. The player is still holding X when the mouse gets home, and a held key's repeats are queued and typed at the next question (S24), so without it the initials would start with a string of X's. S24's subroutine empties the queue first, and while the key is still held it keeps finding more, so the question waits until the key is let go. After a win and RUN, the title shows:
BEST TIME 25 BY GJW
As in 32.1, ERA "BEST.DAT" first if S32 left one on the disc.
33.1 Put S31's timing lines into the finished game, save it under a new name, and compile it:
130 CALL &E000:K=PEEK(&E047) AND 96:J=PEEK(&E040) AND 64:NP=NP+1:IF NP=1 THEN TI$="000000"
189 IF NP=301 THEN PRINT @2,4;"T=";TI$:GOSUB 1810:END
SAVE "TIMED"
DOS
XC TIMED
XR TIMED
Left alone, it shows T=000013: 300 passes in 13 seconds, 43 ms a pass, against 22 seconds in BASIC. Run it again holding X from the moment the game starts until the time appears: T=000024, 80 ms a pass, against 48 seconds in BASIC. Standing still it is 1.7 times as fast, and walking twice as fast. If you are still holding X when it ends, a row of X's follows the 0: prompt; ENTER clears it with No File.
33.2
300 VX=0:IF K=64 THEN VX=-3:IF FC<>144 THEN FC=144:SPRITE 0,MX,MY,14,FC
310 IF K=32 THEN VX=3:IF FC<>132 THEN FC=132:SPRITE 0,MX,MY,14,FC
Saved as MOUSE16, compiled and run. To know the speed is the same, time it as in 33.1 with X held: T=000024 again, 80 ms a pass. So the mouse moves 3 pixels every 80 thousandths of a second - exactly the 6 every 160 it managed in BASIC - in steps half the size. The jump is unchanged: it still moves 4 a pass in the air.
33.3
10 PRINT "HELLO"
20 END
30 GOTO 500
RUN prints HELLO and Ready: BASIC never reaches line 30, so it never finds out that line 500 does not exist. Saved as REFTEST and compiled:
0:XC REFTEST
Xtal BASIC Compiler Ver 5.10
(c) Xtal 1987
Compiling REFTEST -
Pass 1 - Reference Error(s):
500 in: 30
Pass 2 Pass 3
Compiled OK
The compiler checks every GOTO before anything runs, and names both the missing line and the line that wants it - and still compiles.
34.1 The instructions have small letters, so press CAPS LOCK before typing the text:
1690 PRINT@2,7;"* This code is a ";C$;" digit number."
1700 PRINT@2,8;"* Each number is in the range 1 to ";N$;"."
With 1130 C=5:C$="5":N=8:N$="8", the instructions read:
* This code is a 5 digit number.
* Each number is in the range 1 to 8.
C$ and N$ are already there as text, so there is no leading space to get rid of.
34.2
1605 IF RESULT THEN GOSUB 2010
2000 REM ** FEWEST GOES, KEPT ON THE DISC
2010 FG=0:ON ERR GOTO 2030
2020 OPEN "FEWEST.DAT",FD$:INPUT #FD$:INPUT FG:CLOSE
2025 OFF ERR
2030 IF FG=0 OR GO<FG THEN FG=GO:CREATE "FEWEST.DAT",FD$:PRINT #FD$:PRINT FG:PRINT #0:CLOSE
2040 PRINT@8,19;"FEWEST GOES SO FAR";FG;
2050 IF NOT Z THEN ON ERR GOTO 1210
2060 RETURN
It is S32's pattern again. GO is still the number of the winning go when line 1520 returns. Line 2050 puts back the program's own error trap from line 1110, which line 2010 replaced. Save it under a name of your own; the disc's copy is locked. To test it without having to play well, put 1300 I$="1234" in for a moment, so that you know the code. Winning in two, then in one, then (after RUN) in two again showed FEWEST GOES SO FAR 2, then 1, then still 1: the last one read back from the disc.
34.3 LOAD "HANGMAN" and LIST 1090,,1190:
1130 GOSUB 1200:REM SET-UP
1140 GOSUB 1450:REM CHARACTER-DEFINITION
1150 GOSUB 2670:REM INTRODUCTION/INSTRUCTIONS
1160 GOSUB 2990:REM UNTIL COMND="F"(FOR FINISH)
M$. It has no RETURN of its own, so it runs straight on through the next part to the RETURN at 2660.SHAPE - the prisoner in each of his walking poses, the portcullis - and the numbers for his walk. After 1200 has run, this is its second time through.DICTIONE.DAT or DICTIONH.DAT and runs the guessing, until F is pressed.Look at line 3170 while you are there: FOR REC0RD = 1 TO RND(DCSZ), with a nought for the O, and W0RD$ on the next line. RECORD and WORD both have OR in them: this is S8's trap, and the zero is how David Wess got round it.
35.1
CLEAR &DFFF
POKE &E000,&3E,42,&CF,158,&C9
FOR I=1 TO 5:CALL &E000:NEXT I
*****Ready
Five stars, and Ready straight after them on the same line: the machine code prints a star and nothing else, not even a new line.
35.2 SWAP. The manual's entry says it swaps two variables of the same type, array elements included, and that mixing types is a TYPE ERROR:
A=1:C=2:SWAP A,C:PRINT A;C
2 1
D$="CAT":E$="MOUSE":SWAP D$,E$:PRINT D$;" ";E$
MOUSE CAT
DIM A(3),B(3):A(1)=5:B(1)=9:SWAP A(1),B(1):PRINT A(1);B(1)
9 5
SWAP A,D$
Type Error
All four claims hold.
35.3 Anything of your own is right. Here is a small one, built from the course's parts: cheese falls from the top, and the mouse has to catch it.
5 CLEAR &DFFF:GOSUB 1710
10 BCOL 1:TCOL 15,1:CLS
20 RESTORE 1100:N=130:GOSUB 900
30 N=131:GOSUB 900
40 MAG 1:SPRITE OFF
50 PTS=0:MISS=0
60 GCOL 7,1:FOR Y=0 TO 3:DRAW 0,Y TO 255,Y:NEXT Y
70 MX=120:CX=RND(240):CY=160
80 SPRITE 0,MX,20,14,130:SPRITE 1,CX,CY,11,131
90 CALL &E000:K=PEEK(&E047) AND 96
100 IF K=64 THEN MX=MX-6
110 IF K=32 THEN MX=MX+6
120 IF MX<0 THEN MX=0
130 IF MX>240 THEN MX=240
140 CY=CY-4
150 SPRITE 0,MX,20:SPRITE 1,CX,CY
160 IF INP(9) AND 32 THEN PTS=PTS+1:GOSUB 300
170 IF CY<8 THEN MISS=MISS+1:GOSUB 300
180 TCOL 11,1:PRINT @1,0;"CAUGHT";PTS;" MISSED";MISS;" ";
190 IF PEEK(&E045)=64 OR MISS=3 THEN 200 ELSE 90
200 GOSUB 1810:PRINT @15,10;"GAME OVER":END
290 REM -- A NEW PIECE AT THE TOP --
300 CX=RND(240):CY=160:SPRITE 1,CX,CY
310 FOR W=1 TO 20:NEXT W:W=INP(9)
320 RETURN
890 REM -- READ EIGHT ROWS AND MAKE SHAPE N --
900 S$=""
910 FOR R=1 TO 8
920 READ P$
930 V=0:G=128
940 FOR B=1 TO 8
950 IF MID$(P$,B,1)<>"." THEN V=V+G
960 G=G/2
970 NEXT B
980 S$=S$+RIGHT$(HEX$(V),2)
990 NEXT R
1000 SHAPE N,S$
1010 RETURN
1100 DATA "........","........","......#.",".....###"
1110 DATA "..######",".#######","#.#...#.","........"
1200 DATA "........","........","....#...","...###.."
1210 DATA "..#####.",".#######","########","........"
and S24's lines 1700 to 1840, the key reader and the queue emptier, typed exactly as they are in the game. Line 5 puts the key reader in memory before anything else, as the game's line 15 does, and line 200 empties the key queue before the game stops.
Z and X move the mouse. Three misses, or Q, end the game. Line 300 moves the cheese away before line 310 reads port 9 again, for the reason S28 gave. Left alone, it ends at MISSED 3 with GAME OVER - and the mouse may still have caught one, if a piece happened to fall straight onto it where it stood. With the first piece dropped straight onto the mouse, it counted CAUGHT 1 - once, not twice. Hold X for a couple of seconds and then press Q: GAME OVER, and nothing is typed after Ready. Then make it yours: faster cheese as the score goes up, a cat that drops instead now and then, a sound for a catch.