
' GFXlib 2 declarations.
#include "fbgfx.bi"

DECLARE SUB InitGraphics () ' Sub that loads the game graphics
DECLARE SUB MainMenu () ' Sub where the main menu loop/content is placed
DECLARE SUB PlayGame () ' Sub where the main (piece sliding) loop/code
                        ' is placed
DECLARE SUB SlidePiece (piece_to_slide, slide_direction) 
' Sub where proper "sliding" variables are initiate for
' a specific piece that is about to slide
       
const FALSE = 0
const TRUE = 1

TYPE PieceType
Column AS INTEGER ' Flags the specific piece column inside the puzzle
Row AS INTEGER    ' Flags the specific piece row inside the puzzle
CorrectColumn AS INTEGER ' Flags the piece's correct column inside the puzzle
CorrectRow AS INTEGER ' Flags the piece's correct row inside the puzzle
OldColumn AS INTEGER  ' Flags the piece's old column (used with sliding)
OldRow AS INTEGER     ' Flags the piece's old row (used with sliding)
XPos AS INTEGER       ' XPos and YPos are used during sliding to enable
YPos AS INTEGER       ' the "piece sliding" animation
Sliding AS INTEGER    ' Flags if a piece is sliding or not
SlidingDirec AS INTEGER ' Flags in which direction a specific piece is sliding
PieceBuffer as any ptr  ' Used to hold the graphics data of a specific piece
END TYPE


DIM SHARED ScreenBuffer(10) as any ptr ' Each ScreenBuffer is used to
                                       ' store all 9 images used in the
                                       ' game -> for easier management
                                       ' (memory consumption is
                                       ' irrelevant in a such small
                                       ' program).
DIM SHARED SmallScrnBuffer(10) as any ptr ' Same like the previous buffer
                                          ' but this one holds the
                                          ' smaller versions of images.
DIM SHARED Picture_Piece(36) AS PieceType ' Our puzzle pieces (36 max).
DIM SHARED Tempbuffer AS any ptr ' Temporary buffer used to enable the
                                 ' "broken TV" effect on the small
                                 ' image during the game.

DIM SHARED workpage
DIM SHARED st AS DOUBLE
DIM SHARED starttime AS DOUBLE

DIM SHARED FPS2, FPS, EndGame, EndGame2
' EndGame flags if a round has ended (any situation) -> it 
' stops the seconds to advance on the in-game clock.
' EndGame2 flags if a round has been won (puzzle solved).

DIM SHARED Frame1, Frame2, Frame3, Frame4
DIM SHARED NoPress
DIM SHARED Piece_Sliding ' A variable that is TRUE if ANY piece is
                         ' sliding (a bit of lazy coding -> to prevent
                         ' keypress if any piece is sliding)

' Various variables used to set the game parameters on the main menu.
' NumofRows represents the number of columns of a puzzle since were
' are using square-shaped puzzle fields. Also, NumofRows and PieceWidth 
' are calculated from NumofPieces.
DIM SHARED NumofPieces, NumofRows, PieceWidth, PictureNum, TimeLimit, bgcolor

const fpslimit = 50 ' Sets the number of FPS in our program.

SCREENRES 640, 480, 16, 2, 1 ' Set out screen resolution and bit depth.
SCREENSET 1, 0
SETMOUSE 50,50,0 ' Hide the mouse cursor.

' Default game parameters (9 pieces, first picture, no time limit,
' black background color).
NumofPieces = 9
PictureNum = 1
TimeLimit = 4
bgcolor = 7

' Init game's graphics.
InitGraphics

returntomainm:

' Play the main loop.
MainMenu

' Calculate the number of rows and columns and
' pieces' width according to set number of pieces.
NumofRows = SQR(NumofPieces)
PieceWidth = 360/NumofRows
RANDOMIZE TIMER

PlayGame

' Once a game has ended, return to main menu.
GOTO returntomainm:

END

SUB InitGraphics ()

