Sliding Blocks Puzzle

I thought it would be fun to create a sliding-block puzzle on-screen. However I lost the code when I accidentally copied an 8G card image over the firtst 8G of my hard drive! This is therefore a re-creation, and bits are yet to add ( see the remarks in the code). I think an AI autosolver is beyond me however!

Code at present requires a 400x400 bitmap image called 'cellist.bmp', but fileselector will be added soon.

To be continued.....






    '   ********************************************************************
    '   **                                                                **
    '   **    SlidingBlocks6a1.bas  tenochtitlanuk   17 Jan 2020          **
    '   **                                                                **
    '   ********************************************************************

    '   To-dos
    '       make the move conditional on whether adjacent block chosen and blank    DONE
    '       get the graphics to work correctly- array seems to work & update        DONE

    '       add initial shuffle                                                     DONE

    '       add option to choose image, including one showing numbers
    '       test if all are in 'correct' places and announce number of attempted moves entered

    '       add routine to display moves attempted
    '       add routine to detect completion.
    '       add routine to save moves so can reverse/rewind to start.....



       nomainwin

    global blankX, blankY, clicks

    WindowWidth  = 412
    WindowHeight = 440
    UpperLeftX   = 800
    UpperLeftY   =  20

    open "Sliding blocks puzzle" for graphics_nsb as #wg

    #wg "trapclose quit"

    #wg "when leftButtonUp moveIfPossible"

    loadbmp "scr", "cellist.bmp"
    #wg "drawbmp scr 1 1 ; flush"

    dim puzzle$( 5, 5)

    i =1

    for y =1 to 4   '   save tile00 to tile15
        for x =1 to 4
            #wg "getbmp tile" +right$( "00" +str$( i), 2); " "; ( x -1) *100; " "; ( y -1) *100; " 100 100"
            'bmpsave "tile", "tile_" +right$( "00" +str$( i), 2)
            puzzle$( x, y) ="tile" +right$( "00" +str$( x +( y -1) *4), 2)
            i =i +1
        next x
    next y

    #wg "cls"   '   and now tile16, all white blank one
    #wg "getbmp tile16 300 300 100 100"
    #wg "cls"

    blankX =4
    blankY =4
    clicks =0

    '   fill the puzzle area systematically
    'for i =1 to 15  '   tile16 is the white one...
    '    #wg "drawbmp tile" +right$( "00" +str$( i), 2); " "; 100 *( ( i -1) mod 4); " "; 100 *( int( ( i -1) /4))
    'next i
    '        . .  . . . OR fill at random
    posn$       =" 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16"
    scrambled$  =""
    do
        R           =int( len( posn$) /3 *rnd( 1))              '   ie 0 ... 15
        scrambled$  =scrambled$ +mid$( posn$, 1 +3 *R, 3)       '   3 chars   starting at 1, 4, 7, ..
        lPart$      =left$( posn$, 3 *R)                        '   all chars up to & inc 0, 3, 6, ....
        rPart$      =mid$(  posn$, 3 *R +4)                     '   all chars after & inc 4, 7,10, ....
        posn$       =lPart$ +rPart$
        print scrambled$

        scan
    loop until len( posn$) =0

    for i =0 to 15
        x                       =( i mod 4)
        y                       =int( i /4)
        puzzle$( x +1, y +1)    ="tile" +mid$( scrambled$, 3 *i +2, 2)
        XX                      =val( mid$( puzzle$( x +1, y +1), 5, 1))
        YY                      =val( mid$( puzzle$( x +1, y +1), 6, 1))
        print "x+1, y+1 "; x+1; " "; y+1, "XX, YY "; XX; " "; YY; " tile = "; puzzle$( x +1, y +1)
        #wg "drawbmp "; puzzle$( x+1, y+1); " "; 100 *x; " "; 100 *y
        if str$( XX) ="1" and str$( YY) ="6" then blankX =x +1: blankY =y +1: print "Blank tile @ "; blankX; "; "; blankY
    next i

    print ""
    for y =1 to 4
        for x =1 to 4
            print puzzle$( x, y),
        next x
        print ""
    next y

    wait

    sub quit h$
        close #wg
        end
    end sub

    sub moveIfPossible h$, x, y
        'scan
        if clicks =0 then
            for y =1 to 4
                for x =1 to 4
                    print puzzle$( x, y),
                next x
                print ""
            next y
        end if

        print ""


        clicks                      =clicks +1

        tileX                       =int( MouseX /100) +1   '   1 to 4 in x and y
        tileY                       =int( MouseY /100) +1


        if ( tileX =4) and ( tileY =4) and abs( tileX -blankX) =1 and ( tileY -blankY) =1 then notice "Home!!": goto [kk]
        if ( tileX =blankX) and ( tileY =blankY)             then notice "You clicked space!": goto [skip]
        if abs( tileX -blankX) >1 or abs( tileY -blankY) >1  then notice "Too far away!":      goto [skip]
        if abs( tileX -blankX) =1 and abs( tileY -blankY) =1 then notice "Diagonal!":          goto [skip]
      [kk]
        print " Swap "; tileX; " ";  tileY; " "; puzzle$(  tileX,  tileY); " with ";_
                       blankX; " "; blankY; " "; puzzle$( blankX, blankY)

        ch                          =(  tileX) +4 *(  tileY -1)
        bl                          =( blankX) +4 *( blankY -1)

        #wg   "drawbmp "; puzzle$( blankX, blankY); " "; (  tileX -1) *100; " "; (  tileY -1) *100
        #wg   "drawbmp "; puzzle$(  tileX,  tileY); " "; ( blankX -1) *100; " "; ( blankY -1) *100

        temp$                       =puzzle$( blankX, blankY)
        puzzle$( blankX, blankY)    =puzzle$(  tileX,  tileY)
        puzzle$(  tileX,  tileY)    =temp$

        blankX                      =tileX
        blankY                      =tileY

        for y =1 to 4
            for x =1 to 4
                print puzzle$( x, y),
            next x
            print ""
        next y

        print " Blank at "; blankX; ", "; blankY
        print ""

        #wg "getbmp all 0 0 399 399"
        bmpsave "all", "all/all_" +right$( "000" +str$( clicks), 3) +".bmp"

      [skip]
    end sub

    end