Twists

Developer(s): Paul Clansey
Date: 1984
Type: Program
Platform(s): TS 2068
Tags: Game

A sliding-tile puzzle against the clock. The board is a four-by-four grid in four colour blocks: red, yellow, green and blue quarters. Thirty random twists scramble it. Keys a–d shift a column up, i–l shift a column down, e–h shift a row left and m–p shift a row right; each shift wraps the end tile round to the other side. The keys are labelled with arrows round the board. Press Q when you think you are done: a solved board shows your time in seconds, and an unsolved one says INCOMPLETE and the game starts over.

A REM credits Paul Clansey and ZX Computing, February/March 1984.

Program Analysis

Structure

  • Lines 1–2: a REM holding the machine code, and a loop that POKEs the 44 code bytes from DATA lines 6–8 to 26715.
  • Lines 20–55: set up the target board in a(4,4), define four arrow UDGs and draw the frame.
  • Lines 65–73: the scramble and the key loop. GO TO (CODE INKEY$)+3 sends keys a–p to lines 100–115, which set the row or column and jump to one of four shift routines at lines 82–85.
  • Lines 116–125: redraw the board. Lines 75–81: stop the clock and check the board.

Machine code

The routine at 26715 fills a four-by-four block of attribute cells with one colour. Line 120 POKEs the colour and the block’s column and row into the code and calls it with USR 26715 for each of the sixteen tiles. 26715 is where the text of the first REM line sits on the TS2068 (it is 23760 on a Spectrum), so this listing is a 2068 version.

Notable Techniques

  • Key dispatch by computed GO TO on the key code.
  • The timer reads the three-byte FRAMES counter (23672–23674) and divides by 60.
  • DATA lines 11–12 use the variable Z as an item, which takes whatever value was last READ into z.

Potential Issues

  • The scramble picks a line with GO TO INT (RND*16+97). Lines 97–99 do not exist, so those three values fall through to line 100, and the first column is shifted far more often than the others.

This program came from an Oliger (JLO SAFE) disk, a copy of the SNUG library disk 17/18, and was converted to load from tape. The disk copy started at line 10, which skipped the machine code loader in line 2 and the DIM in line 5 and stopped with “2 Variable not found”; the tape version starts at line 1. It was tested in ZEsarUX, scrambling the board and twisting a column.

Related Content

Image Gallery