' Allocate needed memory for all the buffers (and more
' to be sure -> leave me alone!)
FOR initscrn = 1 TO 18
ScreenBuffer(initscrn)=ImageCreate(361,361) 
SmallScrnBuffer(initscrn)=ImageCreate(126,126)
NEXT initscrn
Tempbuffer=ImageCreate(150,30)

FOR cpiece = 1 TO 36
Picture_Piece(cpiece).PieceBuffer = ImageCreate(121,121)
NEXT cpiece

' Load all the images and store them in appropriate memory
' buffers.
FOR countpic = 1 TO 9
BLOAD "Images/pic"+LTRIM$(RTRIM$(STR$(countpic)))+".bmp",0
GET (0,0)-(359,359), ScreenBuffer(countpic)
BLOAD "Images/pic"+LTRIM$(RTRIM$(STR$(countpic)))+"_small.bmp",0
GET (0,0)-(125,125), SmallScrnBuffer(countpic)
NEXT countpic

END SUB


SUB MainMenu ()
    
' Main menu loop.

DO

' REMed code used during development to check
' the number of FPS.
'FPS = FPS + 1     
'IF starttime + 1 <= TIMER& THEN
'FPS2 = FPS
'FPS = 0
'starttime = TIMER&
'END IF
'LOCATE 1,1
'PRINT FPS2

' Hide our workpage.
screenset workpage, workpage xor 1

CLS

' Put the currently selected image (small version)
' on the main menu screen.
PUT (398,240), SmallScrnBuffer(PictureNum), ALPHA, 200

' Boring code featuring menu options.

COLOR &H0875C2
LOCATE 1, 70
PRINT "L.D. Dec 06"

COLOR &H006DC0
LOCATE 10,27
PRINT "***************************"
LOCATE 12,27
PRINT "***************************"
LOCATE 11,27
PRINT "*                         *"
COLOR &H23AFFF
LOCATE 11,28
PRINT "Classic Art Slider Puzzle"
COLOR &H00C000
LOCATE 19,10
PRINT "Select the number of pieces:"
COLOR &HC0C0FF
LOCATE 19,50
PRINT "Select the artist:"
COLOR &HFF8080
LOCATE 27,16
PRINT "Time to solve:"
COLOR &HFF40FF
LOCATE 36,15
PRINT "Background color:"

COLOR &H83E3FF
LOCATE 55,24
PRINT "Press S or ENTER to start playing"

COLOR &HC0C0C0
IF NumofPieces = 9 THEN COLOR &HFFFFFF
LOCATE 21,17
PRINT "1)  9 (3 * 3)"
COLOR &HC0C0C0
IF NumofPieces = 16 THEN COLOR &HFFFFFF
LOCATE 22,17
PRINT "2) 16 (4 * 4)"
COLOR &HC0C0C0
IF NumofPieces = 36 THEN COLOR &HFFFFFF
LOCATE 23,17
PRINT "3) 36 (6 * 6)"
COLOR &HFFFFFF
LOCATE 21,15
IF NumofPieces=16 THEN LOCATE 22,15
IF NumofPieces=36 THEN LOCATE 23,15
PRINT "*"

COLOR &HC0C0C0
LOCATE 21,53
IF PictureNum = 1 THEN COLOR &HFFFFFF
PRINT "F1) Raphael"
COLOR &HC0C0C0
LOCATE 22,53
IF PictureNum = 2 THEN COLOR &HFFFFFF
PRINT "F2) Dali"
COLOR &HC0C0C0
LOCATE 23,53
IF PictureNum = 3 THEN COLOR &HFFFFFF
PRINT "F3) Goya"
COLOR &HC0C0C0
LOCATE 24,53
IF PictureNum = 4 THEN COLOR &HFFFFFF
PRINT "F4) Munch"
COLOR &HC0C0C0
LOCATE 25,53
IF PictureNum = 5 THEN COLOR &HFFFFFF
PRINT "F5) Khalo"
COLOR &HC0C0C0
LOCATE 26,53
IF PictureNum = 6 THEN COLOR &HFFFFFF
PRINT "F6) Durer"
COLOR &HC0C0C0
LOCATE 27,53
IF PictureNum = 7 THEN COLOR &HFFFFFF
PRINT "F7) Pollock"
COLOR &HC0C0C0
LOCATE 28,53
IF PictureNum = 8 THEN COLOR &HFFFFFF
PRINT "F8) Rembrandt"
COLOR &HC0C0C0
LOCATE 29,53
IF PictureNum = 9 THEN COLOR &HFFFFFF
PRINT "F9) Bosh"

