Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Interlocking Jigsaw Puzzle
#1
This is a Jigsaw Puzzle sim which features a picture of some QB64 members' avatar.  It is a 60-piece jigsaw and the pieces are shaped to be interlocking.

There are 6 pictures to choose from.  As well as the QB64 picture, there is and one of a map of the user-selected region.  The program comes with 4 other pictures to choose from.


.zip   Interlocking Jigsaw.zip (Size: 4.92 MB / Downloads: 15)
Unzip the file and extract the folder into your PEQB64 directory.  In the IDE make sure that you have the Run Option “Save EXE in source folder” checked.

   
A large screen is required for this program, at least 1400x800 pixels.


The first time that you run the program, you will have to click on a picture of a mouse (rodent).  This is so that the program knows which mouse button to respond to in all cases (as far as I know) of button configuration.  There may be a delay after you click.  After that, you also have to click with the opposite mouse button.  This routine sets right and left mouse clicks for the program.  Then you will be shown a map of the world.  Select your region.  The mouse button and region routine does not happen on subsequent runs.
   
   


Entering the game, firstly choose the picture you wish to play with by mouse click.  The program then enters the play area.

When doing the puzzle, the screen is divided into 3 regions.  At the bottom left is a grid where the pieces are assembled to form the finished picture.  At the top right is a small reference picture.  Surrounding the picture grid are the pieces to be moved, which are randomly placed with random orientation.  Move pieces by normal mouse button single click, which picks up the piece.  The picked-up piece will then move with the cursor (drag-and-drop is not implemented – everything is done with single clicks).  When selected, the piece can be moved into or out of the work area.  Single click to drop and place the piece.  If you click outside the work area, the selected piece will be returned to the stock.  When a piece has been selected, it can be rotated by opposite mouse button single click.

When the pieces are placed correctly next to each other there is a 'perfect' fit with no gap: this does make the picture in the grid look slightly less “jigsaw-like” than would be desirable.  The program will know when you have completed the puzzle.

At any point when a piece has not been selected, the reference picture may be enlarged by clicking on it (and then clicking again to reduce it).

The game is completed, naturally enough, when all the pieces are in their correct position and with correct orientation.  Pressing Escape allows the puzzle to be aborted at any time.

A user guide is attached.  This is for interest only and is not required to run and enjoy the program.

.pdf   Interlocking Jigsaw Puzzle User Guide.pdf (Size: 398.44 KB / Downloads: 19)

The video is a short excerpt of the running program.



Code: (Select All)
'Jigsaw Puzzle Game (with interlocking pieces) 2025-12-04 by Magdha ex Qwerkey
'Pictures available:
'QB64 Avatar Gallery Picture & User Region Map Picture
'4 Other Supplied Pictures: User could use own pictures

'Clipart from openclipart.org & clipartfest.com
'Pictures from bayo-hampshire.org.uk, Wikipedia, WordAtlas & huntonit.com

CONST False = 0, True = NOT False
CONST ScreenX% = 1380, ScreenY% = 820, Rad1% = 5, Rad2% = 3, Delta% = 9, XBPic% = 1177, YBPic% = 696
CONST xD% = 158, yD% = 158, NoPics%% = 6, NoCols% = 10, NoRows% = 6, NoPieces% = NoCols% * NoRows%
CONST YSelPic% = 355, XSize% = 78, YSize% = 74
CONST X1% = 5, Y1% = 5, X1Gap%% = 23, Y1Gap%% = 19, X2% = 799, Y2% = 4, X21% = ScreenX% - 4
CONST Y21% = 348, X22% = 199, Y23% = 700, X3% = 795, Y3% = 362, X3Gap%% = 21, Y3Gap%% = 19, X4% = 5
CONST Y4% = ScreenY% - (NoRows% * YSize%) - 5, X41% = X4% + (XSize% * NoCols%), Y41% = Y4% + (YSize% * NoRows%)
DIM Espacos%%(3), Slangenden&(6), Grenze&(1), Souris%%(9), Tulpanlok%%(13, 8), Lado%%(3), Regione%(7, 6)
DIM Jigsaw&(5)

_TITLE "Jigsaw Puzzle"
$EXEICON:'.\Jigsaw.ico'

'Randomness required to mix puzzle pieces, to choose Gallery images and to orient Phoenix images
RANDOMIZE (TIMER)

'Read data
'Interlocking Shape Data
DATA -1,-1,-1,-1,-1,-1,-1,-1,-1
DATA 0,0,-1,-1,-1,-1,-1,0,0
DATA 0,0,-1,-1,-1,-1,-1,0,0
DATA 0,0,-1,-1,-1,-1,-1,0,0
DATA 0,0,-1,-1,-1,-1,-1,0,0
DATA 0,0,-1,-1,-1,-1,-1,0,0
DATA 0,-1,-1,-1,-1,-1,-1,-1,0
DATA -1,-1,-1,-1,-1,-1,-1,-1,-1
DATA -1,-1,-1,-1,-1,-1,-1,-1,-1
DATA -1,-1,-1,-1,-1,-1,-1,-1,-1
DATA -1,-1,-1,-1,-1,-1,-1,-1,-1
DATA -1,-1,-1,-1,-1,-1,-1,-1,-1
DATA 0,-1,-1,-1,-1,-1,-1,-1,0
DATA 0,0,-1,-1,-1,-1,-1,0,0
FOR S%% = 0 TO 13
    FOR R%% = 0 TO 8
        READ Tulpanlok%%(S%%, R%%)
    NEXT R%%
NEXT S%%

'Top and Bottom Spaces
DATA 8,4,6,5
FOR R%% = 0 TO 3
    READ Espacos%%(R%%)
NEXT R%%
X11% = X1% + (XSize% + X1Gap%%) * (Espacos%%(0) - 1) + XSize%
Y11% = Y1% + (YSize% + Y1Gap%%) * (Espacos%%(1) - 1) + YSize%
X31% = X3% + (XSize% + X3Gap%%) * (Espacos%%(2) - 1) + XSize%
Y31% = Y3% + (YSize% + Y3Gap%%) * (Espacos%%(3) - 1) + YSize%

'Load Mouse & Region Data
OPEN "mouse.cfg" FOR INPUT AS #1
FOR S%% = 0 TO 9
    INPUT #1, Dumm$
    Souris%%(S%%) = CVI(Dumm$) - 9876
NEXT S%%
CLOSE #1