Source Code

    1 REM >@! OUT W MERGE A# MOVE B RESTORE HCw# LLIST MERGE MOVE A<>xxxxxxxxxxx
    2 FOR n=26715 TO 26758: READ a: POKE n,a: NEXT n
    3 REM >>  TWISTS  <<                                         * ZX COMPUTING,     Feb/Mar 1984         by Paul Clansey         
    5 RANDOMIZE : DIM a(4,4)
    6 DATA 62,64,1,0,0,17,4,4,33,223,87,213,17,32,0,4,25,16,253
    7 DATA 65,4,35,16,253,209,66,229,72,67,119,35,16,252,225,213
    8 DATA 17,32,0,25,209,65,16,239,201
   10 DATA 16,16,48,48,16,16,48,48,32,32,8,8,32,32,8,8
   11 DATA 0,8,28,42,8,Z,0,Z,Z,Z,8,Z,42,28,8,0
   12 DATA 0,16,32,124,32,16,0,Z,Z,8,4,62,4,8,0,Z
   20 RESTORE 10: FOR y=1 TO 4: FOR x=1 TO 4: READ z: LET a(x,y)=z: NEXT x: NEXT y
   21 FOR f=0 TO 31: READ z: POKE USR "a"+f,z: NEXT f
   25 BORDER 0: PAPER 5: CLS 
   26 PRINT AT 2,9;"aa  ba  ca  da  ";AT 19,9;"lb  kb  jb  ib"
   27 PRINT AT 4,7;"p";AT 4,24;"e";AT 8,7;"o";AT 8,24;"f"
   28 FOR n=5 TO 17 STEP 4: PRINT AT n,7;"c";AT n,24;"d": NEXT n
   29 PRINT AT 12,7;"n";AT 12,24;"g"
   30 PRINT AT 16,7;"m";AT 16,24;"h"
   31 FOR n=3 TO 10: PRINT PAPER 2;AT n,8;"        "; PAPER 6;"        ": NEXT n: FOR n=11 TO 18: PRINT PAPER 4;AT n,8;"        "; PAPER 1;"        ": NEXT n
   45 FOR n=64 TO 216 STEP 32: PLOT n,24: DRAW 0,127: PLOT 64,n-40: DRAW 127,0: NEXT n
   55 PRINT AT 10,28; PAPER 2;" "; PAPER 6;" ";AT 11,28; PAPER 4;" "; PAPER 1;" "
   61 PRINT AT 0,0;" PRESS ANY KEY TO PLAY."
   62 IF INKEY$<>"" THEN GO TO 62
   63 IF INKEY$="" THEN GO TO 63
   64 PRINT AT 0,0,,: LET fg=30
   65 LET fg=fg-1: GO TO INT (RND*16+97)
   70 IF INKEY$="" THEN GO TO 70
   71 IF INKEY$="q" THEN GO TO 75
   72 IF CODE INKEY$<97 OR CODE INKEY$>112 THEN GO TO 70
   73 GO TO ((CODE INKEY$)+3)
   75 RESTORE 10: LET t=(256*256*PEEK 23674+256*PEEK 23673+PEEK 23672)/60-t
   76 FOR y=1 TO 4: FOR x=1 TO 4: READ z: IF z<>a(x,y) THEN GO TO 80
   77 NEXT x: NEXT y
   78 PRINT AT 21,0,, FLASH 1;AT 21,10;"TIME: ";t: GO TO 61
   80 PRINT AT 21,0,,: PRINT AT 21,10;"INCOMPLETE"
   81 FOR n=1 TO 500: NEXT n: RESTORE 10: GO TO 20
   82 LET v=a(ar,1): FOR n=1 TO 3: LET a(ar,n)=a(ar,n+1): NEXT n: LET a(ar,n)=v: GO TO 116
   83 LET v=a(4,ar): FOR n=4 TO 2 STEP -1: LET a(n,ar)=a(n-1,ar): NEXT n: LET a(n,ar)=v: GO TO 116
   84 LET v=a(ar,4): FOR n=4 TO 2 STEP -1: LET a(ar,n)=a(ar,n-1): NEXT n: LET a(ar,n)=v: GO TO 116
   85 LET v=a(1,ar): FOR n=1 TO 3: LET a(n,ar)=a(n+1,ar): NEXT n: LET a(n,ar)=v: GO TO 116
  100 LET ar=1: GO TO 82
  101 LET ar=2: GO TO 82
  102 LET ar=3: GO TO 82
  103 LET ar=4: GO TO 82
  104 LET ar=1: GO TO 83
  105 LET ar=2: GO TO 83
  106 LET ar=3: GO TO 83
  107 LET ar=4: GO TO 83
  108 LET ar=4: GO TO 84
  109 LET ar=3: GO TO 84
  110 LET ar=2: GO TO 84
  111 LET ar=1: GO TO 84
  112 LET ar=4: GO TO 85
  113 LET ar=3: GO TO 85
  114 LET ar=2: GO TO 85
  115 LET ar=1: GO TO 85
  116 IF fg=0 THEN GO TO 120
  117 IF fg>1 THEN GO TO 65
  118 LET fg=0: PRINT AT 21,0;" Press 'Q' to stop clock.": LET t=VAL "(256*256*PEEK 23674+256*PEEK 23673+PEEK 23672)/60"
  120 FOR y=1 TO 4: FOR x=1 TO 4: POKE 26716,a(x,y): POKE 26718,8+4*(x-1): POKE 26719,3+4*(y-1): LET q=USR 26715: NEXT x: NEXT y
  125 GO TO 70

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