LOCATE 29, 16
COLOR &HC0C0C0
IF TimeLimit = 1 THEN COLOR &HFFFFFF
PRINT "A) 15 minutes"
LOCATE 30, 16
COLOR &HC0C0C0
IF TimeLimit = 2 THEN COLOR &HFFFFFF
PRINT "B) 10 minutes"
LOCATE 31, 16
COLOR &HC0C0C0
IF TimeLimit = 3 THEN COLOR &HFFFFFF
PRINT "C) 5 minutes"
LOCATE 32,16
COLOR &HC0C0C0
IF TimeLimit = 4 THEN COLOR &HFFFFFF
PRINT "D) Unlimited time"

LOCATE 44, 16
COLOR &HC0C0C0
PRINT "(+/- to change)"
IF bgcolor = 1 THEN lclr = &HC00000
IF bgcolor = 2 THEN lclr = &H808000
IF bgcolor = 3 THEN lclr = &H00C000
IF bgcolor = 4 THEN lclr = &H00C0C0
IF bgcolor = 5 THEN lclr = &H0000C0
IF bgcolor = 6 THEN lclr = &HC000C0
IF bgcolor = 7 THEN lclr = &H000000
LINE (130,300)-(220,330), lclr, BF
LINE (129,299)-(221,331), &H808080, B

COLOR &HFFFFFF
LOCATE 20+PictureNum,51
PRINT "*"
LOCATE 28+TimeLimit,14
PRINT "*"

IF MULTIKEY(SC_1) THEN NumofPieces = 9
IF MULTIKEY(SC_2) THEN NumofPieces = 16
IF MULTIKEY(SC_3) THEN NumofPieces = 36

IF MULTIKEY(SC_F1) THEN PictureNum = 1
IF MULTIKEY(SC_F2) THEN PictureNum = 2
IF MULTIKEY(SC_F3) THEN PictureNum = 3
IF MULTIKEY(SC_F4) THEN PictureNum = 4
IF MULTIKEY(SC_F5) THEN PictureNum = 5
IF MULTIKEY(SC_F6) THEN PictureNum = 6
IF MULTIKEY(SC_F7) THEN PictureNum = 7
IF MULTIKEY(SC_F8) THEN PictureNum = 8
IF MULTIKEY(SC_F9) THEN PictureNum = 9

IF MULTIKEY(SC_A) THEN TimeLimit = 1
IF MULTIKEY(SC_B) THEN TimeLimit = 2
IF MULTIKEY(SC_C) THEN TimeLimit = 3
IF MULTIKEY(SC_D) THEN TimeLimit = 4


workpage xor = 1

IF MULTIKEY(SC_PLUS) THEN 
bgcolor = bgcolor + 1
WHILE MULTIKEY(SC_PLUS)
WEND
END IF
IF MULTIKEY(SC_MINUS) THEN 
bgcolor = bgcolor - 1
WHILE MULTIKEY(SC_MINUS)
WEND
END IF
IF bgcolor > 7 THEN bgcolor = 1
IF bgcolor < 1 THEN bgcolor = 7

' End of boring code featuring menu options.

do 
loop until timer& - st >= (1/fpslimit) 
st = timer& 

SLEEP 1

' End program is ESC is pressed!
IF MULTIKEY(SC_ESCAPE) THEN END

LOOP UNTIL MULTIKEY(SC_S) OR MULTIKEY(SC_ENTER)

END SUB

SUB PlayGame ()