'Routine to Set Mouse Buttons and Location (First Time Only)
IF Souris%%(0) = 0 THEN
    _TITLE "Jigsaw Puzzle - Set Mouse Buttons"
    'Region  Highlight Data
    DATA 60,7,338,180,0,255,0
    DATA 150,167,303,335,0,150,0
    DATA 150,345,655,405,0,0,255
    DATA 340,12,490,113,150,0,0
    DATA 335,105,495,285,180,180,0
    DATA 470,10,705,200,255,0,0
    DATA 610,215,785,320,180,0,80
    FOR S%% = 1 TO 7
        FOR R%% = 0 TO 6
            READ Regione%(S%%, R%%)
        NEXT R%%
    NEXT S%%
    Mousey& = _LOADIMAGE(strDir$ + "Mouse.png", 32)
    MappaMundi& = _LOADIMAGE("Continents.jpg", 32)
    SCREEN _NEWIMAGE(500, 500, 32)
    _SCREENMOVE 100, 100
    _DEST 0
    CLS
    _PUTIMAGE (50, 100), Mousey&
    LOCATE 2, 7
    PRINT "Click on the mouse below with your normal button";
    LOCATE 3, 5
    PRINT "Click (not double-click) to make this screen disappear";
    LOCATE 5, 6
    PRINT "There may be a delay - Please wait for next screen";
    CorrectButton%% = False
    WHILE NOT CorrectButton%%
        _LIMIT 60
        'Assumes hardware has mouse buttons, value <=5
        IF _MOUSEINPUT THEN
            CorrectButton%% = False: Souris%%(0) = 1
            WHILE NOT CorrectButton%% AND Souris%%(0) <= 5
                IF _MOUSEBUTTON(Souris%%(0)) THEN
                    CorrectButton%% = True
                ELSE
                    Souris%%(0) = Souris%%(0) + 1
                END IF
            WEND
        END IF
    WEND
    CLS
    _PUTIMAGE (450, 100)-(50, 400), Mousey&
    LOCATE 2, 7
    PRINT "Click on the mouse below with your opposite button";
    LOCATE 3, 5
    PRINT "Click (not double-click) to make this screen disappear";
    CorrectButton%% = False
    'Opposite Button
    WHILE NOT CorrectButton%%
        _LIMIT 60
        'Assumes hardware has mouse buttons, value <=5
        IF _MOUSEINPUT THEN
            CorrectButton%% = False: Souris%%(8) = 1
            WHILE NOT CorrectButton%% AND Souris%%(8) <= 5
                IF _MOUSEBUTTON(Souris%%(8)) THEN
                    IF Souris%%(0) <> Souris%%(8) THEN
                        CorrectButton%% = True
                    ELSE
                        LOCATE 4, 5: PRINT "Cannot have same button as previous";
                        BEEP
                        Souris%%(8) = Souris%%(8) + 1
                    END IF
                ELSE
                    Souris%%(8) = Souris%%(8) + 1
                END IF
            WEND
        END IF
    WEND
    CLS
    _FREEIMAGE Mousey&
    _TITLE "Jigsaw Puzzle - Set Region"
    InRegione%% = 0
    SCREEN _NEWIMAGE(800, 405, 32)
    _SCREENMOVE 100, 80
    _DEST 0
    COLOR _RGB32(0, 0, 0), _RGB32(180, 150, 0)
    CLS
    WHILE Souris%%(9) = 0
        _LIMIT 60
        CLS
        _PUTIMAGE (0, 0), MappaMundi&
        LINE (10, 240)-(80, 320), _RGB32(180, 150, 0), BF
        _PRINTSTRING (20, 250), "SELECT"
        _PRINTSTRING (20, 270), "YOUR"
        _PRINTSTRING (20, 290), "REGION"
        WHILE _MOUSEINPUT
            XMouse% = _MOUSEX: YMouse% = _MOUSEY
            InRegione%% = 0
            Reg%% = 1
            WHILE InRegione%% = 0 AND Reg%% <= 7
                IF XMouse% >= Regione%(Reg%%, 0) + 2 AND XMouse% <= Regione%(Reg%%, 2) - 2 AND YMouse% >= Regione%(Reg%%, 1) + 2 AND YMouse% <= Regione%(Reg%%, 3) - 2 THEN
                    InRegione%% = Reg%%

                    IF _MOUSEBUTTON(Souris%%(0)) THEN Souris%%(9) = Reg%%

                ELSE
                    Reg%% = Reg%% + 1
                END IF
            WEND

            'IF XMouse% >= Regione%(1, 0) + 2 AND XMouse% <= Regione%(1, 2) - 2 AND YMouse% >= Regione%(1, 1) + 2 AND YMouse% <= Regione%(1, 3) - 2 THEN
            '    InRegione%% = 1
            '    IF _MOUSEBUTTON(Souris%%(0)) THEN Souris%%(9) = 1
            'ELSEIF XMouse% >= Regione%(2, 0) + 2 AND XMouse% <= Regione%(2, 2) - 2 AND YMouse% >= Regione%(2, 1) + 2 AND YMouse% <= Regione%(2, 3) - 2 THEN
            '    InRegione%% = 2
            '    IF _MOUSEBUTTON(Souris%%(0)) THEN Souris%%(9) = 2
            'ELSEIF XMouse% >= Regione%(3, 0) + 2 AND XMouse% <= Regione%(3, 2) - 2 AND YMouse% >= Regione%(3, 1) + 2 AND YMouse% <= Regione%(3, 3) - 2 THEN
            '    InRegione%% = 3
            '    IF _MOUSEBUTTON(Souris%%(0)) THEN Souris%%(9) = 3
            'ELSEIF XMouse% >= Regione%(4, 0) + 2 AND XMouse% <= Regione%(4, 2) - 2 AND YMouse% >= Regione%(4, 1) + 2 AND YMouse% <= Regione%(4, 3) - 2 THEN
            '    InRegione%% = 4
            '    IF _MOUSEBUTTON(Souris%%(0)) THEN Souris%%(9) = 4
            'ELSEIF XMouse% >= Regione%(5, 0) + 2 AND XMouse% <= Regione%(5, 2) - 2 AND YMouse% >= Regione%(5, 1) + 2 AND YMouse% <= Regione%(5, 3) - 2 THEN
            '    InRegione%% = 5
            '    IF _MOUSEBUTTON(Souris%%(0)) THEN Souris%%(9) = 5
            'ELSEIF XMouse% >= Regione%(6, 0) + 2 AND XMouse% <= Regione%(6, 2) - 2 AND YMouse% >= Regione%(6, 1) + 2 AND YMouse% <= Regione%(6, 3) - 2 THEN
            '    InRegione%% = 6
            '    IF _MOUSEBUTTON(Souris%%(0)) THEN Souris%%(9) = 6
            'ELSEIF XMouse% >= Regione%(7, 0) + 2 AND XMouse% <= Regione%(7, 2) - 2 AND YMouse% >= Regione%(7, 1) + 2 AND YMouse% <= Regione%(7, 3) - 2 THEN
            '    InRegione%% = 7
            '    IF _MOUSEBUTTON(Souris%%(0)) THEN Souris%%(9) = 7
            'ELSE
            '    InRegione%% = 0
            'END IF

        WEND
        'SELECT CASE InRegione%%
        '    CASE 1
        '        LINE (Regione%(1, 0), Regione%(1, 1))-(Regione%(1, 2), Regione%(1, 3)), _RGBA32(Regione%(1, 4), Regione%(1, 5), Regione%(1, 6), 100), BF
        '    CASE 2
        '        LINE (Regione%(2, 0), Regione%(2, 1))-(Regione%(2, 2), Regione%(2, 3)), _RGBA32(Regione%(2, 4), Regione%(2, 5), Regione%(2, 6), 100), BF
        '    CASE 3
        '        LINE (Regione%(3, 0), Regione%(3, 1))-(Regione%(3, 2), Regione%(3, 3)), _RGBA32(Regione%(3, 4), Regione%(3, 5), Regione%(3, 6), 100), BF
        '    CASE 4
        '    CASE 5
        '    CASE 6
        '    CASE 7
        'END SELECT

        IF InRegione%% >= 1 AND InRegione%% <= 7 THEN LINE (Regione%(InRegione%%, 0), Regione%(InRegione%%, 1))-(Regione%(InRegione%%, 2), Regione%(InRegione%%, 3)), _RGBA32(Regione%(InRegione%%, 4), Regione%(InRegione%%, 5), Regione%(InRegione%%, 6), 100), BF

        'IF InRegione%% = 1 THEN
        '    LINE (Regione%(1, 0), Regione%(1, 1))-(Regione%(1, 2), Regione%(1, 3)), _RGBA32(Regione%(1, 4), Regione%(1, 5), Regione%(1, 6), 100), BF
        'ELSEIF InRegione%% = 2 THEN
        '    LINE (Regione%(2, 0), Regione%(2, 1))-(Regione%(2, 2), Regione%(2, 3)), _RGBA32(Regione%(2, 4), Regione%(2, 5), Regione%(2, 6), 100), BF
        'ELSEIF InRegione%% = 3 THEN
        '    LINE (Regione%(3, 0), Regione%(3, 1))-(Regione%(3, 2), Regione%(3, 3)), _RGBA32(Regione%(3, 4), Regione%(3, 5), Regione%(3, 6), 100), BF
        'ELSEIF InRegione%% = 4 THEN
        '    LINE (Regione%(4, 0), Regione%(4, 1))-(Regione%(4, 2), Regione%(4, 3)), _RGBA32(Regione%(4, 4), Regione%(4, 5), Regione%(4, 6), 100), BF
        'ELSEIF InRegione%% = 5 THEN
        '    LINE (Regione%(5, 0), Regione%(5, 1))-(Regione%(5, 2), Regione%(5, 3)), _RGBA32(Regione%(5, 4), Regione%(5, 5), Regione%(5, 6), 100), BF
        'ELSEIF InRegione%% = 6 THEN
        '    LINE (Regione%(6, 0), Regione%(6, 1))-(Regione%(6, 2), Regione%(6, 3)), _RGBA32(Regione%(6, 4), Regione%(6, 5), Regione%(6, 6), 100), BF
        'ELSEIF InRegione%% = 7 THEN
        '    LINE (Regione%(7, 0), Regione%(7, 1))-(Regione%(7, 2), Regione%(7, 3)), _RGBA32(Regione%(7, 4), Regione%(7, 5), Regione%(7, 6), 100), BF
        'END IF
        _DISPLAY
    WEND
    _FREEIMAGE MappaMundi&
    OPEN "mouse.cfg" FOR OUTPUT AS #2
    FOR S%% = 0 TO 9
        PRINT #2, MKI$(Souris%%(S%%) + 9876)
    NEXT S%%
    CLOSE #2
    _DELAY 0.2
    DO 'Make sure that mouse button is released
        Dum%% = _MOUSEINPUT
    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(0))
    DO 'Make sure that mouse button is released
        Dum%% = _MOUSEINPUT
    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(8))
    _AUTODISPLAY
    CLS
