Classic Computer Magazine Archive COMPUTE! ISSUE 72 / MAY 1986 / PAGE 79

Amiga Puzzle

Bill Boegelein

The following programs provide you with an entertaining puzzle game that pops up as a small window on the Workbench screen. But more importantly, they demonstrate some interesting and powerful programming techniques in Amiga BASIC.


A popular game that used to keep kids occupied for hours in the back of the station wagon was known as the "slide puzzle." This was simply a plastic frame with 15 numbered or lettered tiles arranged in a 4 X 4 pattern with one square left vacant. The object was to slide one tile at a time into the vacant slot in an attempt to restore the puzzle to its proper numeric or alphabetic order. "Amiga Puzzle" is the Amiga BASIC equivalent of the slide puzzle.
    Amiga Puzzle works on any Amiga with Amiga Microsoft BASIC (not ABasiC-Amiga BASIC is available as a free upgrade if your computer was shipped with ABasiC). To get started, run Amiga BASIC, enter Program 1 below, and save a copy on disk. Be sure to set Preferences for a 60-column screen before running Amiga Puzzle. When you run the program, it pops open as a small window on the Workbench screen and scrambles the tiles. When the program announces "Ready" using the Amiga's built-in speech capability, you can begin.
    To move a tile into the vacant slot, point to the tile with the mouse and press the left mouse button. If you try to cheat by moving a tile diagonally, the program will scold you. The gadget in the lower-right corner of the window, normally reserved for window resizing, has been replaced with a plus sign in Amiga Puzzle. Clicking on this gadget rescrambles the puzzle and starts a new game. The other gadgets (front/back, the move bar, and dose window) are all active as usual.
    As a final touch, the Puzzle window displays the elapsed time and number of moves since the start of the game.

multitasking capabilities
This photo shows two copies of "Amiga
Puzzle" running simultaneously, an ex-
ample of the Amiga's multitasking
capabilities.

How It Works
Amiga Puzzle was adapted from a similar puzzle game available on the Macintosh. Those of you familiar with Microsoft BASIC 2.0 on the Macintosh will immediately see many similarities in Amiga BASIC. In fact, many Macintosh BASIC programs can be converted to Amiga BASIC with little effort. Both languages support windows, pull-down menus, labels, many types of graphics commands, and other features.
    Amiga Puzzle is divided into seven subroutines named Done, Init, DrawScreen, Mix, Play, CheckCheat, and More. There are also two small subprograms, Talk and Position. Here are descriptions of what these subroutines do:

    Init: initializes variables, userdefined functions, and loads the puzzle's characters A-O into the two-dimensional array c0.

    DrawScreen: displays the puzzle's squares and characters.

    Mix: mixes only adjacent squares and keeps track of the blank square's position in variables blankX and blankY.

    Play: the main subroutine where the current mouse position is compared to coordinates of each square stored in the three-dimensional array rat.

    CheckCheat: makes sure the attempted move is a legal one (adjacent squares only, no diagonal moves).

    More: checks if the mouse is clicked on the plus-sign gadget in Amiga Puzzle's lower-right corner. If so, the program starts a new game by jumping back to Start.

    Done: ends the program and returns control to BASIC.

Special Features
Most of the program is standard Microsoft BASIC. The only lines that merit special attention are the user-defined functions in the Init subroutine. One function operates the puzzle's timer, and the other determines if the puzzle has been solved.
    A quick way to time any event is to define a function that subtracts the current time from the initial starting time. This is done with the function FNlaps. The current time is obtained from TIMER and the initial time stored in the variable starttime.
    The other defined function, FNwin, determines if the puzzle has been solved by comparing the letter in each tile-stored in the array c0-with the characters A-O. Each letter in the correct position returns a value of -1 (true). So the puzzle has been solved when all 15 letters are sorted, returning a value of -15.
    A very powerful feature of Amiga BASIC is its subprogram capability (see "Requester Windows in Amiga BASIC," COMPUTE!, March 1986). In effect, subprograms let you add new commands to the language. The word TALK is not a command in Amiga BASIC, but has been added to Amiga Puzzle as a subprogram. It lets you execute both a SAY command and the text-to-speech TRANSLATE$ function by simply typing TALK followed by the desired string. Similarly, POSITION is a subprogram that expects parameters of the X and Y coordinates as the location to PRINT the desired string.
    Program 2, "MakeIcon," lets you create a special icon for Amiga Puzzle. This is optional, of course, since Amiga BASIC automatically assigns a standard icon when you save the program. MakeIcon recreates the special icon I designed with the Amiga's Icon Editor (a new feature that's included with the free upgrade to version 1.1 of the operating system). The icon data is converted from the hexadecimal values in the DATA statements into singlebyte values and stored in the file Puzzle.info (all Amiga icon files end with.info). In addition to the icon's shape and color, the special data also contains information that makes Amiga BASIC the program's default tool. That means when the icon is clicked on the Workbench screen, Amiga BASIC is automatically loaded and run prior to loading and running the game.

