' ****** START INCLUDE PUTSTRING(x%, y%, s$) ******
SUB PUTSTRING(x%, y%, s$)
  FOR c = 1 TO LEN(s$)
    sc$ = MID$(s$, c, 1)
    this$ = _GETCHR$(ASC(sc$))
    FOR yi = 0 TO 7
      FOR xi = 0 TO 7
        x_pset% = x% + xi + (c-1)*8 : y_pset% = y% + yi
        IF MID$(this$, (xi + yi*8) + 1, 1) = "X" AND BETWEEN(x_pset%, 0, _WIDTH-1) AND BETWEEN(y_pset%, 0, _HEIGHT-1)  THEN PSET (x_pset%, y_pset%)
      NEXT xi
    NEXT yi
  NEXT c
END SUB
'  ****** END INCLUDE PUTSTRING(x%, y%, s$) ******

'📚📚📚📚

' This BASIC Anywhere Machine program by Charlie Veniot
' This program exported from BASIC Anywhere Machine (Version [5.2.3].[2023.07.15.14.59]) on 2023.07.15 at 17.03

'🟠🟠🟠🟠 -— Declarations -—

CONST  Go⬅ = 0, Go➡ = 1, Go⬆ = 2, Go⬇ = 3

Side📐 = 4 ' Puzzle side length in number of tiles
ts = 56 ' tile side length in pixels

DECLARE FUNCTION IsPuzzleComplete%()

'🟠🟠🟠🟠 -— Main Program -—

_ALERT("Solve the puzzle.\n\n" + _
       "Every tile is labelled with the X,Y position indicating where the tile belongs.\n\n"  + _
       "Only coloured tiles adjacent to the black tile (labelled 1,1) can move.\n\n" + _
       "Click on such a tile, and it will switch positions with the black tile.\n\n" + _
       "The puzzle will be solved when each tile is in its correct X,Y position.\n\n" + _
       "Click OK to view the tiles in their correct positions, then click on the screen to shuffle the pieces and play.")

🎉NewGame:

  temp$ = _PROMPT("How big of a square puzzle?  Enter the length of one side (3 to 8).", "4")
  IF temp$ = "" THEN SCREEN 0 : PRINT "Have a great day!" : END
  Side📐 =  VAL( temp$ )
  IF NOT BETWEEN(Side📐, 2, 8) THEN Side📐 = 4
  SCREEN _NEWIMAGE(Side📐 * ts, Side📐 * ts, 14)
  GOSUB ⚙InitTheBoard
  _ALERT("Take a look at the completed puzzle.  Click on the screen when you are ready to shuffle the puzzle board.")
  SLEEP 

  x = 0 : y = 0 : i = 0
  GOSUB 🧩ScrambleTheBoard
  _DISPLAY
            
  _ALERT("Okay, done shuffling the puzzle board.  Have fun !")

  🏁Loopstart: 
      IF _MOUSEBUTTON THEN 
          xpos = INT( _MOUSEX / ts ) : ypos = INT( _MOUSEY / ts ) 
          WHILE _MOUSEBUTTON : WEND 
          IF POINT(xpos*ts,ypos*ts) <> 0 THEN
              IF xpos > 0 AND POINT([(xpos-1)*ts], [ypos*ts]) = 0 _
                 THEN GOSUB ⬅Scroll : GOTO ✅IsPuzzleComplete
              IF xpos < (Side📐-1) AND POINT([(xpos+1)*ts], [ypos*ts]) = 0 _
                 THEN GOSUB ➡Scroll : GOTO ✅IsPuzzleComplete
              IF ypos > 0 AND POINT([xpos*ts], [(ypos-1)*ts]) = 0 _
                 THEN GOSUB ⬆Scroll : GOTO ✅IsPuzzleComplete
              IF ypos < (Side📐-1) AND POINT([xpos*ts], [(ypos+1)*ts]) = 0 _
                 THEN GOSUB ⬇Scroll
              ✅IsPuzzleComplete:
              _DISPLAY
              IF IsPuzzleComplete%()  _
                 THEN _ALERT("Woohoo !! you've solved the puzzle !!  Let's setup the next game.") :  GOTO 🎉NewGame
          END IF
      END IF

  GOTO 🏁Loopstart

END

'🟠🟠🟠🟠 -— Functions -—