END IF

Gallery% = 1
MorePics%% = True
WHILE MorePics%%
    IF NOT _FILEEXISTS("Gallery\" + LTRIM$(STR$(Gallery% + 1)) + ".jpg") THEN
        MorePics%% = False
    ELSE
        Gallery% = Gallery% + 1
    END IF
WEND

DoJigsaw%% = True
WHILE DoJigsaw%%

    'Picture Selection
    _TITLE "Jigsaw Puzzle - Select Picture"
    ImgTemp& = _NEWIMAGE(ScreenX%, ScreenY%, 32)
    _DEST ImgTemp&
    COLOR _RGB32(255, 255, 0), _RGB32(128, 128, 128)
    CLS
    FOR Q%% = 0 TO 2
        FOR R%% = 0 TO 1
            LINE (5 + Q%% * (ScreenY% - YSelPic% - 5), 10 + R%% * 400)-(5 + Q%% * (ScreenY% - YSelPic% - 5) + 450, 10 + R%% * 400 + 390), , B
        NEXT R%%
    NEXT Q%%
    SelPicBack& = HardwareImage&(ImgTemp&)
    ImgTemp& = _NEWIMAGE(470, 90, 32)
    _DEST ImgTemp&
    COLOR _RGB32(255, 255, 0), _RGBA32(0, 0, 0, 0)
    CLS
    Cali& = _LOADFONT("calibriz.ttf", 80)
    _FONT Cali&
    _PRINTSTRING (0, 5), "Select Picture"
    SelPicture& = HardwareImage&(ImgTemp&)
    FOR S%% = 2 TO NoPics%%
        IF S%% = NoPics%% THEN
            Jigsaw&(S%% - 1) = _LOADIMAGE("E" + LTRIM$(STR$(Souris%%(9))) + ".jpg", 33)
        ELSE
            Jigsaw&(S%% - 1) = _LOADIMAGE(CHR$(S%% + 63) + ".jpg", 33)
        END IF
    NEXT S%%
    'Gallery Picture
    REDIM SnapsOrder%(18)
    'Images 1 & 18 are fixed - Magdha & Steve
    SnapsOrder%(1) = 1
    SnapsOrder%(18) = 2
    'Images 2 to 17 are selected from available
    SnapsOrder%(2) = INT((Gallery% - 1) * RND) + 2
    FOR S%% = 3 TO 17
        CanFill%% = False
        WHILE NOT CanFill%%
            TryCell% = INT((Gallery% - 1) * RND) + 2
            R%% = 1: NotSame%% = True
            WHILE NotSame%% AND R%% < S%%
                IF SnapsOrder%(R%%) = TryCell% THEN
                    NotSame%% = False
                ELSE
                    R%% = R%% + 1
                END IF
            WEND
            IF NotSame%% THEN
                SnapsOrder%(S%%) = TryCell%
                CanFill%% = True
            END IF
        WEND
    NEXT S%%
    ByTheTimeIGetTo& = _LOADIMAGE("Phoenix.jpg", 32)
    W1% = _WIDTH(ByTheTimeIGetTo&)
    H1% = _HEIGHT(ByTheTimeIGetTo&)
    XLeft% = CINT((xD% - W1%) / 2)
    XRight% = xD% - XLeft%
    YTop% = CINT((yD% - H1%) / 2)
    YBottom% = yD% - YTop%
    XRht% = W1% - 1
    YBot% = H1% - 1
    i1& = _NEWIMAGE(8 * xD%, (5 * yD%), 32)
    _DEST i1&
    COLOR _RGB32(100, 100, 100), _RGB32(255, 255, 255)
    CLS
    FOR S%% = 1 TO 18
        Snaps& = _LOADIMAGE("Gallery\" + LTRIM$(STR$(SnapsOrder%(S%%))) + ".jpg", 32)
        _PUTIMAGE (((S%% - 1) MOD 6) * xD% + ((xD% - _WIDTH(Snaps&)) / 2) + xD%, ((S%% - 1) \ 6) * yD% + ((yD% - _HEIGHT(Snaps&)) / 2) + yD%), Snaps&
        _FREEIMAGE Snaps&
    NEXT S%%
    FOR S%% = 0 TO 7
        IF RND < 0.5 THEN
            _PUTIMAGE ((S%% * xD%) + XLeft%, YTop%), ByTheTimeIGetTo&
        ELSE
            _MAPTRIANGLE (0, 0)-(XRht%, 0)-(0, YBot%), ByTheTimeIGetTo& TO((S%% * xD%) + XRight%, YBottom%)-((S%% * xD%) + XLeft%, YBottom%)-((S%% * xD%) + XRight%, YTop%)
            _MAPTRIANGLE (XRht%, YBot%)-(0, YBot%)-(XRht%, 0), ByTheTimeIGetTo& TO((S%% * xD%) + XLeft%, YTop%)-((S%% * xD%) + XRight%, YTop%)-((S%% * xD%) + XLeft%, YBottom%)
        END IF
        IF RND < 0.5 THEN
            _PUTIMAGE ((S%% * xD%) + XLeft%, (4 * yD%) + YTop%), ByTheTimeIGetTo&
        ELSE
            _MAPTRIANGLE (0, 0)-(XRht%, 0)-(0, YBot%), ByTheTimeIGetTo& TO((S%% * xD%) + XRight%, (4 * yD%) + YBottom%)-((S%% * xD%) + XLeft%, (4 * yD%) + YBottom%)-((S%% * xD%) + XRight%, (4 * yD%) + YTop%)
            _MAPTRIANGLE (XRht%, YBot%)-(0, YBot%)-(XRht%, 0), ByTheTimeIGetTo& TO((S%% * xD%) + XLeft%, (4 * yD%) + YTop%)-((S%% * xD%) + XRight%, (4 * yD%) + YTop%)-((S%% * xD%) + XLeft%, (4 * yD%) + YBottom%)
        END IF
    NEXT S%%
    FOR R%% = 1 TO 3
        IF RND < 0.5 THEN
            _PUTIMAGE (XLeft%, (R%% * yD%) + YTop%), ByTheTimeIGetTo&
        ELSE
            _MAPTRIANGLE (0, 0)-(XRht%, 0)-(0, YBot%), ByTheTimeIGetTo& TO(XRight%, (R%% * yD%) + YBottom%)-(XLeft%, (R%% * yD%) + YBottom%)-(XRight%, (R%% * yD%) + YTop%)
            _MAPTRIANGLE (XRht%, YBot%)-(0, YBot%)-(XRht%, 0), ByTheTimeIGetTo& TO(XLeft%, (R%% * yD%) + YTop%)-(XRight%, (R%% * yD%) + YTop%)-(XLeft%, (R%% * yD%) + YBottom%)
        END IF
        IF RND < 0.5 THEN
            _PUTIMAGE ((7 * xD%) + XLeft%, (R%% * yD%) + YTop%), ByTheTimeIGetTo&
        ELSE
            _MAPTRIANGLE (0, 0)-(XRht%, 0)-(0, YBot%), ByTheTimeIGetTo& TO((7 * xD%) + XRight%, (R%% * yD%) + YBottom%)-((7 * xD%) + XLeft%, (R%% * yD%) + YBottom%)-((7 * xD%) + XRight%, (R%% * yD%) + YTop%)
            _MAPTRIANGLE (XRht%, YBot%)-(0, YBot%)-(XRht%, 0), ByTheTimeIGetTo& TO((7 * xD%) + XLeft%, (R%% * yD%) + YTop%)-((7 * xD%) + XRight%, (R%% * yD%) + YTop%)-((7 * xD%) + XLeft%, (R%% * yD%) + YBottom%)
        END IF
    NEXT R%%
    Jigsaw&(0) = _COPYIMAGE(i1&, 33)
    _FREEIMAGE ByTheTimeIGetTo&
    _FREEFONT Cali&
    DoPuzzle%% = True: Picked%% = False: K$ = ""
    SCREEN _NEWIMAGE(ScreenX%, ScreenY%, 32)
    _SCREENMOVE 5, 5
    _DEST 0
    COLOR _RGB32(255, 255, 0), _RGB32(128, 128, 128)
    CLS
    _DISPLAYORDER _HARDWARE
    WHILE NOT Picked%%
        _LIMIT 60
        _PUTIMAGE (0, 0), SelPicBack&
        FOR P%% = 1 TO NoPics%%
            Q%% = (P%% - 1) MOD 3
            R%% = (P%% - 1) \ 3
            _PUTIMAGE (5 + Q%% * (ScreenY% - YSelPic% - 5), 10 + R%% * 400)-(5 + Q%% * (ScreenY% - YSelPic% - 5) + 450, 10 + R%% * 400 + 390), Jigsaw&(P%% - 1)
        NEXT P%%
        _PUTIMAGE ((ScreenY% - YSelPic% - 5), 380), SelPicture&
        WHILE _MOUSEINPUT
            XMouse% = _MOUSEX: YMouse% = _MOUSEY
            IF _MOUSEBUTTON(Souris%%(0)) THEN
                IF YMouse% >= 15 AND YMouse% <= 395 AND XMouse% >= 10 AND XMouse% < 450 THEN
                    PicNo%% = 1
                    Picked%% = True
                ELSEIF YMouse% >= 15 AND YMouse% <= 395 AND XMouse% >= (ScreenY% - YSelPic% - 5) AND XMouse% < 910 THEN
                    PicNo%% = 2
                    Picked%% = True
                ELSEIF YMouse% >= 15 AND YMouse% <= 395 AND XMouse% >= 920 AND XMouse% < 1370 AND NoPics%% >= 3 THEN
                    PicNo%% = 3
                    Picked%% = True
                ELSEIF YMouse% >= 415 AND YMouse% <= 795 AND XMouse% >= 10 AND XMouse% < 450 AND NoPics%% >= 4 THEN
                    PicNo%% = 4
                    Picked%% = True
                ELSEIF YMouse% >= 415 AND YMouse% <= 795 AND XMouse% >= (ScreenY% - YSelPic% - 5) AND XMouse% < 910 AND NoPics%% >= 5 THEN
                    PicNo%% = 5
                    Picked%% = True
                ELSEIF YMouse% >= 415 AND YMouse% <= 795 AND XMouse% >= 920 AND XMouse% < 1370 AND NoPics%% = 6 THEN
                    PicNo%% = 6
                    Picked%% = True
                END IF
            END IF
        WEND
        K$ = INKEY$
        IF K$ <> "" THEN
            IF ASC(K$) = 27 THEN
                DoPuzzle%% = False
                Picked%% = True
            END IF
        END IF
        K$ = ""
        _DISPLAY
    WEND
    _FREEIMAGE SelPicBack&
    _FREEIMAGE SelPicture&
    FOR S%% = 0 TO NoPics%% - 1
        IF S%% <> (PicNo%% - 1) THEN _FREEIMAGE Jigsaw&(S%%)
    NEXT S%%

    'Create & Do Selected Jigsaw
    _TITLE "Jigsaw Puzzle - Esc to Quit"
    _AUTODISPLAY
    CLS
    WHILE INKEY$ <> "": K$ = INKEY$: WEND 'Clear Inkey buffer
    DO 'Make sure that mouse button is released
        Dum%% = _MOUSEINPUT
    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(0))
    DO 'Make sure that mouse button is released
        Dum%% = _MOUSEINPUT
    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(8))
    IF DoPuzzle%% THEN
        'Initialise Data and Images
        REDIM Grid~%%(NoCols%, NoRows%), Numbers%(NoPieces%), Stock%(NoPieces%)
        REDIM TopEspacos%%(Espacos%%(0), Espacos%%(1))
        REDIM BottomEspacos%%(Espacos%%(2), Espacos%%(3))
        REDIM PictImg&(NoPieces%), Orient%%(NoPieces%)
        REDIM GridH%%(NoCols%, NoRows% - 1, 1), GridV%%(NoCols% - 1, NoRows%, 1)
        FOR S%% = 1 TO NoCols%
            FOR R%% = 1 TO NoRows% - 1
                GridH%%(S%%, R%%, 0) = INT(RND * 2) + 1
                GridH%%(S%%, R%%, 1) = 3 * (INT(RND * 3) - 1)
            NEXT R%%
        NEXT S%%
        FOR S%% = 1 TO NoCols% - 1
            FOR R%% = 1 TO NoRows%
                GridV%%(S%%, R%%, 0) = INT(RND * 2) + 1
                GridV%%(S%%, R%%, 1) = 3 * (INT(RND * 3) - 1)
            NEXT R%%
        NEXT S%%
        XHalf% = XSize% / 2
        XCLine% = 13 + XHalf%
        XOff% = XCLine% - 4
        YHalf% = YSize% / 2
        YCLine% = 13 + YHalf%
        YOff% = YCLine% - 4
        Alphaimg& = _NEWIMAGE(1, 1, 32)
        _DEST Alphaimg&
        COLOR _RGB32(0, 0, 0), _RGB32(0, 0, 0)
        CLS
        IF PicNo%% = NoPics%% THEN
            PicChoice& = _LOADIMAGE("E" + LTRIM$(STR$(Souris%%(9))) + ".jpg", 32)
        ELSEIF PicNo%% = 1 THEN
            PicChoice& = _COPYIMAGE(i1&, 32)
        ELSE
            PicChoice& = _LOADIMAGE(CHR$(PicNo%% + 63) + ".jpg", 32)
        END IF
        _FREEIMAGE i1&
        TempImg& = _NEWIMAGE(XBPic%, YBPic%, 32)
        _DEST TempImg&
        _PUTIMAGE (1, 1)-(XBPic% - 2, YBPic% - 2), PicChoice&
        LINE (0, 0)-(XBPic% - 1, YBPic% - 1), _RGB32(255, 0, 0), B
        LINE (1, 1)-(XBPic% - 2, YBPic% - 2), _RGB32(255, 0, 0), B
        BorderedPic& = HardwareImage&(TempImg&)
        FramedPic& = _NEWIMAGE((NoCols% * XSize%) + 27, (NoRows% * YSize%) + 27, 32)
        _DEST FramedPic&
        _PUTIMAGE (13, 13)-((NoCols% * XSize%) + 13, (NoRows% * YSize%) + 13), PicChoice&
        _FREEIMAGE PicChoice&
        FOR S%% = 0 TO 6
            Slangenden&(S%%) = _NEWIMAGE(8, 14, 32)
            _DEST Slangenden&(S%%)
            COLOR _RGBA32(0, 0, 220, 100), _RGBA32(0, 0, 0, 0)
            CLS
            _PRINTSTRING (0, 0), CHR$(Souris%%(S%% + 1))
        NEXT S%%
        'Set Interlocking Positions and Piece Images
        ImNo% = 1
        FOR Column%% = 0 TO NoCols% - 1
            FOR Row%% = 0 TO NoRows% - 1
                TempImg& = _NEWIMAGE(XSize% + 26 + 1, YSize% + 26 + 1, 32)
                _DEST TempImg&
                _PUTIMAGE (13, 13)-(13 + XSize%, 13 + YSize%), FramedPic&, , ((Column%% * XSize%) + 13, (Row%% * YSize%) + 13)-((Column%% + 1) * XSize% + 13, (Row%% + 1) * YSize% + 13)
                FOR T%% = 0 TO 3
                    'Convert GridHV%% data into Lado%% data
                    IF (Column%% = 0 AND T%% = 3) OR (Column%% = (NoCols% - 1) AND T%% = 1) OR (Row%% = 0 AND T%% = 0) OR (Row%% = (NoRows% - 1) AND T%% = 2) THEN
                        Lado%%(T%%) = 0
                    ELSE
                        IF T%% = 0 THEN
                            IF GridH%%(Column%% + 1, Row%%, 0) = 1 THEN
                                Lado%%(T%%) = 2
                            ELSE
                                Lado%%(T%%) = 1
                            END IF
                            O%% = GridH%%(Column%% + 1, Row%%, 1)
                        ELSEIF T%% = 1 THEN
                            IF GridV%%(Column%% + 1, Row%% + 1, 0) = 1 THEN
                                Lado%%(T%%) = 1
                            ELSE
                                Lado%%(T%%) = 2
                            END IF
                            O%% = GridV%%(Column%% + 1, Row%% + 1, 1)
                        ELSEIF T%% = 2 THEN
                            IF GridH%%(Column%% + 1, Row%% + 1, 0) = 1 THEN
                                Lado%%(T%%) = 1
                            ELSE
                                Lado%%(T%%) = 2
                            END IF
                            O%% = GridH%%(Column%% + 1, Row%% + 1, 1)
                        ELSE
                            IF GridV%%(Column%%, Row%% + 1, 0) = 1 THEN
                                Lado%%(T%%) = 2
                            ELSE
                                Lado%%(T%%) = 1
                            END IF
                            O%% = GridV%%(Column%%, Row%% + 1, 1)
                        END IF
                    END IF
                    Q%% = T%% MOD 2
                    IF T%% = 0 OR T%% = 3 THEN
                        P%% = -1
                    ELSE
                        P%% = 1
                    END IF
                    IF Lado%%(T%%) >= 1 THEN
                        FOR S%% = 0 TO 13
                            FOR R%% = 0 TO 8
                                IF Tulpanlok%%(S%%, R%%) THEN
                                    IF Lado%%(T%%) = 1 THEN
                                        IF Q%% = 0 THEN
                                            _PUTIMAGE (XOff% + R%% + O%%, YCLine% + (YHalf% * P%%) + (S%% * P%%))-(XOff% + R%% + O%%, YCLine% + (YHalf% * P%%) + (S%% * P%%)), FramedPic&, , ((Column%% * XSize%) + XOff% + R%% + O%%, (Row%% * YSize%) + YCLine% + (YHalf% * P%%) + (S%% * P%%))-((Column%% * XSize%) + XOff% + R%% + O%%, (Row%% * YSize%) + YCLine% + (YHalf% * P%%) + (S%% * P%%))
                                        ELSE
                                            _PUTIMAGE (XCLine% + (XHalf% * P%%) + (S%% * P%%), YOff% + R%% + O%%)-(XCLine% + (XHalf% * P%%) + (S%% * P%%), YOff% + R%% + O%%), FramedPic&, , ((Column%% * XSize%) + XCLine% + (XHalf% * P%%) + (S%% * P%%), (Row%% * YSize%) + YOff% + R%% + O%%)-((Column%% * XSize%) + XCLine% + (XHalf% * P%%) + (S%% * P%%), (Row%% * YSize%) + YOff% + R%% + O%%)
                                        END IF
                                    ELSE
                                        IF Q%% = 0 THEN
                                            _PUTIMAGE (XOff% + R%% + O%%, YCLine% + (YHalf% * P%%) - (S%% * P%%))-(XOff% + R%% + O%%, YCLine% + (YHalf% * P%%) - (S%% * P%%)), Alphaimg&, , (0, 0)-(0, 0)
                                        ELSE
                                            _PUTIMAGE (XCLine% + (XHalf% * P%%) - (S%% * P%%), YOff% + R%% + O%%)-(XCLine% + (XHalf% * P%%) - (S%% * P%%), YOff% + R%% + O%%), Alphaimg&, , (0, 0)-(0, 0)
                                        END IF
                                    END IF
                                END IF
                            NEXT R%%
                        NEXT S%%
                    END IF
                NEXT T%%
                IF PicNo%% = 1 AND (ImNo% MOD 6 = 0 AND ImNo% <= 42) THEN
                    _MAPTRIANGLE (0, 0)-(7, 0)-(0, 13), Slangenden&((ImNo% \ 6) - 1) TO(XSize% - 1, YSize% + 11)-(XSize% - 1, YSize% + 4)-(XSize% + 12, YSize% + 11)
                    _MAPTRIANGLE (7, 13)-(0, 13)-(7, 0), Slangenden&((ImNo% \ 6) - 1) TO(XSize% + 12, YSize% + 4)-(XSize% + 12, YSize% + 11)-(XSize% - 1, YSize% + 4)
                END IF
                _SETALPHA 0, _RGB32(0, 0, 0) TO _RGB32(0, 0, 0)
                PictImg&(ImNo%) = HardwareImage&(TempImg&)
                ImNo% = ImNo% + 1
            NEXT Row%%
        NEXT Column%%
        _FREEIMAGE FramedPic&
        _FREEIMAGE Alphaimg&
        'Load Additional Images
        ImgTemp& = _NEWIMAGE(600, 90, 32)
        _DEST ImgTemp&
        COLOR _RGB32(255, 255, 0), _RGBA32(0, 0, 0, 0)
        CLS
        Cali& = _LOADFONT("calibriz.ttf", 80)
        _FONT Cali&
        _PRINTSTRING (0, 0), "Puzzle Completed"
        WellDone& = HardwareImage&(ImgTemp&)
        _FREEFONT Cali&
        'Draw grids
        ImgTemp& = _NEWIMAGE((NoCols% * XSize%) + 3, (NoRows% * YSize%) + 3, 32)
        _DEST ImgTemp&
        COLOR _RGB32(255, 0, 0), _RGBA32(0, 0, 0, 255)
        CLS
        FOR Q%% = 1 TO NoCols%
            FOR R%% = 1 TO NoRows%
                LINE ((Q%% - 1) * XSize%, (R%% - 1) * YSize%)-(Q%% * XSize%, R%% * YSize%), , B , 3
            NEXT R%%
        NEXT Q%%
        LINE (0, 0)-((NoCols% * XSize%) + 1, (NoRows% * YSize%) + 1), , B
        LINE (1, 1)-((NoCols% * XSize%) + 2, (NoRows% * YSize%) + 2), , B
        Grenze&(0) = HardwareImage&(ImgTemp&)
        'Draw highlight
        ImgTemp& = _NEWIMAGE(XSize% + 1, YSize% + 1, 32)
        _DEST ImgTemp&
        COLOR _RGB32(255, 0, 0), _RGBA32(0, 0, 0, 0)
        CLS
        LINE (0, 0)-(XSize%, YSize%), , B
        LINE (1, 1)-(XSize% - 1, YSize% - 1), , B
        Grenze&(1) = HardwareImage&(ImgTemp&)
        'Randomise Positions of Pieces
        FOR N% = 1 TO NoPieces%
            Numbers%(N%) = N%
        NEXT N%
        FillStock%% = False: FillNo% = NoPieces%
        WHILE NOT FillStock%%
            IF FillNo% = 1 THEN
                Stock%(1) = Numbers%(1)
                FillStock%% = True
            ELSE
                Seln% = 1 + INT(RND * FillNo%)
                Stock%(FillNo%) = Numbers%(Seln%)
                IF Seln% <> FillNo% THEN
                    FOR N% = Seln% TO FillNo% - 1
                        Numbers%(N%) = Numbers%(N% + 1)
                    NEXT N%
                END IF
                FillNo% = FillNo% - 1
            END IF
        WEND
        FOR N% = 1 TO NoPieces%
            Orient%%(N%) = INT(RND * 4)
            IF N% > Espacos%%(0) * Espacos%%(1) THEN
                'Place piece in bottom spaces
                N1% = N% - Espacos%%(0) * Espacos%%(1)
                Q%% = 1 + ((N1% - 1) MOD Espacos%%(2))
                R%% = 1 + ((N1% - 1) \ Espacos%%(2))
                BottomEspacos%%(Q%%, R%%) = Stock%(N%)
            ELSE
                'Place piece in top spaces
                Q%% = 1 + ((N% - 1) MOD Espacos%%(0))
                R%% = 1 + ((N% - 1) \ Espacos%%(0))
                TopEspacos%%(Q%%, R%%) = Stock%(N%)
            END IF
        NEXT N%

        'Now Do the Puzzle
        K$ = "": IsSmall%% = True: PickedUp% = 0: DoneCount% = 0: Completed%% = False
        SCREEN _NEWIMAGE(ScreenX%, ScreenY%, 32)
        _DEST 0
        _SCREENMOVE 5, 5
        COLOR _RGB32(255, 0, 0), _RGB32(0, 0, 0)
        CLS
        _DISPLAYORDER _HARDWARE
        WHILE DoPuzzle%%
            _LIMIT 60
            'Images in Top Grid
            FOR Q%% = 1 TO Espacos%%(0)
                FOR R%% = 1 TO Espacos%%(1)
                    N% = TopEspacos%%(Q%%, R%%)
                    IF N% <> 0 AND N% <> PickedUp% THEN CALL DisplayPiece((PictImg&(N%)), X1% + (Q%% - 1) * (XSize% + X1Gap%%) - 13, Y1% + (R%% - 1) * (YSize% + Y1Gap%%) - 13, (Orient%%(N%)))
                NEXT R%%
            NEXT Q%%
            'Images in Bottom Grid
            FOR Q%% = 1 TO Espacos%%(2)
                FOR R%% = 1 TO Espacos%%(3)
                    N% = BottomEspacos%%(Q%%, R%%)
                    IF N% <> 0 AND N% <> PickedUp% THEN CALL DisplayPiece((PictImg&(N%)), X3% + (Q%% - 1) * (XSize% + X3Gap%%) - 13, Y3% + (R%% - 1) * (YSize% + Y3Gap%%) - 13, (Orient%%(N%)))
                NEXT R%%
            NEXT Q%%
            'Images in Main Grid
            _PUTIMAGE (X4% - 1, Y4% - 1), Grenze&(0)
            FOR Q%% = 1 TO NoCols%
                FOR R%% = 1 TO NoRows%
                    N% = Grid~%%(Q%%, R%%)
                    IF N% <> 0 AND N% <> PickedUp% THEN CALL DisplayPiece((PictImg&(N%)), X4% + (Q%% - 1) * XSize% - 13, Y4% + (R%% - 1) * YSize% - 13, (Orient%%(N%)))
                NEXT R%%
            NEXT Q%%
            'Other Images
            IF IsSmall%% THEN
                _PUTIMAGE (X2%, Y2%)-(X21%, Y21%), BorderedPic&
                IF (InMain%% OR InTop%% OR InBot%%) AND PickedUp% = 0 THEN
                    _PUTIMAGE (XBox%, YBox%), Grenze&(1)
                ELSEIF PickedUp% <> 0 THEN
                    CALL DisplayPiece((PictImg&(PickedUp%)), XMouse% - ((XSize% + 26) \ 2), YMouse% - ((YSize% + 26) \ 2), (Orient%%(PickedUp%)))
                END IF
            ELSE
                _PUTIMAGE (X22%, Y2%), BorderedPic&
            END IF

            IF NOT Completed%% THEN
                'Mouse Manipulations
                WHILE _MOUSEINPUT
                    XMouse% = _MOUSEX: YMouse% = _MOUSEY
                    WithinMain%% = False: InMain%% = False: InTop%% = False: InBot%% = False
                    IF XMouse% > X4% + 2 AND XMouse% < X41% - 2 AND YMouse% > Y4% + 2 AND YMouse% < Y41% - 2 THEN
                        WithinMain%% = True
                        CALL Extract((XMouse%), (YMouse%), (X4%), (Y4%), (XSize%), (YSize%), Q%%, R%%)
                        IF Grid~%%(Q%%, R%%) <> 0 THEN
                            XBox% = X4% + (Q%% - 1) * XSize%
                            YBox% = Y4% + (R%% - 1) * YSize%
                            InMain%% = True
                        END IF
                    ELSEIF XMouse% > X1% + 2 AND XMouse% < X11% - 2 AND YMouse% > Y1% + 2 AND YMouse% < Y11% - 2 THEN
                        CALL Extract((XMouse%), (YMouse%), (X1% - 13), (Y1% - 13), (XSize% + X1Gap%%), (YSize% + Y1Gap%%), Q%%, R%%)
                        IF TopEspacos%%(Q%%, R%%) <> 0 THEN
                            XBox% = X1% + (Q%% - 1) * (XSize% + X1Gap%%)
                            YBox% = Y1% + (R%% - 1) * (YSize% + Y1Gap%%)
                            InTop%% = True
                        END IF
                    ELSEIF XMouse% > X3% + 2 AND XMouse% < X31% - 2 AND YMouse% > Y3% + 2 AND YMouse% < Y31% - 2 THEN
                        CALL Extract((XMouse%), (YMouse%), (X3% - 13), (Y3% - 13), (XSize% + X3Gap%%), (YSize% + Y3Gap%%), Q%%, R%%)
                        IF BottomEspacos%%(Q%%, R%%) <> 0 THEN
                            XBox% = X3% + (Q%% - 1) * (XSize% + X3Gap%%)
                            YBox% = Y3% + (R%% - 1) * (YSize% + Y3Gap%%)
                            InBot%% = True
                        END IF
                    END IF
                    IF _MOUSEBUTTON(Souris%%(0)) THEN
                        IF NOT IsSmall%% THEN
                            IsSmall%% = True
                        ELSEIF IsSmall%% AND PickedUp% = 0 AND XMouse% > X2% + 2 AND XMouse% < X21% - 2 AND YMouse% > Y2% AND YMouse% < Y21% - 2 THEN
                            IsSmall%% = False
                        ELSEIF PickedUp% = 0 AND InMain%% THEN
                            'Select piece if available from main grid
                            PickedUp% = Grid~%%(Q%%, R%%)
                            Grid~%%(Q%%, R%%) = 0
                        ELSEIF PickedUp% = 0 AND InTop%% THEN
                            'Select piece if available from top grid
                            PickedUp% = TopEspacos%%(Q%%, R%%)
                            TopEspacos%%(Q%%, R%%) = 0
                        ELSEIF PickedUp% = 0 AND InBot%% THEN
                            'Select piece if available from bottom grid
                            PickedUp% = BottomEspacos%%(Q%%, R%%)
                            BottomEspacos%%(Q%%, R%%) = 0
                        ELSEIF PickedUp% <> 0 AND WithinMain%% THEN
                            'Place piece in main grid if not occupied
                            IF NOT InMain%% THEN
                                Grid~%%(Q%%, R%%) = PickedUp%
                                PickedUp% = 0
                            END IF
                        ELSEIF PickedUp% <> 0 THEN
                            'Move to vacant:  click anywhere outside main grid
                            FindPlace%% = False
                            WHILE NOT FindPlace%%
                                Q%% = 1
                                WHILE NOT FindPlace%% AND Q%% <= Espacos%%(0)
                                    R%% = 1
                                    WHILE NOT FindPlace%% AND R%% <= Espacos%%(1)
                                        IF TopEspacos%%(Q%%, R%%) = 0 THEN
                                            FindPlace%% = True
                                            TopEspacos%%(Q%%, R%%) = PickedUp%
                                        ELSE
                                            R%% = R%% + 1
                                        END IF
                                    WEND
                                    Q%% = Q%% + 1
                                WEND
                                Q%% = 1
                                WHILE NOT FindPlace%% AND Q%% <= Espacos%%(2)
                                    R%% = 1
                                    WHILE NOT FindPlace%% AND R%% <= Espacos%%(3)
                                        IF BottomEspacos%%(Q%%, R%%) = 0 THEN
                                            FindPlace%% = True
                                            BottomEspacos%%(Q%%, R%%) = PickedUp%
                                        ELSE
                                            R%% = R%% + 1
                                        END IF
                                    WEND
                                    Q%% = Q%% + 1
                                WEND
                            WEND
                            PickedUp% = 0
                        END IF
                    ELSEIF _MOUSEBUTTON(Souris%%(8)) AND PickedUp% <> 0 THEN
                        'Rotate piece when picked up
                        Orient%%(PickedUp%) = Orient%%(PickedUp%) + 1
                        IF Orient%%(PickedUp%) > 3 THEN Orient%%(PickedUp%) = 0
                    END IF
                    DO 'make sure that mouse button is released
                        Dum%% = _MOUSEINPUT
                    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(0))
                    DO 'make sure that mouse button is released
                        Dum%% = _MOUSEINPUT
                    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(8))
                WEND

                'Look for completed puzzle
                Completed%% = True: CCount% = 1
                WHILE Completed%% AND CCount% <= NoPieces%
                    Q%% = 1 + ((CCount% - 1) \ NoRows%)
                    R%% = 1 + ((CCount% - 1) MOD NoRows%)
                    IF Grid~%%(Q%%, R%%) <> CCount% OR Orient%%(Grid~%%(Q%%, R%%)) <> 0 THEN
                        Completed%% = False
                    ELSE
                        CCount% = CCount% + 1
                    END IF
                WEND
            ELSE
                DoneCount% = DoneCount% + 1
                IF DoneCount% > 30 THEN
                    _PUTIMAGE (5, 85)-(1200, ScreenY% - 5), Jigsaw&(PicNo%% - 1)
                END IF
                IF DoneCount% > 70 THEN
                    _PUTIMAGE (450, 380), WellDone&
                END IF
                IF DoneCount% > 240 THEN
                    DoPuzzle%% = False
                END IF
            END IF
            K$ = INKEY$
            IF K$ <> "" THEN
                IF ASC(K$) = 27 THEN DoPuzzle%% = False
            END IF
            K$ = ""
            _DISPLAY
        WEND
        FOR N% = 1 TO NoPieces%
            _FREEIMAGE PictImg&(N%)
        NEXT N%
        _FREEIMAGE Jigsaw&(PicNo%% - 1)
        _FREEIMAGE BorderedPic&
        _FREEIMAGE WellDone&
        FOR S%% = 0 TO 1
            _FREEIMAGE Grenze&(S%%)
        NEXT S%%
        FOR S%% = 0 TO 6
            _FREEIMAGE Slangenden&(S%%)
        NEXT S%%
    END IF

    'Another Run?
    _TITLE "Jigsaw Puzzle - Another Puzzle?"
    _AUTODISPLAY
    CLS
    WHILE INKEY$ <> "": K$ = INKEY$: WEND 'Clear inkey buffer
    DO 'Make sure that mouse button is released
        Dum%% = _MOUSEINPUT
    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(0))
    DO 'Make sure that mouse button is released
        Dum%% = _MOUSEINPUT
    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(8))

    ImgTemp& = _NEWIMAGE(320, 80, 32)
    _DEST ImgTemp&
    COLOR _RGB32(255, 0, 0), _RGBA32(100, 100, 100, 120)
    CLS
    Highlight& = HardwareImage&(ImgTemp&)
    ImgTemp& = _NEWIMAGE(500, 500, 32)
    _DEST ImgTemp&
    COLOR _RGB32(255, 255, 0), _RGB32(80, 80, 80)
    CLS
    Cali& = _LOADFONT("calibriz.ttf", 80)
    _FONT Cali&
    _PRINTSTRING (120, 95), "Another"
    _PRINTSTRING (120, 160), "Puzzle?"
    COLOR _RGB32(0, 255, 0)
    _PRINTSTRING (180, 300), "Yes"
    COLOR _RGB32(255, 0, 0)
    _PRINTSTRING (190, 420), "No"
    Repeat& = HardwareImage&(ImgTemp&)
    _FREEFONT Cali&
    SCREEN _NEWIMAGE(500, 500, 32)
    _SCREENMOVE 100, 100
    _DEST 0
    DoExit%% = False: DoJigsaw%% = False: K$ = ""
    WHILE NOT DoExit%%
        _LIMIT 60
        _PUTIMAGE (0, 0), Repeat&
        WHILE _MOUSEINPUT
            XMouse% = _MOUSEX: YMouse% = _MOUSEY
            IF _MOUSEBUTTON(Souris%%(0)) THEN
                IF XMouse% > 96 AND XMouse% < 394 AND YMouse% > 281 AND YMouse% < 349 THEN
                    DoJigsaw%% = True
                    DoExit%% = True
                ELSEIF YMouse% >= 381 AND YMouse% <= 449 AND XMouse% >= 96 AND XMouse% <= 394 THEN
                    DoExit%% = True
                END IF
            END IF
        WEND
        IF YMouse% >= 280 AND YMouse% <= 350 AND XMouse% >= 95 AND XMouse% < 395 THEN
            _PUTIMAGE (85, 285), Highlight&
        ELSEIF YMouse% >= 380 AND YMouse% <= 450 AND XMouse% >= 95 AND XMouse% <= 395 THEN
            _PUTIMAGE (85, 405), Highlight&
        END IF
        K$ = INKEY$
        IF K$ <> "" THEN
            IF ASC(K$) = 13 THEN 'CR
                IF XMouse% > 96 AND XMouse% < 394 AND YMouse% > 281 AND YMouse% < 349 THEN
                    DoJigsaw%% = True
                    DoExit%% = True
                ELSEIF YMouse% >= 381 AND YMouse% <= 449 AND XMouse% >= 96 AND XMouse% <= 394 THEN
                    DoExit%% = True
                ELSE
                    K$ = ""
                END IF
            ELSE
                DoExit%% = True
                IF UCASE$(K$) = "Y" THEN DoJigsaw%% = True
            END IF
        END IF
        _DISPLAY
    WEND
    _FREEIMAGE Highlight&
    _FREEIMAGE Repeat&
    _AUTODISPLAY
    CLS
    WHILE INKEY$ <> "": K$ = INKEY$: WEND 'Clear inkey buffer
    DO 'Make sure that mouse button is released
        Dum%% = _MOUSEINPUT
    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(0))
    DO 'Make sure that mouse button is released
        Dum%% = _MOUSEINPUT
    LOOP UNTIL NOT _MOUSEBUTTON(Souris%%(8))