Multitasking With BASIC
Since multitasking is built into the Amiga's operating system as a standard feature, no special programming techniques are required to write a BASIC program that's capable of running simultaneously with other tasks. Feel free to move Amiga Puzzle over or under other windows running different programs without causing interference. If your computer has at least 512K RAM, you can even click on the Amiga Puzzle icon a second time and run two of the games at once.


Program 1: Amiga Puzzle

Start::←
GOSUB Init←
GOSUB DrawScreen←
GOSUB Mix←
WHILE WINDOW(7)<>0←
GOSUB Play←
WEND←
Done:,←
BEEP:WINDOW CLOSE 2:WINDOW 1←
END←
Init: ←
DEFINT a-z←
Talk " " ←
WINDOW l,"Puzzle",(230,48)-(230+13
8,48+96),30←
tries= 0:RANDOMIZE TIMER ←
FOR y=0 TO 3←
FOR x=0 TO 3←
c(x,y)=x+y4+ASC("A") 'Load oharac
ters←
NEXT x←
NEXT y←
blankX=x-1:blankY=y-1←
cCblankX,blankY)=ASC("  ") ←
DEF FNlapsl=((TIMER-starttimel)\60)
+(((TIMER-starttimel) MoD 60)/100)←
DEF FNa=(c(0,0)=65)+(c(l,0)=66)+(
c(2,0)=67)+(c(3,0)=68)←
DEF FNb=(c(0,1)=69)+(c(1,1)=70)+(
c(2,1)=71) +(c(3,1)= 72)←
DEF FNc=(c(0,2)=73)+(c(1,2)=74)+(c
(2,2)=78)+(c(3,2)=76)←
DEF FNd=(c(0,3)=77)+(c(1,3)=78)+(
c(2,3)=79)+(c(3,3)=80)←
DEF FNwin=(FNa+FNb+FNc+FNd
)'Won if = -15←
RETURN←
DrawScreen:←
FOR y=0 TO 3←
FOR x=0 TO 3 ←
Position (x+l)"3,(y+l)'2,CHR$(c(x,y
)) ' Print characters←
x1=x'30+10:y1=y'18+3' Drawboxes