' Init round variables.
Minutes = 0
Seconds = -1
EndGame = FALSE
EndGame2 = FALSE
missingpiece_alpha = 0

' Hide the work page
screenset workpage, workpage xor 1

' Display the currently selected picture (big version)
PUT (140,60), ScreenBuffer(PictureNum), PSET

crow = 1
ccolumn = 1

' Loop through our Picture_Piece array and
' grab all the piece into appropriate
' memory buffers
FOR cpiece = 1 TO NumofPieces
    Picture_Piece(cpiece).Row = 0
    Picture_Piece(cpiece).Column = 0
    Picture_Piece(cpiece).CorrectRow = crow
    Picture_Piece(cpiece).CorrectColumn = ccolumn
    GET (140+(ccolumn-1)*PieceWidth,60+(crow-1)*PieceWidth)-(139+PieceWidth+(ccolumn-1)*PieceWidth,59+PieceWidth+(crow-1)*PieceWidth), Picture_Piece(cpiece).PieceBuffer 
    ccolumn = ccolumn + 1
    IF ccolumn > NumofRows THEN 
        ccolumn = 1
        crow = crow + 1
    END IF
NEXT cpiece

' Randomize the starting positions of pieces
FOR cpiece1 = 1 TO NumofPieces
    repeatpieceRND:    
    Picture_Piece(cpiece1).Row = INT(RND * NumofRows) + 1
    Picture_Piece(cpiece1).Column = INT(RND * NumofRows) + 1
    FOR cpiece2 = 1 TO cpiece1
        IF (cpiece2<>cpiece1 AND Picture_Piece(cpiece2).Row > 0 AND Picture_Piece(cpiece1).Row = Picture_Piece(cpiece2).Row AND Picture_Piece(cpiece1).Column = Picture_Piece(cpiece2).Column) THEN GOTO repeatpieceRND:
    NEXT cpiece2
NEXT cpiece1

CLS

DO

' Code used to count the seconds and minutes
FPS = FPS + 1     
IF starttime + 1 <= TIMER& THEN
    IF EndGame = FALSE THEN Seconds = Seconds + 1
        FPS2 = FPS
        FPS = 0
    IF Seconds>59 THEN
        Seconds = 0
        Minutes = Minutes + 1
    END IF
    starttime = TIMER&
END IF
    
' Variables used to enable the "broken TV" 
' effect on the small "help" picture
Frame1 = (Frame1 MOD 120) + 1
mov_small_pic_y = Frame1
alpha_tremble = INT(RND * 12) + 1

screenset workpage, workpage xor 1

CLS

COLOR &H808080
LOCATE 1,4
PRINT "ESC to abort"

minstr$ = STR$(Minutes)
IF Minutes<10 THEN minstr$="0"+minstr$
secstr$ = STR$(Seconds)
IF Seconds<10 THEN secstr$="0"+secstr$

' Display the play time or time left
' according to selected mode
IF TimeLimit = 4 THEN
    COLOR &HFFFFFF
    IF EndGame = TRUE THEN COLOR &H40FF40
    LOCATE 42,60
    PRINT "Play time: "+minstr$+":"+secstr$
END IF
IF TimeLimit < 4 THEN
    IF TimeLimit = 1 THEN EndMinutes = 14
    IF TimeLimit = 2 THEN EndMinutes = 9
    IF TimeLimit = 3 THEN EndMinutes = 4
    RemainingMinutes = EndMinutes - Minutes
    RemainingSeconds = 59 - Seconds
    minstr$ = STR$(RemainingMinutes)
    IF RemainingMinutes<10 THEN minstr$="0"+minstr$
    secstr$ = STR$(RemainingSeconds)
    IF RemainingSeconds<10 THEN secstr$="0"+secstr$
    COLOR &HFFFFFF
    LOCATE 42,60
    PRINT "Time left: "+minstr$+":"+secstr$
    IF RemainingMinutes <= 0 AND RemainingSeconds <= 0 THEN
        COLOR &HFF4040
        LOCATE 42,60
        PRINT "Time left: 00:00"
        EndGame = TRUE
        COLOR &HFF4040
        LOCATE 11,63
        PRINT "TIME OUT!"
        COLOR &HC00000
        LOCATE 12,58
        PRINT "PRESS ENTER TO EXIT"
    END IF
