“The Puzzler” contains two sliding-block puzzle games — “Inversion” and “Double Inversion” — in which the player maneuvers variable-width pieces (1–4 cells wide, each occupying two screen rows) horizontally and vertically around a playing field. Piece data is stored in a 36×12 (or 68×12 for the double variant) array, with columns 3–7 holding length and four corner character codes, and columns 8–12 holding solution state for comparison during the analysis routine. The display engine at line 7000 uses computed GOTO (7000 + 100 × piece length) to branch to specialized PRINT routines for 1-, 2-, 3-, and 4-wide pieces, and the cursor highlight is implemented by directly POKEing character codes into the display file using addresses derived from PEEK 16396/16397. A four-character lock code feature, stored in a substring of S$, allows the puzzle state to be saved in a locked configuration requiring a password to resume play.
Program Analysis
Program Structure
The listing contains two complete, nearly identical BASIC programs: “Inversion” (36-cell grid) and “Double Inversion” (68-cell grid). Both share the same line numbering scheme and logic, differing mainly in grid size constants, title strings, and a few display coordinates. The flow is:
- Initialization (lines 10–280): dimension arrays, set constants and column-index aliases.
- Menu (lines 330–520): display options B/D/L/S with an animated cursor blink loop.
- Lock check (lines 530–690): validate four-character password stored in
S$(21 TO ). - Game setup (lines 700–740): call display-building subroutines, then fall into main loop.
- Main input loop (lines 1000–3570): read keypress, dispatch to movement or utility routines.
- Movement routines (lines 2000–5340): horizontal/vertical piece movement with collision detection.
- Display engine (lines 7000–7610): computed GOTO rendering for pieces of width 1–4.
- UI subroutines (lines 8000–8350): title/border drawing, analysis, congratulations.
- Save/load routines (lines 9500–9920): save with or without lock code.
- Utility routines (lines 9950–9985): clear comment area, COPY to printer.
Data Representation
Each cell in the playing field is a row in the array T. The twelve columns serve distinct purposes, aliased by variables set at initialization:
| Column | Alias | Contents |
|---|---|---|
| 1 | — | Screen row of piece’s top edge |
| 2 | — | Screen column of piece’s left edge |
| 3 | L | Piece width in cells (0 = empty, 1–4 = occupied) |
| 4 | UL | Character code for upper-left corner (8 = empty/space) |
| 5 | UR | Character code for upper-right corner |
| 6 | LL | Character code for lower-left corner |
| 7 | LR | Character code for lower-right corner |
| 8–12 | (solution) | Mirror of columns 3–7 holding the target/solved state |
The character code 8 acts as a sentinel meaning “empty cell.” Values 129 and 130 are special (likely inverse-video block graphics) and are handled by separate branches in lines 3310–3380 to avoid the offset arithmetic applied to normal piece characters.
Display Engine: Computed GOTO
The rendering subroutine beginning at line 7000 iterates over a range SG to EG and dispatches based on piece width using a computed GOTO:
GOTO 7000+(100*T(SG,L))
This lands at line 7100 (width 1), 7200 (width 2), 7300 (width 3), or 7400 (width 4). Each handler prints two rows of characters using consecutive T array entries. Width-1 handler at line 7140 also manages a blank-cell counter (MV) used during post-move refresh to skip re-rendering unchanged regions, with a branch at line 7170 jumping ahead by 8 (or 16 for Double Inversion) cells in the table.
Cursor Highlight via Direct POKE
Rather than redrawing the selected piece through PRINT, the game highlights the current piece by directly writing modified character codes into the display file. Lines 3400–3480 calculate the display-file address as:
Z = PEEK 16396 + 256 * PEEK 16397 (base of display file)
ULP = Z + (33 * T(P,1)) + 1 + T(P,2)
This uses the 33-byte-per-row structure of the ZX81 display file (32 character bytes + 1 NEWLINE). The four corner addresses ULP, URP, LLP, LRP are POKEd with highlight values computed in lines 3310–3380, then restored to original values at lines 3520–3550, creating a flicker-highlight effect in the main loop.
Keyboard Handling and Key Codes
All input uses INKEY$ polled via CODE INKEY$. The key mappings are:
| CODE | Key | Action |
|---|---|---|
| 33 | Q | Move selected piece left (cursor) |
| 36 | T / Y | Move selected piece right (cursor) |
| 34 | W | Move piece up one row |
| 35 | E | Move piece down one row |
| 112–115 | Shifted variants | Vertical/horizontal piece slide |
| 38 | A | Analyze puzzle state |
| 40 | H | Clear comment area |
| 45 | P / printer key | COPY to printer |
| 55 | 7 | Return to menu |
| 39 | B | Begin/Continue (menu) |
| 41 | D | Display solution (menu) |
| 49 | L | Save with lock (menu) |
| 56 | S | Save (menu) |
Puzzle Lock System
A four-character password is stored in S$(21 TO 24) (the tail of the 24-character string S$). When the user chooses “Save with Lock,” they enter a code stored there. On loading, if this substring is not all spaces, the player must supply the correct code before play resumes. After three failed attempts, the game returns to the menu without granting access. The lock code travels with the saved program data since S$ is a BASIC variable retained in the save.
Analysis Routine
Lines 8350–8710 implement a “solve-check” comparison. The routine first verifies that cells 1–4 (the dedicated empty/space slots) are indeed vacant (T(X,UL)=8). It then iterates over cells 5 through 36 (or 68), comparing current character codes in columns 4–7 against the solution values stored in columns 9–12. For non-special codes, a difference of less than 5 is considered acceptable (likely accounting for normal vs. inverse variants of the same graphic); larger differences or mismatched special codes increment an error counter Z. If Z=0 and no prior solve has been recorded (TM=0), the congratulations sequence fires and the solver’s name plus move count are stored.
Menu Cursor Animation
Lines 410–440 implement a simple blinking cursor at the menu prompt. CHR$ 8 (inverse space / cursor block) and CHR$ 0 (space) are alternately POKEd to position (17,26) with short FOR…NEXT delay loops of only 2 iterations — extremely brief, relying on SLOW mode’s inherent display overhead to produce a visible blink rate.
Notable Differences Between the Two Variants
- Grid size:
DIM T(36,12)vs.DIM T(68,12); boundary checks use 36 vs. 68. - Vertical stride constants: 8 (Inversion) vs. 16 (Double Inversion) for up/down movement and post-move display jumps.
- Starting piece position:
P=11vs.P=17. - Move counter display column:
AT 8,25vs.AT 8,18. - The Double Inversion variant inlines
COPYat line 1036 rather than calling subroutine 9980. - Title string and header layout differ to accommodate the longer “DOUBLE INVERSION” title.
Anomalies and Notes
- Line 9965 in both variants duplicates the
PRINT AT 7,0;B$( TO 15)statement from line 9960 — this appears to be a harmless redundancy. - Line 2490’s boundary check
IF X>3 THEN GOTO 9000uses a hard-coded literal 3 regardless of grid size, which is intentional — it guards the fixed empty-cell pool at indices 1–4. - Line 9920
GOTO 20jumps to line 20 (LET Z=0) rather than line 10, so the arrayTand string variables are not re-dimensioned after a save/reload cycle — this is intentional since the saved state already contains valid data. - The
GOSUB 9950“clear comments” routine at line 9965 prints the same line twice, suggesting a copy-paste oversight with no functional impact.
Content
Image Gallery
Source Code
3 REM "* INVERSION *"
5 REM "* A VSSP PUZZLE *"
7 REM "* COPYRIGHT 1982 *"
8 REM "* N.L.MARTINO *"
10 DIM T(36,12)
11 LET S$=" "
12 LET TM=0
13 LET P=11
15 LET M=0
16 LET H$=" "
17 LET B$=" "
20 LET Z=0
110 LET SG=1
130 LET EG=36
140 LET I=1
150 LET K=0
160 LET A=0
170 LET B=0
180 LET C=0
190 LET D=0
200 LET ES=0
210 LET MV=0
220 LET X=0
230 LET Y=0
240 LET L=3
250 LET UL=4
260 LET UR=5
270 LET LL=6
280 LET LR=7
330 CLS
335 GOSUB 8020
340 PRINT AT 7,3;"------PUZZLE MENU-------"
350 PRINT AT 9,3;" B-BEGIN/CONTINUE "
360 PRINT AT 11,3;" D-DISPLAY A SOLUTION"
370 PRINT AT 13,3;" L-SAVE WITH LOCK "
380 PRINT AT 15,3;" S-SAVE "
390 PRINT AT 17,3;"ENTER ONE CODE B/D/L/S "
400 LET K=0
410 IF INKEY$ <>"" THEN GOTO 410
420 PRINT AT 17,26;CHR$ 8
422 FOR X=1 TO 2
426 NEXT X
430 PRINT AT 17,26;CHR$ 0
432 FOR X=1 TO 2
436 NEXT X
440 IF INKEY$ ="" THEN GOTO 420
450 LET K=CODE INKEY$
460 IF K=39 THEN GOTO 530
470 IF K=41 THEN GOTO 8800
480 IF K=49 THEN GOTO 9500
490 IF K=56 THEN GOTO 9800
500 PRINT AT 17,3;"INCORRECT CODE..REENTER "
510 FOR X=1 TO 50
515 NEXT X
520 GOTO 390
530 IF S$(21 TO )=" " THEN GOTO 700
540 LET X=0
542 PRINT AT 19,2;B$( TO 30)
550 PRINT AT 20,2;" PUZZLE IS LOCKED... "
560 PRINT AT 21,2;" ENTER LOCK CODE-PRESS ENTER"
570 INPUT H$(1 TO 4)
580 IF H$(1 TO 4)<>S$(21 TO ) THEN GOTO 610
590 LET S$(21 TO )=" "
600 GOTO 700
610 LET X=X+1
630 PRINT AT 21,3;H$;" IS NOT VALID-REENTER "
640 FOR Y=1 TO 50
642 NEXT Y
645 IF X>2 THEN GOTO 660
650 GOTO 560
660 PRINT AT 19,2;"THERE HAVE BEEN 3 UNSUCCESSFUL"
670 PRINT AT 20,2;"ATTEMPTS TO UNLOCK THE PUZZLE"
680 PRINT AT 21,2;"ENTER MENU CODE B TO TRY AGAIN"
690 GOTO 400
700 CLS
702 FAST
704 GOSUB 8000
708 GOSUB 8150
710 LET SG=1
720 LET EG=36
730 GOSUB 7000
740 GOTO 3300
1000 IF INKEY$ ="" THEN GOTO 3450
1020 LET K=CODE INKEY$
1030 IF K=55 THEN GOTO 330
1032 IF K=40 THEN GOSUB 9950
1034 IF K=38 THEN GOTO 8350
1036 IF K=45 THEN GOSUB 9980
1040 IF K>32 AND K<37 THEN GOTO 2000
1050 IF K>111 AND K<116 THEN GOTO 2000
1055 LET K=0
1060 GOTO 3450
2000 FAST
2005 IF K=36 THEN GOTO 2100
2010 IF K=33 THEN GOTO 2120
2020 IF K=34 THEN GOTO 2300
2030 IF K=35 THEN GOTO 2320
2040 IF K=115 THEN GOTO 4000
2050 IF K=114 THEN GOTO 4020
2060 IF K=113 THEN GOTO 5000
2070 IF K=112 THEN GOTO 5020
2075 LET K=0
2080 GOTO 3450
2100 LET I=1
2110 GOTO 2130
2120 LET I=-1
2130 LET X=P
2140 LET X=X+I
2150 IF X<1 OR X>36 THEN GOTO 9000
2160 IF T(X,1)<>T(P,1) THEN GOTO 9000
2170 IF T(X,L)=0 OR T(X,UL)=8 THEN GOTO 2140
2180 LET P=X
2190 GOTO 3300
2300 LET I=8
2305 LET MV=0
2310 GOTO 2330
2315 LET MV=0
2320 LET I=-8
2330 LET X=P+I
2340 IF X>36 THEN GOTO 9000
2345 IF X<1 THEN LET X=1
2350 IF T(X,UL)<>8 AND T(X,L)>0 THEN GOTO 2450
2360 IF T(X,UL)<>8 THEN GOTO 2366
2362 LET Y=1
2363 IF P+I<1 THEN GOTO 2470
2364 GOTO 2370
2366 LET Y=-1
2370 LET MV=MV+1
2372 LET X=P+I
2375 LET X=X+Y
2380 IF X<1 OR X>36 THEN GOTO 2420
2390 IF T(X,1)<>T(P+I,1) THEN GOTO 2420
2400 IF T(X,UL)<>8 AND T(X,L)>0 THEN GOTO 2450
2410 GOTO 2375
2420 IF MV>=2 THEN GOTO 9000
2430 IF Y>0 THEN GOTO 2366
2440 GOTO 2362
2445 LET MV=0
2450 LET P=X
2455 LET MV=0
2460 GOTO 3300
2470 LET X=X+Y
2480 IF T(X,UL)<>8 AND T(X,L)>0 THEN GOTO 2450
2490 IF X>3 THEN GOTO 9000
2500 GOTO 2470
3300 LET ES=P+T(P,L)-1
3305 LET K=0
3310 IF T(P,UL)=129 OR T(P,UL)=130 THEN LET A=T(P,UL)
3320 IF T(P,UL)<129 OR T(P,UL)>130 THEN LET A=T(P,UL)-19
3330 IF T(ES,UR)=129 OR T(ES,UR)=130 THEN LET B=T(ES,UR)
3340 IF T(ES,UR)<129 OR T(ES,UR)>130 THEN LET B=T(ES,UR)-18
3350 IF T(P,LL)=129 OR T(P,LL)=130 THEN LET C=T(P,LL)
3360 IF T(P,LL)<129 OR T(P,LL)>130 THEN LET C=T(P,LL)-19
3370 IF T(ES,LR)=129 OR T(ES,LR)=130 THEN LET D=T(ES,LR)
3380 IF T(ES,LR)<129 OR T(ES,LR)>130 THEN LET D=T(ES,LR)-18
3400 LET Z=PEEK 16396+256*PEEK 16397
3410 LET ULP=Z+(33*T(P,1))+1+T(P,2)
3420 LET URP=Z+(33*T(ES,1))+2+T(ES,2)
3430 LET LLP=ULP+33
3440 LET LRP=URP+33
3450 SLOW
3455 POKE ULP,A
3460 POKE URP,B
3470 POKE LLP,C
3480 POKE LRP,D
3500 IF INKEY$ ="" THEN GOTO 3520
3510 LET K=CODE INKEY$
3520 POKE ULP,T(P,UL)
3530 POKE URP,T(ES,UR)
3540 POKE LLP,T(P,LL)
3550 POKE LRP,T(ES,LR)
3560 IF K>0 THEN GOTO 1030
3570 GOTO 1000
4000 LET I=1
4010 GOTO 4030
4020 LET I=-1
4030 LET X=P
4040 LET X=X+I
4050 IF X<1 OR X>36 THEN GOTO 9000
4060 IF T(X,1)<>T(P,1) THEN GOTO 9000
4070 IF T(X,UL)<>8 THEN GOTO 4040
4080 IF I<0 THEN GOTO 4130
4090 LET SG=X
4100 LET EG=P
4110 LET I=-1
4120 GOTO 4160
4130 LET SG=X
4140 LET EG=P+T(P,L)-1
4150 LET I=1
4160 IF SG=EG THEN GOTO 4220
4170 FOR Z=L TO LR
4180 LET T(SG,Z)=T(SG+I,Z)
4190 NEXT Z
4200 LET SG=SG+I
4210 GOTO 4160
4220 LET T(SG,L)=1
4230 FOR Z=UL TO LR
4240 LET T(SG,Z)=8
4250 NEXT Z
4260 IF P<X THEN LET SG=P
4270 IF P<X THEN LET EG=X
4280 IF P>X THEN LET SG=X
4282 LET M=M+1
4284 PRINT AT 8,25;M
4290 GOSUB 7000
4300 IF I>0 THEN LET P=P-1
4310 IF I<0 THEN LET P=P+1
4320 GOTO 3300
5000 LET I=8
5010 GOTO 5030
5020 LET I=-8
5030 LET X=P+I
5040 IF X<1 OR X>36 THEN GOTO 9000
5050 LET MV=0
5060 IF T(X,UL)=8 THEN GOSUB 5300
5070 IF MV<T(P,L) THEN LET MV=0
5075 IF MV<T(P,L) THEN GOTO 9000
5080 LET SG=P
5090 FOR Z=X TO EG
5100 FOR Y=L TO LR
5110 LET T(Z,Y)=T(SG,Y)
5120 NEXT Y
5130 LET SG=SG+1
5140 NEXT Z
5150 LET EG=P+T(P,L)-1
5160 FOR Z=P TO EG
5170 LET T(Z,L)=1
5180 FOR Y=UL TO LR
5190 LET T(Z,Y)=8
5200 NEXT Y
5210 NEXT Z
5220 IF P<X THEN LET SG=P
5225 IF P<X THEN LET EG=X+T(P,L)-1
5230 IF P>X THEN LET SG=X
5232 IF P>X THEN LET EG=P+T(X,L)-1
5235 LET M=M+1
5237 PRINT AT 8,25;M
5240 GOSUB 7000
5250 LET P=X
5260 GOTO 3300
5300 LET EG=X+T(P,L)-1
5310 FOR Z=X TO EG
5320 IF T(Z,UL)=8 THEN LET MV=MV+1
5330 NEXT Z
5340 RETURN
7000 IF SG>EG THEN RETURN
7010 GOTO 7000+(100*T(SG,L))
7100 PRINT AT T(SG,1),T(SG,2);CHR$ T(SG,UL);CHR$ T(SG,UR)
7130 PRINT AT T(SG,1)+1,T(SG,2);CHR$ T(SG,LL);CHR$ T(SG,LR)
7140 IF T(SG,UL)<>8 THEN GOTO 7500
7150 LET MV=MV-1
7160 IF MV<>0 THEN GOTO 7510
7170 LET SG=P+8
7180 GOTO 7000
7200 PRINT AT T(SG,1),T(SG,2);CHR$ T(SG,UL);CHR$ T(SG,UR);CHR$ T(SG+1,UL);CHR$ T(SG+1,UR)
7210 PRINT AT T(SG,1)+1,T(SG,2);CHR$ T(SG,LL);CHR$ T(SG,LR);CHR$ T(SG+1,LL);CHR$ T(SG+1,LR)
7220 GOTO 7500
7300 PRINT AT T(SG,1),T(SG,2);CHR$ T(SG,UL);CHR$ T(SG,UR);CHR$ T(SG+1,UL);CHR$ T(SG+1,UR);CHR$ T(SG+2,UL);CHR$ T(SG+2,UR)
7310 PRINT AT T(SG,1)+1,T(SG,2);CHR$ T(SG,LL);CHR$ T(SG,LR);CHR$ T(SG+1,LL);CHR$ T(SG+1,LR);CHR$ T(SG+2,LL);CHR$ T(SG+2,LR)
7320 GOTO 7500
7400 PRINT AT T(SG,1),T(SG,2);CHR$ T(SG,UL);CHR$ T(SG,UR);CHR$ T(SG+1,UL);CHR$ T(SG+1,UR);CHR$ T(SG+2,UL);CHR$ T(SG+2,UR);CHR$ T(SG+3,UL);CHR$ T(SG+3,UR)
7410 PRINT AT T(SG,1)+1,T(SG,2);CHR$ T(SG,LL);CHR$ T(SG,LR);CHR$ T(SG+1,LL);CHR$ T(SG+1,LR);CHR$ T(SG+2,LL);CHR$ T(SG+2,LR);CHR$ T(SG+3,LL);CHR$ T(SG+3,LR)
7500 IF MV>0 THEN GOTO 7600
7510 LET SG=SG+T(SG,L)
7520 GOTO 7000
7600 LET SG=SG+8
7610 GOTO 7000
8000 LET Y=1
8010 GOTO 8030
8020 LET Y=5
8030 PRINT AT 0,6;"I N E R S I O N"
8040 PRINT AT 0,10;CHR$ 187
8050 IF Y=1 THEN GOTO 8090
8060 PRINT AT 2,7;"A VSSP PUZZLE"
8070 PRINT AT 3,7;"COPYRIGHT 1982"
8080 PRINT AT 4,10;"N.L.MARTINO"
8090 PRINT AT Y,0;"████████████████████████████████"
8120 RETURN
8150 PRINT AT 9,7;"▗▄▄▄▄▄▄▄▟ ▌"
8190 PRINT AT 7,15;"▗▄▄▄▄▄▄▄▄▖"
8200 FOR X=10 TO 17
8205 PRINT AT X,7;"▐"
8210 PRINT AT X,24;"▌"
8215 NEXT X
8220 PRINT AT 8,15;"▐ ▌"
8250 PRINT AT 18,7;"▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘"
8270 PRINT AT 2,0;"SOLVED BY:"
8290 PRINT AT 7,25;"MOVES"
8295 PRINT AT 8,25;M
8300 PRINT AT 19,0;"(H)ARD COPY (R)ETURN"
8310 PRINT AT 21,0;"(C)LEAR COMMENTS (A)NALYZE"
8312 IF TM=0 THEN GOTO 8320
8314 PRINT AT 2,12;S$( TO 20)
8316 PRINT AT 3,12;"IN ";TM;" MOVES"
8320 RETURN
8350 FAST
8352 LET K=0
8355 IF T(1,UL)=8 AND T(2,UL)=8 AND T(3,UL)=8 AND T(4,UL)=8 THEN GOTO 8390
8360 PRINT AT 5,0;"ANALYSIS INCOMPLETE"
8370 PRINT AT 6,0;" SPACES IN MAIN AREA"
8380 GOTO 3450
8390 LET Z=0
8400 LET SG=5
8410 LET EG=36
8420 FOR X=SG TO EG
8430 IF T(X,L)>0 THEN LET MV=0
8440 FOR Y=UL TO LR
8450 IF T(X,Y+5)=129 OR T(X,Y+5)=130 THEN GOTO 8520
8460 LET Q=T(X,Y+5)-T(X,Y)
8470 IF Q<5 AND Q>-5 THEN GOTO 8530
8480 IF MV=1 THEN GOTO 8530
8490 LET MV=1
8500 LET Z=Z+1
8510 GOTO 8530
8520 IF T(X,Y+5)<>T(X,Y) THEN GOTO 8480
8530 NEXT Y
8540 NEXT X
8545 LET MV=0
8550 IF Z=0 THEN GOTO 8590
8560 PRINT AT 5,0;"ANALYSIS RESULTS-"
8570 PRINT AT 6,0;Z;" PIECES IN ERROR"
8580 GOTO 3450
8590 IF TM>0 THEN GOTO 3450
8600 PRINT AT 5,0;"C O N G R A T U L A T I O N S"
8610 PRINT AT 6,0;"YOU SOLVED THE PUZZLE"
8620 PRINT AT 7,0;"ENTER YOUR NAME"
8630 PRINT AT 8,0;"PRESS ENTER"
8635 SLOW
8640 INPUT S$(1 TO 20)
8650 LET TM=M
8660 LET M=0
8670 PRINT AT 2,11;S$( TO 20)
8680 PRINT AT 3,11;"IN ";TM;" MOVES"
8690 PRINT AT 7,0;B$( TO 15)
8700 PRINT AT 8,0;B$( TO 15)
8705 PRINT AT 8,18;TM
8710 GOTO 3450
8800 CLS
8803 FAST
8805 GOSUB 8000
8810 GOSUB 8150
8820 PRINT AT 2,12;"AUTHOR";B$( TO 13)
8822 PRINT AT 3,0;B$
8823 PRINT AT 8,25;" "
8824 PRINT AT 21,0;B$
8830 LET SG=1
8840 LET EG=36
8850 LET L=8
8860 LET UL=9
8870 LET UR=10
8880 LET LL=11
8890 LET LR=12
8900 GOSUB 7000
8910 LET L=3
8920 LET UL=4
8930 LET UR=5
8940 LET LL=6
8950 LET LR=7
8955 SLOW
8960 LET K=0
8970 IF INKEY$ ="" THEN GOTO 8970
8980 LET K=CODE INKEY$
8990 IF K=55 THEN GOTO 330
8992 IF K=45 THEN GOSUB 9980
8995 LET K=0
8998 GOTO 8970
9005 LET K=0
9010 GOTO 3450
9500 CLS
9510 GOSUB 8000
9520 PRINT AT 5,3;"-----SAVE WITH LOCK----- "
9530 IF S$(21 TO )=" " THEN GOTO 9700
9540 LET X=0
9550 PRINT AT 8,3;"PUZZLE IS ALREADY LOCKED... "
9560 PRINT AT 9,3;" S-SAVE WITH CURRENT LOCKCODE"
9570 PRINT AT 10,3;" R-RETURN TO MENU "
9580 PRINT AT 12,3;"ENTER ONE CODE S/R "
9590 LET K=0
9600 IF INKEY$ <>"" THEN GOTO 9600
9610 PRINT AT 12,22;CHR$ 8
9620 PRINT AT 12,22;CHR$ 0
9630 IF INKEY$ ="" THEN GOTO 9610
9640 LET K=CODE INKEY$
9650 IF K=56 THEN GOTO 9830
9660 IF K=55 THEN GOTO 330
9670 PRINT AT 12,3;"INCORRECT CODE..REENTER "
9680 FOR X=1 TO 25
9685 NEXT X
9690 GOTO 9580
9700 PRINT AT 8,3;"ENTER A FOUR CHARACTER LOCK "
9710 PRINT AT 9,3;"CODE--PRESS ENTER "
9720 INPUT H$(1 TO 4)
9730 PRINT AT 8,3;"YOUR LOCK CODE IS ";H$;" "
9740 PRINT AT 9,3;"MAKE A NOTE OF IT "
9750 LET S$(21 TO )=H$
9760 GOTO 9830
9800 CLS
9810 GOSUB 8000
9820 PRINT AT 5,3;"---SAVE WITHOUT LOCK----"
9822 IF S$(21 TO )=" " THEN GOTO 9830
9824 PRINT AT 9,3;"SAVING WITH CURRENT LOCKCODE"
9830 PRINT AT 12,3;"ENTER A FILE NAME "
9840 PRINT AT 13,3;"PRESS ENTER TO BEGIN SAVE"
9850 INPUT X$
9890 SAVE X$
9900 CLS
9910 PRINT AT 12,3;"PRESS ANY KEY TO BEGIN "
9914 IF INKEY$ <>"" THEN GOTO 9914
9918 IF INKEY$ ="" THEN GOTO 9918
9920 GOTO 20
9950 PRINT AT 5,0;B$
9955 PRINT AT 6,0;B$
9960 PRINT AT 7,0;B$( TO 15)
9965 PRINT AT 7,0;B$( TO 15)
9970 LET K=0
9975 RETURN
9980 COPY
9982 LET K=0
9985 RETURN
3 REM "*DOUBLE INVERSION*"
5 REM "*A VSSP PUZZLE*"
7 REM "*COPYRIGHT 1982*"
8 REM "*N.L.MARTINO*"
10 DIM T(68,12)
11 LET S$=" "
12 LET TM=0
13 LET P=17
15 LET M=0
16 LET H$=" "
17 LET B$=" "
20 LET Z=0
110 LET SG=1
130 LET EG=68
140 LET I=1
150 LET K=0
160 LET A=0
170 LET B=0
180 LET C=0
190 LET D=0
200 LET ES=0
210 LET MV=0
220 LET X=0
230 LET Y=0
240 LET L=3
250 LET UL=4
260 LET UR=5
270 LET LL=6
280 LET LR=7
330 CLS
335 GOSUB 8020
340 PRINT AT 7,3;"------PUZZLE MENU-------"
350 PRINT AT 9,3;" B-BEGIN/CONTINUE "
360 PRINT AT 11,3;" D-DISPLAY A SOLUTION"
370 PRINT AT 13,3;" L-SAVE WITH LOCK "
380 PRINT AT 15,3;" S-SAVE "
390 PRINT AT 17,3;"ENTER ONE CODE B/D/L/S "
400 LET K=0
410 IF INKEY$ <>"" THEN GOTO 410
420 PRINT AT 17,26;CHR$ 8
422 FOR X=1 TO 2
426 NEXT X
430 PRINT AT 17,26;CHR$ 0
432 FOR X=1 TO 2
436 NEXT X
440 IF INKEY$ ="" THEN GOTO 420
450 LET K=CODE INKEY$
460 IF K=39 THEN GOTO 530
470 IF K=41 THEN GOTO 8800
480 IF K=49 THEN GOTO 9500
490 IF K=56 THEN GOTO 9800
500 PRINT AT 17,3;"INCORRECT CODE..REENTER "
510 FOR X=1 TO 50
515 NEXT X
520 GOTO 390
530 IF S$(21 TO )=" " THEN GOTO 700
540 LET X=0
542 PRINT AT 19,2;B$( TO 30)
550 PRINT AT 20,2;" PUZZLE IS LOCKED... "
560 PRINT AT 21,2;" ENTER LOCK CODE-PRESS ENTER"
570 INPUT H$(1 TO 4)
580 IF H$(1 TO 4)<>S$(21 TO ) THEN GOTO 610
590 LET S$(21 TO )=" "
600 GOTO 700
610 LET X=X+1
630 PRINT AT 21,3;H$;" IS NOT VALID-REENTER "
640 FOR Y=1 TO 50
643 NEXT Y
645 IF X>2 THEN GOTO 660
650 GOTO 560
660 PRINT AT 19,2;"THERE HAVE BEEN 3 UNSUCCESSFUL"
670 PRINT AT 20,2;"ATTEMPTS TO UNLOCK THE PUZZLE"
680 PRINT AT 21,2;"ENTER MENU CODE B TO TRY AGAIN"
690 GOTO 400
700 CLS
702 FAST
704 GOSUB 8000
708 GOSUB 8150
710 LET SG=1
720 LET EG=68
730 GOSUB 7000
740 GOTO 3300
1000 IF INKEY$ ="" THEN GOTO 3450
1020 LET K=CODE INKEY$
1030 IF K=55 THEN GOTO 330
1032 IF K=40 THEN GOSUB 9950
1034 IF K=38 THEN GOTO 8350
1036 IF K=45 THEN COPY
1040 IF K>32 AND K<37 THEN GOTO 2000
1050 IF K>111 AND K<116 THEN GOTO 2000
1055 LET K=0
1060 GOTO 3450
2000 FAST
2005 IF K=36 THEN GOTO 2100
2010 IF K=33 THEN GOTO 2120
2020 IF K=34 THEN GOTO 2300
2030 IF K=35 THEN GOTO 2320
2040 IF K=115 THEN GOTO 4000
2050 IF K=114 THEN GOTO 4020
2060 IF K=113 THEN GOTO 5000
2070 IF K=112 THEN GOTO 5020
2075 LET K=0
2080 GOTO 3450
2100 LET I=1
2110 GOTO 2130
2120 LET I=-1
2130 LET X=P
2140 LET X=X+I
2150 IF X<1 OR X>68 THEN GOTO 9000
2160 IF T(X,1)<>T(P,1) THEN GOTO 9000
2170 IF T(X,L)=0 OR T(X,UL)=8 THEN GOTO 2140
2180 LET P=X
2190 GOTO 3300
2300 LET I=16
2305 LET MV=0
2310 GOTO 2330
2315 LET MV=0
2320 LET I=-16
2330 LET X=P+I
2340 IF X>68 THEN GOTO 9000
2345 IF X<1 THEN LET X=1
2350 IF T(X,UL)<>8 AND T(X,L)>0 THEN GOTO 2450
2360 IF T(X,UL)<>8 THEN GOTO 2366
2362 LET Y=1
2363 IF P+I<1 THEN GOTO 2470
2364 GOTO 2370
2366 LET Y=-1
2370 LET MV=MV+1
2372 LET X=P+I
2375 LET X=X+Y
2380 IF X<1 OR X>68 THEN GOTO 2420
2390 IF T(X,1)<>T(P+I,1) THEN GOTO 2420
2400 IF T(X,UL)<>8 AND T(X,L)>0 THEN GOTO 2450
2410 GOTO 2375
2420 IF MV>=2 THEN GOTO 9000
2430 IF Y>0 THEN GOTO 2366
2440 GOTO 2362
2445 LET MV=0
2450 LET P=X
2455 LET MV=0
2460 GOTO 3300
2470 LET X=X+Y
2480 IF T(X,UL)<>8 AND T(X,L)>0 THEN GOTO 2450
2490 IF X>3 THEN GOTO 9000
2500 GOTO 2470
3300 LET ES=P+T(P,L)-1
3305 LET K=0
3310 IF T(P,UL)=129 OR T(P,UL)=130 THEN LET A=T(P,UL)
3320 IF T(P,UL)<129 OR T(P,UL)>130 THEN LET A=T(P,UL)-19
3330 IF T(ES,UR)=129 OR T(ES,UR)=130 THEN LET B=T(ES,UR)
3340 IF T(ES,UR)<129 OR T(ES,UR)>130 THEN LET B=T(ES,UR)-18
3350 IF T(P,LL)=129 OR T(P,LL)=130 THEN LET C=T(P,LL)
3360 IF T(P,LL)<129 OR T(P,LL)>130 THEN LET C=T(P,LL)-19
3370 IF T(ES,LR)=129 OR T(ES,LR)=130 THEN LET D=T(ES,LR)
3380 IF T(ES,LR)<129 OR T(ES,LR)>130 THEN LET D=T(ES,LR)-18
3400 LET Z=PEEK 16396+256*PEEK 16397
3410 LET ULP=Z+(33*T(P,1))+1+T(P,2)
3420 LET URP=Z+(33*T(ES,1))+2+T(ES,2)
3430 LET LLP=ULP+33
3440 LET LRP=URP+33
3450 SLOW
3455 POKE ULP,A
3460 POKE URP,B
3470 POKE LLP,C
3480 POKE LRP,D
3500 IF INKEY$ ="" THEN GOTO 3520
3510 LET K=CODE INKEY$
3520 POKE ULP,T(P,UL)
3530 POKE URP,T(ES,UR)
3540 POKE LLP,T(P,LL)
3550 POKE LRP,T(ES,LR)
3560 IF K>0 THEN GOTO 1030
3570 GOTO 1000
4000 LET I=1
4010 GOTO 4030
4020 LET I=-1
4030 LET X=P
4040 LET X=X+I
4050 IF X<1 OR X>68 THEN GOTO 9000
4060 IF T(X,1)<>T(P,1) THEN GOTO 9000
4070 IF T(X,UL)<>8 THEN GOTO 4040
4080 IF I<0 THEN GOTO 4130
4090 LET SG=X
4100 LET EG=P
4110 LET I=-1
4120 GOTO 4160
4130 LET SG=X
4140 LET EG=P+T(P,L)-1
4150 LET I=1
4160 IF SG=EG THEN GOTO 4220
4170 FOR Z=L TO LR
4180 LET T(SG,Z)=T(SG+I,Z)
4190 NEXT Z
4200 LET SG=SG+I
4210 GOTO 4160
4220 LET T(SG,L)=1
4230 FOR Z=UL TO LR
4240 LET T(SG,Z)=8
4250 NEXT Z
4260 IF P<X THEN LET SG=P
4270 IF P<X THEN LET EG=X
4280 IF P>X THEN LET SG=X
4282 LET M=M+1
4284 PRINT AT 8,18;M
4290 GOSUB 7000
4300 IF I>0 THEN LET P=P-1
4310 IF I<0 THEN LET P=P+1
4320 GOTO 3300
5000 LET I=16
5010 GOTO 5030
5020 LET I=-16
5030 LET X=P+I
5040 IF X<1 OR X>68 THEN GOTO 9000
5050 LET MV=0
5060 IF T(X,UL)=8 THEN GOSUB 5300
5070 IF MV<T(P,L) THEN LET MV=0
5075 IF MV<T(P,L) THEN GOTO 9000
5080 LET SG=P
5090 FOR Z=X TO EG
5100 FOR Y=L TO LR
5110 LET T(Z,Y)=T(SG,Y)
5120 NEXT Y
5130 LET SG=SG+1
5140 NEXT Z
5150 LET EG=P+T(P,L)-1
5160 FOR Z=P TO EG
5170 LET T(Z,L)=1
5180 FOR Y=UL TO LR
5190 LET T(Z,Y)=8
5200 NEXT Y
5210 NEXT Z
5220 IF P<X THEN LET SG=P
5225 IF P<X THEN LET EG=X+T(P,L)-1
5230 IF P>X THEN LET SG=X
5232 IF P>X THEN LET EG=P+T(X,L)-1
5235 LET M=M+1
5237 PRINT AT 8,18;M
5240 GOSUB 7000
5250 LET P=X
5260 GOTO 3300
5300 LET EG=X+T(P,L)-1
5310 FOR Z=X TO EG
5320 IF T(Z,UL)=8 THEN LET MV=MV+1
5330 NEXT Z
5340 RETURN
7000 IF SG>EG THEN RETURN
7010 GOTO 7000+(100*T(SG,L))
7100 PRINT AT T(SG,1),T(SG,2);CHR$ T(SG,UL);CHR$ T(SG,UR)
7130 PRINT AT T(SG,1)+1,T(SG,2);CHR$ T(SG,LL);CHR$ T(SG,LR)
7140 IF T(SG,UL)<>8 THEN GOTO 7500
7150 LET MV=MV-1
7160 IF MV<>0 THEN GOTO 7510
7170 LET SG=P+16
7180 GOTO 7000
7200 PRINT AT T(SG,1),T(SG,2);CHR$ T(SG,UL);CHR$ T(SG,UR);CHR$ T(SG+1,UL);CHR$ T(SG+1,UR)
7210 PRINT AT T(SG,1)+1,T(SG,2);CHR$ T(SG,LL);CHR$ T(SG,LR);CHR$ T(SG+1,LL);CHR$ T(SG+1,LR)
7220 GOTO 7500
7300 PRINT AT T(SG,1),T(SG,2);CHR$ T(SG,UL);CHR$ T(SG,UR);CHR$ T(SG+1,UL);CHR$ T(SG+1,UR);CHR$ T(SG+2,UL);CHR$ T(SG+2,UR)
7310 PRINT AT T(SG,1)+1,T(SG,2);CHR$ T(SG,LL);CHR$ T(SG,LR);CHR$ T(SG+1,LL);CHR$ T(SG+1,LR);CHR$ T(SG+2,LL);CHR$ T(SG+2,LR)
7320 GOTO 7500
7400 PRINT AT T(SG,1),T(SG,2);CHR$ T(SG,UL);CHR$ T(SG,UR);CHR$ T(SG+1,UL);CHR$ T(SG+1,UR);CHR$ T(SG+2,UL);CHR$ T(SG+2,UR);CHR$ T(SG+3,UL);CHR$ T(SG+3,UR)
7410 PRINT AT T(SG,1)+1,T(SG,2);CHR$ T(SG,LL);CHR$ T(SG,LR);CHR$ T(SG+1,LL);CHR$ T(SG+1,LR);CHR$ T(SG+2,LL);CHR$ T(SG+2,LR);CHR$ T(SG+3,LL);CHR$ T(SG+3,LR)
7500 IF MV>0 THEN GOTO 7600
7510 LET SG=SG+T(SG,L)
7520 GOTO 7000
7600 LET SG=SG+16
7610 GOTO 7000
8000 LET Y=1
8010 GOTO 8030
8020 LET Y=5
8030 PRINT AT 0,0;"D O U B L E I N E R S I O N"
8040 PRINT AT 0,18;CHR$ 187
8050 IF Y=1 THEN GOTO 8090
8060 PRINT AT 2,7;"A VSSP PUZZLE"
8070 PRINT AT 3,7;"COPYRIGHT 1982"
8080 PRINT AT 4,10;"N.L.MARTINO"
8090 PRINT AT Y,0;"████████████████████████████████"
8120 RETURN
8150 PRINT AT 9,0;"▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
8190 PRINT AT 7,24;"▄▄▄▄▄▄▄▄"
8210 PRINT AT 7,23;CHR$ 135
8220 PRINT AT 8,23;CHR$ 133
8230 PRINT AT 9,23;CHR$ 129
8250 PRINT AT 18,0;"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
8270 PRINT AT 2,0;"SOLVED BY:"
8290 PRINT AT 7,17;" MOVES"
8295 PRINT AT 8,18;M
8300 PRINT AT 19,0;"(H)ARD COPY (R)ETURN"
8310 PRINT AT 21,0;"(C)LEAR COMMENTS (A)NALYZE"
8312 IF TM=0 THEN GOTO 8320
8314 PRINT AT 2,12;S$( TO 20)
8316 PRINT AT 3,12;"IN ";TM;" MOVES"
8320 RETURN
8350 FAST
8352 LET K=0
8355 IF T(1,UL)=8 AND T(2,UL)=8 AND T(3,UL)=8 AND T(4,UL)=8 THEN GOTO 8390
8360 PRINT AT 5,0;"ANALYSIS INCOMPLETE"
8370 PRINT AT 6,0;" SPACES IN MAIN AREA"
8380 GOTO 3450
8390 LET Z=0
8400 LET SG=5
8410 LET EG=68
8420 FOR X=SG TO EG
8430 IF T(X,L)>0 THEN LET MV=0
8440 FOR Y=UL TO LR
8450 IF T(X,Y+5)=129 OR T(X,Y+5)=130 THEN GOTO 8520
8460 LET Q=T(X,Y+5)-T(X,Y)
8470 IF Q<5 AND Q>-5 THEN GOTO 8530
8480 IF MV=1 THEN GOTO 8530
8490 LET MV=1
8500 LET Z=Z+1
8510 GOTO 8530
8520 IF T(X,Y+5)<>T(X,Y) THEN GOTO 8480
8530 NEXT Y
8540 NEXT X
8545 LET MV=0
8550 IF Z=0 THEN GOTO 8590
8560 PRINT AT 5,0;"ANALYSIS RESULTS-"
8570 PRINT AT 6,0;Z;" PIECES IN ERROR"
8580 GOTO 3450
8590 IF TM>0 THEN GOTO 3450
8600 PRINT AT 5,0;"C O N G R A T U L A T I O N S"
8610 PRINT AT 6,0;"YOU SOLVED THE PUZZLE"
8620 PRINT AT 7,0;"ENTER YOUR NAME"
8630 PRINT AT 8,0;"PRESS ENTER"
8635 SLOW
8640 INPUT S$(1 TO 20)
8650 LET TM=M
8660 LET M=0
8670 PRINT AT 2,11;S$( TO 20)
8680 PRINT AT 3,11;"IN ";TM;" MOVES"
8690 PRINT AT 7,0;B$( TO 15)
8700 PRINT AT 8,0;B$( TO 15)
8702 PRINT AT 8,18;" "
8705 PRINT AT 8,18;M
8710 GOTO 3450
8800 CLS
8803 FAST
8805 GOSUB 8000
8810 GOSUB 8150
8820 PRINT AT 2,12;"AUTHOR";B$( TO 13)
8822 PRINT AT 3,0;B$
8823 PRINT AT 8,18;" "
8824 PRINT AT 21,0;B$
8830 LET SG=1
8840 LET EG=68
8850 LET L=8
8860 LET UL=9
8870 LET UR=10
8880 LET LL=11
8890 LET LR=12
8900 GOSUB 7000
8910 LET L=3
8920 LET UL=4
8930 LET UR=5
8940 LET LL=6
8950 LET LR=7
8955 SLOW
8960 LET K=0
8970 IF INKEY$ ="" THEN GOTO 8970
8980 LET K=CODE INKEY$
8985 IF K=45 THEN COPY
8990 IF K=55 THEN GOTO 330
8995 LET K=0
8998 GOTO 8970
9005 LET K=0
9010 GOTO 3450
9500 CLS
9510 GOSUB 8000
9520 PRINT AT 5,3;"-----SAVE WITH LOCK----- "
9530 IF S$(21 TO )=" " THEN GOTO 9700
9540 LET X=0
9550 PRINT AT 8,3;"PUZZLE IS ALREADY LOCKED... "
9560 PRINT AT 9,3;" S-SAVE WITH CURRENT LOCKCODE"
9570 PRINT AT 10,3;" R-RETURN TO MENU "
9580 PRINT AT 12,3;"ENTER ONE CODE S/R "
9590 LET K=0
9600 IF INKEY$ <>"" THEN GOTO 9600
9610 PRINT AT 12,22;CHR$ 8
9620 PRINT AT 12,22;CHR$ 0
9630 IF INKEY$ ="" THEN GOTO 9610
9640 LET K=CODE INKEY$
9650 IF K=56 THEN GOTO 9830
9660 IF K=55 THEN GOTO 330
9670 PRINT AT 12,3;"INCORRECT CODE..REENTER "
9680 FOR X=1 TO 25
9685 NEXT X
9690 GOTO 9580
9700 PRINT AT 8,3;"ENTER A FOUR CHARACTER LOCK "
9710 PRINT AT 9,3;"CODE--PRESS ENTER "
9720 INPUT H$(1 TO 4)
9730 PRINT AT 8,3;"YOUR LOCK CODE IS ";H$;" "
9740 PRINT AT 9,3;"MAKE A NOTE OF IT "
9750 LET S$(21 TO )=H$
9760 GOTO 9830
9800 CLS
9810 GOSUB 8000
9820 PRINT AT 5,3;"---SAVE WITHOUT LOCK----"
9830 PRINT AT 12,3;"ENTER A FILE NAME "
9840 PRINT AT 13,3;"PRESS ENTER TO BEGIN SAVE"
9850 INPUT X$
9890 SAVE X$
9900 CLS
9910 PRINT AT 12,3;"PRESS ANY KEY TO BEGIN "
9914 IF INKEY$ <>"" THEN GOTO 9914
9918 IF INKEY$ ="" THEN GOTO 9918
9920 GOTO 20
9950 PRINT AT 5,0;B$
9955 PRINT AT 6,0;B$
9960 PRINT AT 7,0;B$( TO 15)
9965 PRINT AT 7,0;B$( TO 15)
9970 LET K=0
9975 RETURN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.