REM PUZZLE
REM
REM 1996-10-02 * [U] STABLE CODE BASED ON THE "PUZZLE.EXE" DOS GAME (BALOONS...)
REM 2012-08-23 * [S] TILES REVISITED

SCREEN 12

DEF SEG = &HA000

DEFINT A-Z: RANDOMIZE TIMER

RESTART:

CLS

REM DIMENSIONALITIES:
REM
REM FULLFRAME BORDER: (10,10) - (416,416)
REM TILES: (10,10)-(110,110) | ONE-PX-BORDER AT 111 | (112,10)-(212,110) | ...
REM EDGES AT: X(Y) = 111, 213, 315

ON (1 + FIX(RND * 2)) GOSUB LOADPIC1, LOADPIC2

DIM VOID(3000)

DIM TILE01(3000), TILE02(3000), TILE03(3000), TILE04(3000)
DIM TILE05(3000), TILE06(3000), TILE07(3000), TILE08(3000)
DIM TILE09(3000), TILE10(3000), TILE11(3000), TILE12(3000)
DIM TILE13(3000), TILE14(3000), TILE15(3000), TILE16(3000)

GET (500, 10)-(600, 110), VOID
GET (10, 10)-(110, 110), TILE01
GET (112, 10)-(212, 110), TILE02
GET (214, 10)-(314, 110), TILE03
GET (316, 10)-(416, 110), TILE04
GET (10, 112)-(110, 212), TILE05
GET (112, 112)-(212, 212), TILE06
GET (214, 112)-(314, 212), TILE07
GET (316, 112)-(416, 212), TILE08
GET (10, 214)-(110, 314), TILE09
GET (112, 214)-(212, 314), TILE10
GET (214, 214)-(314, 314), TILE11
GET (316, 214)-(416, 314), TILE12
GET (10, 316)-(110, 416), TILE13
GET (112, 316)-(212, 416), TILE14
GET (214, 316)-(314, 416), TILE15
GET (316, 316)-(416, 416), TILE16

REDIM PCXARRAY(0 TO 3, 0 TO 3) AS INTEGER

GOSUB PCXARRAYPREPARE
GOSUB PCXARRAYREFRESH
GOSUB PCXARRAYCHECK

LOCATE 2, 55: PRINT "SOLVE THE PUZZLE"
LOCATE 3, 55: PRINT "MOVES = 0"

REM MAIN LOOP
REM
DO: Q$ = INKEY$
    IF Q$ = CHR$(0) + "H" THEN MOVEDIR = 0: GOSUB MOVETILE
    IF Q$ = CHR$(0) + "K" THEN MOVEDIR = 1: GOSUB MOVETILE
    IF Q$ = CHR$(0) + "M" THEN MOVEDIR = 2: GOSUB MOVETILE
    IF Q$ = CHR$(0) + "P" THEN MOVEDIR = 3: GOSUB MOVETILE
    IF Q$ = CHR$(27) THEN EXIT DO
    IF Q$ = CHR$(32) THEN GOTO RESTART
    IF COMPLETED = 15 THEN GOTO GAMECOMPLETED
    LOOP

LOCATE 2, 55: PRINT "TERMINATED              "
LOCATE 3, 55: PRINT "PRESS ANY KEY...        "
LOCATE 4, 55: PRINT "                        "
SLEEP
END

GAMECOMPLETED:
TX = 10 + RX * 102
TY = 10 + RY * 102
TILENUM = REMOVEDTILE
GOSUB PUTTILE

COLOR 12
LOCATE 6, 55: PRINT "GAME COMPLETED"
COLOR 15
LOCATE 2, 55: PRINT "PUZZLE SOLVED!  "
LOCATE 4, 55: PRINT "16 OF 16 TILES COMPLETED"
LOCATE 7, 55: PRINT "PRESS SPACE TO RELOAD"
LOCATE 11, 55: PRINT "                     "

REM WAITING FOR THE SPACE KEY
REM

DO: Q$ = INKEY$
    IF Q$ = CHR$(27) THEN STOP
    IF Q$ = CHR$(32) THEN EXIT DO
    LOOP

GOTO RESTART: REM MIGHT BE MOVED IN PLACE OF "EXIT DO"

MOVETILE:

SWAP X, Y

TX = 10 + X * 102
TY = 10 + Y * 102