WEND

SYSTEM

FUNCTION HardwareImage& (ImageName&)
    HardwareImage& = _COPYIMAGE(ImageName&, 33)
    _FREEIMAGE ImageName&
END FUNCTION

SUB DisplayPiece (Pict&, X%, Y%, Ont%%)
    SELECT CASE Ont%%
        CASE 0
            _PUTIMAGE (X%, Y%), Pict&
        CASE 1
            _MAPTRIANGLE (0, 0)-(XSize% + 26, 0)-(XSize% + 26, YSize% + 26), Pict& TO(X% + XSize% + 26, Y%)-(X% + XSize% + 26, Y% + YSize% + 26)-(X%, Y% + YSize% + 26)
            _MAPTRIANGLE (XSize% + 26, YSize% + 26)-(0, YSize% + 26)-(0, 0), Pict& TO(X%, Y% + YSize% + 26)-(X%, Y%)-(X% + XSize% + 26, Y%)
        CASE 2
            _MAPTRIANGLE (0, 0)-(XSize% + 26, 0)-(XSize% + 26, YSize% + 26), Pict& TO(X% + XSize% + 26, Y% + YSize% + 26)-(X%, Y% + YSize% + 26)-(X%, Y%)
            _MAPTRIANGLE (XSize% + 26, YSize% + 26)-(0, YSize% + 26)-(0, 0), Pict& TO(X%, Y%)-(X% + XSize% + 26, Y%)-(X% + XSize% + 26, Y% + YSize% + 26)
        CASE ELSE
            _MAPTRIANGLE (0, 0)-(XSize% + 26, 0)-(XSize% + 26, YSize% + 26), Pict& TO(X%, Y% + YSize% + 26)-(X%, Y%)-(X% + XSize% + 26, Y%)
            _MAPTRIANGLE (XSize% + 26, YSize% + 26)-(0, YSize% + 26)-(0, 0), Pict& TO(X% + XSize% + 26, Y%)-(X% + XSize% + 26, Y% + YSize% + 26)-(X%, Y% + YSize% + 26)
    END SELECT