END IF

' Cover the play field with background color
IF bgcolor = 1 THEN lclr = &HC00000
IF bgcolor = 2 THEN lclr = &H808000
IF bgcolor = 3 THEN lclr = &H00C000
IF bgcolor = 4 THEN lclr = &H00C0C0
IF bgcolor = 5 THEN lclr = &H0000C0
IF bgcolor = 6 THEN lclr = &HC000C0
IF bgcolor = 7 THEN lclr = &H000000
LINE (60,40)-(419,399), lclr, BF

' By deafult no pieces are sliding
Piece_Sliding = FALSE
' By deafult the game has ended (my quirky methods of
' solving problems :P)
EndGame2 = TRUE

' Loop through our pieces
FOR cpiece = 1 TO NumofPieces
    ' By deafult display pieces darker (alpha blender is 180)
    piece_alphablend = 180

    ' If any piece is not in its proper place the game has NOT ended
    ' (not that line above makes sense)
    IF Picture_Piece(cpiece).Column <> Picture_Piece(cpiece).CorrectColumn OR Picture_Piece(cpiece).Row <> Picture_Piece(cpiece).CorrectRow THEN EndGame2=FALSE

    ' If a current piece is in its right positon display it fully bright
    ' (alpha blender is 255)
    IF Picture_Piece(cpiece).Column = Picture_Piece(cpiece).CorrectColumn AND Picture_Piece(cpiece).Row = Picture_Piece(cpiece).CorrectRow THEN piece_alphablend = 255

    ' If the current piece is not the last one (which is not drawn - empty
    ' space!) and if not sliding, draw it with the appropriate alpha
    ' blender. Black background behind the pasted piece is needed
    ' due the usage of alpha blending and colored play field background.
    IF cpiece < NumofPieces AND Picture_Piece(cpiece).Sliding = FALSE THEN 
        LINE (60+(Picture_Piece(cpiece).Column-1)*PieceWidth,40+(Picture_Piece(cpiece).Row-1)*PieceWidth)-(59+PieceWidth+(Picture_Piece(cpiece).Column-1)*PieceWidth,39+PieceWidth+(Picture_Piece(cpiece).Row-1)*PieceWidth), 0, BF
        PUT (60+(Picture_Piece(cpiece).Column-1)*PieceWidth,40+(Picture_Piece(cpiece).Row-1)*PieceWidth), Picture_Piece(cpiece).PieceBuffer, ALPHA, piece_alphablend
    END IF

    ' If the current piece is sliding, draw in on the old position (column
    ' and row) but with XPos or YPos added to these coordinates (which
    ' change according to sliding direction).
    IF Picture_Piece(cpiece).Sliding = TRUE THEN
    ' Sliding pieces need to be darker.
        piece_alphablend = 180
        LINE (60+(Picture_Piece(cpiece).OldColumn-1)*PieceWidth+Picture_Piece(cpiece).XPos,40+(Picture_Piece(cpiece).OldRow-1)*PieceWidth+Picture_Piece(cpiece).YPos)-(59+PieceWidth+(Picture_Piece(cpiece).OldColumn-1)*PieceWidth+Picture_Piece(cpiece).XPos,39+PieceWidth+(Picture_Piece(cpiece).OldRow-1)*PieceWidth+Picture_Piece(cpiece).YPos), 0, BF
        PUT (60+(Picture_Piece(cpiece).OldColumn-1)*PieceWidth+Picture_Piece(cpiece).XPos,40+(Picture_Piece(cpiece).OldRow-1)*PieceWidth+Picture_Piece(cpiece).YPos), Picture_Piece(cpiece).PieceBuffer, ALPHA, piece_alphablend    
        ' Change XPos or YPos according to pieces sliding direction.
        IF Picture_Piece(cpiece).SlidingDirec = 1 THEN Picture_Piece(cpiece).XPos = Picture_Piece(cpiece).XPos - 8
        IF Picture_Piece(cpiece).SlidingDirec = 2 THEN Picture_Piece(cpiece).XPos = Picture_Piece(cpiece).XPos + 8
        IF Picture_Piece(cpiece).SlidingDirec = 3 THEN Picture_Piece(cpiece).YPos = Picture_Piece(cpiece).YPos - 8
        IF Picture_Piece(cpiece).SlidingDirec = 4 THEN Picture_Piece(cpiece).YPos = Picture_Piece(cpiece).YPos + 8

        ' Global sliding variable used to flag that ANY piece is sliding
        ' (to prevent the player to move pieces during sliding of
        ' any of them).
        Piece_Sliding = TRUE
        
        ' End sliding when the sliding piece has reached its
        ' new position.
        IF ABS(Picture_Piece(cpiece).YPos) > PieceWidth OR ABS(Picture_Piece(cpiece).XPos) > PieceWidth THEN
            Picture_Piece(cpiece).Sliding = FALSE    
        END IF

    END IF