LINE (xl,yl)-(xl+30,y1+18),l,b←
LINE (xl-l,yl-l)-(xl +30+ l,yl + 18+ 1)
,l,b←
LINE (10-6,3-3)-(4'30+10+8,4'18+3+
3),l,b←
moreX=128:moreY=89←
LINE (moreX,moreY)-(moreX+l0,more
Y+10),l,bf  ←
Position 14,11,"+" ' New game gadget ←
rat(x,y,0)=xl:rat(x,y, l)=y1←
NEXT x←
NEXT y ←
Position 3,10,"TIME 0.00" ←
Position 3,11,"TRIES 0" ←
RETURN←
Mix:←
x=biankX:y=blankY ←
FOR mixing=333 TO 1 STEP -1 ←
IF (mixing AND 1)=0 THEN←
x=INT(RND'4):y=blankY ' Even←
ELSE←
y=INT(RND'4):x=blankX ' Odd←
END IF←
C30SUB CheckCheat←
NEXT mixing ←
Talk "Ready." ←
starttimel =TIMER←
RETURN←
Play:←
LOCATE 10,8:PRINT USING "##.##";FN1
apsl;←
WHILE MOUSE(0)<>0←
mouseX=MOUSE(3):mouseY=MOUSE(
4)←
FOR y=0 TO 3←
FOR x=0 TO 3 ←
IF (mouseX>rat(x,y,0) AND mouseX<r
at(x,y,0)+30) AND (mouseY>rat(x,y,l
) AND mouseY<rat(x,y,l)+18) THE
N GOSUB CheckCheat:RETURN←
NEXT x←
NEXT y ←
GOSUB More ←
WEND←
RETURN←
CheckCheat::←
IF (ABS(x-blankX)> 1 OR ABS(y-blankY)
>1) OR ((x<>blankX AND y<>blankY)
) THEN←
IF mixing=0 THEN Talk "Cheater." 'Ch
eating←
ELSE 'Not cheating←
SWAP c(x,y),c(blankX,blankY)←
Position (x+1)•3,(y+1)•2,CHR$(c(x,y))

SWAP x,blankX:SWAP y,blankY←
Position (x+l)•3,(y+l)'2,CHR$(c(x,y))

END IF←
IF mixing=0 THEN←
tries =tries +1 ←
LOCATE 11,8:PRINT tries; ←
WHILE MOUSE(0)<>0:WEND←
IF FNwin=.15 THEN Talk "We have a wi
nner.":GOTO More←
END IF←
RETURN←
More: ←
WHILE MOUSE(0)<>0 OR FNwin=.15'A
nother game?←
mouseX=MOUSE(3):mouseY=MOUSE(
4)←
IF MOUSE(0)=0 AND (mouseX>more
X AND mouseX<moreX+ 10) AND (mou
seY>moreY AND mouseY<moreY+10
) THEN GOTO Start←
IF WINDOW(7)=0 THEN Done ←
WEND←
RETURN←
SUB Talk(a$) STATIC ←
SAY TRANSLATE$(a$)←
END SUB←
SUB Position(x,y,a$) STATIC ←
LOCATE y,x:PRINT a$;←
END SUB←


Program 2: Makelcon

WIDTH 60←
PRINT:PRINT SPC(20);"Creating Puzzl
e Icon":PRINT←
DEFINT a-z←
CLOSE←
OPEN "Puzzle.info" FOR OUTPUT AS 2←
FOR ii =1 TO 98←
READ long$←
FOR i=1 TO 8 STEP 2←
byte$=MID$(long$,i,2)←
PRINT byte$;←
HX byte$←
tmp=VAL(byte$)←
checksum=checksum+tmp←
PRINT #2,CHR$(tmp);←
NEXT i←
NEXT ii←
CLOSE ←
KILL "Puzzle.info.info"' Delete icon's is
on←
IF checksum<>12063 THEN BEEP:PRI
NT:PRINT "Error in data statements."←
END←
SUB HX(a$) STATIC ` STR$ hex to dec (m
ax=FFFF)←
a$=UCASE$(a$):n=0:ans=0 ←
FOR i=1 TO LEN(a$)←
c=ASC(MID$(a$,i, l))←
n=VAL(CHR$(c))←
IF c>ASC("9") THEN n=(VAL(CHR$(
c-17)))+ 10←
ans=ans*16+n←
NEXT i ←
a$=STR$(ans)←
END SUB←
' Puzzle Icon data←
DATA E3100001,00000000,00800062,0
0280017←
DATA 00040003,00010001,B8C00000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 04400001,B8F00000,00000000,0
0700000←
DATA 00560000,00000000,00000000,1
0000000←
DATA 00000028,00170002,00021600,0
3000000←
DATA 00000000,00000000,3FFFFFFF,F
0002000←
DATA 00000400,27FFFFFF,E4002404,0
8102400←
DATA 24040810,24002404,08102400,2
7FFFFFF←
DATA E4002418,7E0F2400,243C3319,A
400243C←
DATA 33302400,27663E30,E400247E,3
3302400←
DATA 24C33319,A40024C3,7E0F2400,2
7FFFFFF←
DATA E4002404,08102400,24040810,2
4002404←
DATA 08102400,27FFFFFF,E4002000,0
0000400←
DATA 3FFFFFFF,F0000000,00000000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 00000000,00000000,00000000,0
0000000←
DATA 00000000,00000000,00003A41,6
D696761←
DATA 42415349,43000000←