SELECT CASE MOVEDIR
CASE 0: REM N
        IF Y < 3 THEN
        MOVES = MOVES + 1
        PCXARRAY(X, Y) = PCXARRAY(X, Y + 1)
        PCXARRAY(X, Y + 1) = 0
        TILENUM = PCXARRAY(X, Y)
        GOSUB PUTTILE
        Y = Y + 1
        PUT (TX, TY + 102), VOID, AND
        END IF
CASE 2: REM W
        IF X > 0 THEN
        MOVES = MOVES + 1
        PCXARRAY(X, Y) = PCXARRAY(X - 1, Y)
        PCXARRAY(X - 1, Y) = 0
        TILENUM = PCXARRAY(X, Y)
        GOSUB PUTTILE
        X = X - 1
        PUT (TX - 102, TY), VOID, AND
        END IF
CASE 1: REM E
        IF X < 3 THEN
        MOVES = MOVES + 1
        PCXARRAY(X, Y) = PCXARRAY(X + 1, Y)
        PCXARRAY(X + 1, Y) = 0
        TILENUM = PCXARRAY(X, Y)
        GOSUB PUTTILE
        X = X + 1
        PUT (TX + 102, TY), VOID, AND
        END IF
CASE 3: REM S
        IF Y > 0 THEN
        MOVES = MOVES + 1
        PCXARRAY(X, Y) = PCXARRAY(X, Y - 1)
        PCXARRAY(X, Y - 1) = 0
        TILENUM = PCXARRAY(X, Y)
        GOSUB PUTTILE
        Y = Y - 1
        PUT (TX, TY - 102), VOID, AND
        END IF
END SELECT

SWAP X, Y

LOCATE 3, 55: PRINT "MOVES ="; MOVES

GOSUB PCXARRAYCHECK

RETURN

PCXARRAYCHECK:
COMPLETED = 0
CX = 1
FOR PY = 0 TO 3
FOR PX = 0 TO 3
IF PCXARRAY(PX, PY) = CX THEN COMPLETED = COMPLETED + 1
CX = CX + 1
NEXT: NEXT
LOCATE 4, 54: PRINT COMPLETED; "OF 16 TILES COMPLETED"
RETURN

PCXARRAYPREPARE:

COMPLETED = 0
MOVES = 0

TILE = 0
X = FIX(RND * 4): REM 0 1 2 3
Y = FIX(RND * 4)

FOR PX = 0 TO 3
        FOR PY = 0 TO 3
                TILE = TILE + 1
                PCXARRAY(PX, PY) = TILE
        NEXT: NEXT

REMOVEDTILE = PCXARRAY(Y, X)

REM REMEMBER THE POSITION OF THE REMOVED TILE
REM

RY = Y
RX = X
PCXARRAY(Y, X) = 0

LOCATE 2, 55: PRINT "PRESS SPACE TO RESHUFFLE"

DO: Q$ = INKEY$
    IF Q$ = CHR$(27) THEN STOP
    IF Q$ = CHR$(32) THEN EXIT DO
    LOOP

LOCATE 2, 55: PRINT "                        ": REM CLEARING

LOCATE 2, 55: PRINT "RESHUFFLING...          "

MISSINGMAP:
LOCATE 7, 55: PRINT "MISSING ELEMENT:"

FOR PX = 0 TO 3
FOR PY = 0 TO 3
        IF PCXARRAY(PY, PX) > 0 THEN
        LINE (432 + PX * 10, 117 + PY * 10)-(440 + PX * 10, 125 + PY * 10), 2, BF
        LINE (432 + PX * 10, 117 + PY * 10)-(440 + PX * 10, 125 + PY * 10), 10, B
        ELSE
        LINE (432 + PX * 10, 117 + PY * 10)-(440 + PX * 10, 125 + PY * 10), 12, B
        END IF

        NEXT: NEXT

LOCATE 11, 55: PRINT "PRESS SPACE TO RELOAD"

RANDOMWALK:

FLAGN = 1
FLAGS = 1
FLAGW = 1
FLAGE = 1