NEXT cpiece

IF EndGame2 = TRUE THEN
    ' If the player has solved the puzzle, display
    ' appropriate text and "fade in" the missing
    ' puzzle piece (last one).
    IF Piece_Sliding = FALSE THEN
        PUT (60+(Picture_Piece(NumofPieces).Column-1)*PieceWidth,40+(Picture_Piece(NumofPieces).Row-1)*PieceWidth), Picture_Piece(NumofPieces).PieceBuffer, ALPHA, missingpiece_alpha
        IF missingpiece_alpha<255 THEN missingpiece_alpha=missingpiece_alpha+5
    END IF
    EndGame = TRUE
    COLOR &HFFB93F
    LOCATE 11,59
    PRINT "PUZZLE ASSEMBLED!"
    COLOR &HFF9E3F
    LOCATE 12,58
    PRINT "PRESS ENTER TO EXIT"
END IF

' Draw lines around the puzzle and
' the help picture.
LINE (59,39)-(420,400),&H4F62F3, B
LINE (58,38)-(421,401),&H7685F6, B
LINE (57,37)-(422,402),&H4F62F3, B
LINE (469,156)-(596,283),&H4F62F3, B
LINE (468,155)-(597,284),&H7685F6, B
LINE (467,154)-(598,285),&H4F62F3, B

' Draw the help picture and enable appropriate
' visual effects on it.
PUT (470, 157), SmallScrnBuffer(PictureNum), ALPHA, 242+alpha_tremble
GET (471, 157+mov_small_pic_y)-(594, 157+mov_small_pic_y+3), Tempbuffer
PUT (470, 157+mov_small_pic_y), Tempbuffer, TRANS