END SUB

SUB Extract (XM%, YM%, X0%, Y0%, XStep%, YStep%, QQ%%, RR%%)
    QQ%% = 1 + ((XM% - X0%) \ XStep%)
    RR%% = 1 + ((YM% - Y0%) \ YStep%)
END SUB
Reply
#2
Nicely done!  And challenging too.  I just solved the snow cabin one over breakfast.  That brick wall is going to take some time to solve!   I don't how I missed your programs at the old forum.  Some great coding you're doing. Thanks for sharing!

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#3
@Dav thanks for the plaudits.  One of the pleasures in putting that together was to get the interlocking areas as for a jigsaw.  _MAPTRIANGLE obviously, but now I have no idea how I actually went about it.  I used to enjoy doing the Birth of Venus jigsaw.

Richard
Reply
#4
Hey, looking at your code, looks like you copy the images as hardware image when moving them on the screen.  Slick trick.  Also, ByTheTimeIGetTo& = _LoadImage("Phoenix.jpg", 32)  LOL. Smile 

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#5
Smile The thing is that The Compiler knows nothing about the Coder having a chuckle with the Code.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Trackword Puzzle Solver InForm Program Magdha 17 815 01-26-2026, 09:16 PM
Last Post: bplus
  Four-Room Maze Puzzle Game Magdha 0 162 12-28-2025, 11:17 AM
Last Post: Magdha
  Sliding Block Picture Puzzle Magdha 0 227 11-29-2025, 10:14 AM
Last Post: Magdha

Forum Jump:


Users browsing this thread: 1 Guest(s)