REM NUMBER OF RANDOM WALKS ON THE SQUARE ** AGE OF AQUARIUS
REM
FOR K = 1 TO 256

        DIRECTION = FIX(RND * 4)

        SELECT CASE DIRECTION

               CASE 0: REM N
               IF Y > 0 AND FLAGN = 1 THEN
                  FLAGN = 1
                  FLAGS = 0: REM CANNOT GO BACK NORTH...
                  FLAGW = 1: REM
                  FLAGE = 1: REM MAY BE CHANGED TO BIT-LIKE STRUCTURE
                  PCXARRAY(Y, X) = PCXARRAY(Y - 1, X)
                  PCXARRAY(Y - 1, X) = 0
                  Y = Y - 1
                  END IF

               CASE 1: REM S
               IF Y < 3 AND FLAGS = 1 THEN
                  FLAGN = 0
                  FLAGS = 1
                  FLAGW = 1
                  FLAGE = 1
                  PCXARRAY(Y, X) = PCXARRAY(Y + 1, X)
                  PCXARRAY(Y + 1, X) = 0
                  Y = Y + 1
                  END IF

               CASE 2: REM W
               IF X > 0 AND FLAGW = 1 THEN
                  FLAGN = 1
                  FLAGS = 1
                  FLAGW = 1
                  FLAGE = 0
                  PCXARRAY(Y, X) = PCXARRAY(Y, X - 1)
                  PCXARRAY(Y, X - 1) = 0
                  X = X - 1
                  END IF

               CASE 3: REM E
               IF X < 3 AND FLAGE = 1 THEN
                  FLAGN = 1
                  FLAGS = 1
                  FLAGW = 0
                  FLAGE = 1
                  PCXARRAY(Y, X) = PCXARRAY(Y, X + 1)
                  PCXARRAY(Y, X + 1) = 0
                  X = X + 1
                  END IF

        END SELECT

        NEXT

RETURN

PUTTILE:
'PUT (TX, TY), VOID, AND
SELECT CASE TILENUM
       CASE 0: PUT (TX, TY), VOID, PSET
       CASE 1: PUT (TX, TY), TILE01, PSET
       CASE 2: PUT (TX, TY), TILE02, PSET
       CASE 3: PUT (TX, TY), TILE03, PSET
       CASE 4: PUT (TX, TY), TILE04, PSET
       CASE 5: PUT (TX, TY), TILE05, PSET
       CASE 6: PUT (TX, TY), TILE06, PSET
       CASE 7: PUT (TX, TY), TILE07, PSET
       CASE 8: PUT (TX, TY), TILE08, PSET
       CASE 9: PUT (TX, TY), TILE09, PSET
       CASE 10: PUT (TX, TY), TILE10, PSET
       CASE 11: PUT (TX, TY), TILE11, PSET
       CASE 12: PUT (TX, TY), TILE12, PSET
       CASE 13: PUT (TX, TY), TILE13, PSET
       CASE 14: PUT (TX, TY), TILE14, PSET
       CASE 15: PUT (TX, TY), TILE15, PSET
       CASE 16: PUT (TX, TY), TILE16, PSET
END SELECT
RETURN

PCXARRAYREFRESH:
FOR PX = 0 TO 3
FOR PY = 0 TO 3
TILENUM = PCXARRAY(PX, PY)
TX = 10 + PX * 102
TY = 10 + PY * 102
GOSUB PUTTILE

NEXT: NEXT

RETURN

REM
REM LOAD PICTURES:
REM

LOADPIC1:
LINE (10, 10)-(416, 416), 7, B
LINE (11, 11)-(415, 415), 8, BF
LINE (20, 20)-(222, 222), 9, B
LINE (21, 21)-(221, 221), 1, BF
LINE (150, 150)-(400, 400), 10, BF
LINE (151, 151)-(399, 399), 2, BF
LINE (220, 220)-(250, 250), 12, BF
LINE (221, 221)-(249, 249), 4, BF
LINE (106, 106)-(116, 116), 13, BF
LINE (107, 107)-(115, 115), 5, BF

REM TILE BORDERS:
REM VERTICAL
LINE (111, 10)-(111, 416), 0, B: REM THESE TWO LINES CAN BE DONE USING ONE:
LINE (213, 10)-(213, 416), 0, B: REM LINE (111, 9)-(213, 417), 0, B
LINE (315, 10)-(315, 416), 0, B: REM BUT IT'S UNCLEAR... :)
REM HORIZONTAL
LINE (10, 111)-(416, 111), 0, B: REM AS ABOVE...
LINE (10, 213)-(416, 213), 0, B
LINE (10, 315)-(416, 315), 0, B
RETURN

LOADPIC2:
BLOAD "PUZZLE_1.VGA", 0
RETURN