FUNCTION IsPuzzleComplete%()
    temp% = TRUE
    c = 0 : x = 0
    DO : y = 0
        DO
            IF POINT(x*ts, y*ts) <> c THEN temp% = FALSE
            c = c + 1        
            y = y + 1
        LOOP UNTIL y = Side📐 OR temp% = FALSE
        x = x + 1
    LOOP UNTIL x = Side📐 OR temp% = FALSE
IsPuzzleComplete% = temp%
END FUNCTION

'🟠🟠🟠🟠 -— Subroutines -—

⚙InitTheBoard:
    c = 0
    FOR x = 0 TO (Side📐-1)
      FOR y = 0 TO (Side📐-1)
          LINE (x*ts,y*ts) - (x*ts+ts-1, y*ts+ts-1), c, BF
          LINE (x*ts+8,y*ts+32) - (x*ts+46, y*ts+46), 0, BF
          PUTSTRING( [ x*ts+8 ], [ y*ts+35 ], [ STR$(x+1) + "," + REPLACE$(STR$(y+1)," ","") ] )  
          c = c + 1
      NEXT y
    NEXT x
    _DISPLAY
RETURN

🧩ScrambleTheBoard:
    LastGo = 99
    another_move:
        Go🎲 = int(rnd * 4) 
            IF [ Go🎲 = Go⬅ AND LastGo = Go➡ ] OR [ Go🎲 = Go➡ AND LastGo = Go⬅ ] _
               OR [ Go🎲 = Go⬆ AND LastGo = Go⬇ ] OR [ Go🎲 = Go⬇ AND LastGo = Go⬆ ] _
               OR [ x = 0 AND Go🎲 = Go⬅ ] _
               OR [ x = (Side📐-1) AND Go🎲 = Go➡ ] _
               OR [ y = 0 AND Go🎲 = Go⬆ ] _
               OR [ y = (Side📐-1) AND Go🎲 = Go⬇ ] _
            THEN GOTO another_move
        GOSUB 🔄DoSwitch 
        LastGo = Go🎲
        i = i + 1
    IF i < [ (Side📐^2) * 10 ] THEN GOTO another_move
    IF IsPuzzleComplete%() THEN i = 0 : GOTO another_move
RETURN

🔄DoSwitch:
    SELECT CASE Go🎲
        CASE Go⬅
            SCROLL ([(x-1)*ts],[y*ts]) - ([x*ts+ts-1],[y*ts+ts-1]), ts, 0, TRUE 
            x = x - 1
        CASE Go➡
            SCROLL ([x*ts],[y*ts]) - ([(x+1)*ts+ts-1],[y*ts+ts-1]), ts, 0, TRUE
            x = x + 1
        CASE Go⬆
            SCROLL ([x*ts],[(y-1)*ts]) - ([x*ts+ts-1],[y*ts+ts-1]), 0, -ts, TRUE
            y = y - 1
        CASE Go⬇
            SCROLL ([x*ts],[y*ts]) - ([x*ts+ts-1],[(y+1)*ts+ts-1]), 0, ts, TRUE
            y = y + 1
    END SELECT
    _DISPLAY
RETURN

⬅Scroll:
    FOR I = 1 TO ts STEP 4
        SCROLL ( [(xpos-1)*ts] , [ ypos*ts ]) _
               - ( [(xpos-1)*ts+ts*2-1],[ ypos*ts+ts-1 ] ), -4, 0, TRUE
        _DISPLAY               
    NEXT I
RETURN

➡Scroll:
    FOR I = 1 TO ts STEP 4
        SCROLL ( [(xpos)*ts], [ ypos*ts ]) _
               - ( [(xpos)*ts+ts*2-1], [ ypos*ts+ts-1 ] ), 4, 0, TRUE
        _DISPLAY
    NEXT I
RETURN

⬆Scroll:
    FOR I = 1 TO ts STEP 4
        SCROLL ( [xpos*ts] , [ (ypos-1)*ts ]) _
               - ( [xpos*ts+ts-1],[ (ypos-1)*ts+ts*2-1 ] ), 0, -4, TRUE
        _DISPLAY
    NEXT I
RETURN

⬇Scroll:
    FOR I = 1 TO ts STEP 4
        SCROLL ( [ xpos*ts ] , [ (ypos)*ts ]) _
               - ( [xpos*ts+ts-1],[ (ypos)*ts+ts*2-1 ] ), 0, 4, TRUE
        _DISPLAY
    NEXT I
RETURN 

'🟠🟠🟠🟠 -— END OF FILE -—