' If no pieces are sliding and the game has no ended
' allow keypress.
IF Piece_Sliding = FALSE AND EndGame = FALSE THEN

    IF MULTIKEY(SC_LEFT) AND NoPress = FALSE THEN
        IF Picture_Piece(NumofPieces).Column < NumofRows THEN
            ' If the empty space (represented with the last
            ' piece in the puzzle) is not in the last column,
            ' check the puzzle for it and move the piece
            ' right from the empty space.
            FOR cpiece = 1 TO NumofPieces
            IF NoPress = FALSE AND Picture_Piece(cpiece).Row = Picture_Piece(NumofPieces).Row AND Picture_Piece(cpiece).Column - 1 = Picture_Piece(NumofPieces).Column  THEN
            ' Enable sliding for the current piece in direction 1.
            SlidePiece cpiece, 1
            ' Swap positions of the empty space and the current
            ' piece.
            Picture_Piece(cpiece).Column = Picture_Piece(cpiece).Column - 1
            Picture_Piece(NumofPieces).Column = Picture_Piece(NumofPieces).Column + 1
            NoPress = TRUE
            END IF
            NEXT cpiece
        END IF
    END IF
 
    ' The code for other direction goes in the same manner.
    IF MULTIKEY(SC_RIGHT) AND NoPress = FALSE THEN
        ' For the right direction we check for movement only if
        ' the empty space is not in the first row (the movement is
        ' not possible if the empty space is in the first row).
        IF Picture_Piece(NumofPieces).Column > 1 THEN
            FOR cpiece = 1 TO NumofPieces
            IF NoPress = FALSE AND Picture_Piece(cpiece).Row = Picture_Piece(NumofPieces).Row AND Picture_Piece(cpiece).Column + 1 = Picture_Piece(NumofPieces).Column THEN
            SlidePiece cpiece, 2
            Picture_Piece(cpiece).Column = Picture_Piece(cpiece).Column + 1
            Picture_Piece(NumofPieces).Column = Picture_Piece(NumofPieces).Column - 1
            NoPress = TRUE
            END IF
            NEXT cpiece
        END IF
    END IF

    IF MULTIKEY(SC_UP) AND NoPress = FALSE THEN
        IF Picture_Piece(NumofPieces).Row < NumofRows THEN
            FOR cpiece = 1 TO NumofPieces
            IF NoPress = FALSE AND Picture_Piece(cpiece).Column = Picture_Piece(NumofPieces).Column AND Picture_Piece(cpiece).Row - 1 = Picture_Piece(NumofPieces).Row  THEN
            SlidePiece cpiece, 3
            Picture_Piece(cpiece).Row = Picture_Piece(cpiece).Row - 1
            Picture_Piece(NumofPieces).Row = Picture_Piece(NumofPieces).Row + 1
            NoPress = TRUE
            END IF
            NEXT cpiece
        END IF
    END IF

    IF MULTIKEY(SC_DOWN) AND NoPress = FALSE THEN
        IF Picture_Piece(NumofPieces).Row > 1 THEN
            FOR cpiece = 1 TO NumofPieces
            IF NoPress = FALSE AND Picture_Piece(cpiece).Column = Picture_Piece(NumofPieces).Column AND Picture_Piece(cpiece).Row + 1 = Picture_Piece(NumofPieces).Row  THEN
            SlidePiece cpiece, 4
            Picture_Piece(cpiece).Row = Picture_Piece(cpiece).Row + 1
            Picture_Piece(NumofPieces).Row = Picture_Piece(NumofPieces).Row - 1
            NoPress = TRUE
            END IF
            NEXT cpiece
        END IF
    END IF

END IF

COLOR &H0084E0
LOCATE 58,28
PRINT "Use arrow keys to move the pieces"

workpage xor = 1

do 
loop until timer& - st >= (1/fpslimit) 
st = timer& 

' Some crappy code that prevens double keypressing.
IF MULTIKEY(SC_LEFT) OR MULTIKEY(SC_RIGHT) OR MULTIKEY(SC_UP) OR MULTIKEY(SC_DOWN) THEN GOTO skip_press_reset:
NoPress = FALSE
skip_press_reset:

SLEEP 1

LOOP UNTIL MULTIKEY(SC_ESCAPE) OR (MULTIKEY(SC_ENTER) AND EndGame = TRUE)

WHILE MULTIKEY(SC_ENTER) OR MULTIKEY(SC_ESCAPE)
WEND

END SUB


SUB SlidePiece (piece_to_slide, slide_direction)

FOR cpiece = 1 TO NumofPieces
 
    ' This sub initiates appropriate variables for
    ' a piece that is about to slide.
    IF cpiece = piece_to_slide THEN
        Picture_Piece(cpiece).OldRow = Picture_Piece(cpiece).Row
        Picture_Piece(cpiece).OldColumn = Picture_Piece(cpiece).Column
        Picture_Piece(cpiece).Sliding = TRUE
        Picture_Piece(cpiece).SlidingDirec = slide_direction
        Picture_Piece(cpiece).XPos = 0
        Picture_Piece(cpiece).YPos = 0
    END IF

NEXT cpiece

END SUB