Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Classic 15 puzzle
#1
Here's the classic 15 puzzle game in QB64.  Use arrows to move numbers to the empty place.  Put numbers in order 1 to 15 to solve puzzle.  Uses the handy Text SUB by @bplus for the big numbers.

- Dav

Code: (Select All)
'============
'15puzzle.bas
'============
'The classic 15 puzzle game in QB64.
'By Dav, OCT/2024

'Use arrows to move numbers to the empty place.
'Put numbers in order 1 to 15 to solve puzzle.

'Text SUB made by bplus (thanks bplus!)

Randomize Timer

dh = Int(_DesktopHeight * .75) 'scale board to 75% of users desktop height
Screen _NewImage(dh, dh, 32)

Dim board(4, 4) '4x4 board

'=== init board
Dim num(15) '15 random numbers
For n = 0 To 14
    num(n) = n + 1
Next: num(15) = 0 'this one is empty
For b = 1 To 500 'shuffle
    Swap num(Int(Rnd * 15)), num(15)
Next
b = 0 'assign on the board
For row = 0 To 4 - 1
    For col = 0 To 4 - 1
        board(row, col) = num(b)
        If board(row, col) = 0 Then
            emptyrow = row: emptycol = col
        End If
        b = b + 1
    Next
Next

GoSub DrawBoard

'=== main loop
Do

    '=== get user input
    Do
        key$ = InKey$: _Limit 30
    Loop Until key$ <> ""

    Select Case key$
        Case Chr$(0) + Chr$(72) 'up
            If emptyrow < 4 - 1 Then
                board(emptyrow, emptycol) = board(emptyrow + 1, emptycol)
                board(emptyrow + 1, emptycol) = 0
                emptyrow = emptyrow + 1
            End If
        Case Chr$(0) + Chr$(80) 'down
            If emptyrow > 0 Then
                board(emptyrow, emptycol) = board(emptyrow - 1, emptycol)
                board(emptyrow - 1, emptycol) = 0
                emptyrow = emptyrow - 1
            End If
        Case Chr$(0) + Chr$(75) 'left
            If emptycol < 4 - 1 Then
                board(emptyrow, emptycol) = board(emptyrow, emptycol + 1)
                board(emptyrow, emptycol + 1) = 0
                emptycol = emptycol + 1
            End If
        Case Chr$(0) + Chr$(77) 'right
            If emptycol > 0 Then
                board(emptyrow, emptycol) = board(emptyrow, emptycol - 1)
                board(emptyrow, emptycol - 1) = 0
                emptycol = emptycol - 1
            End If
        Case Chr$(27) 'quit
            End
    End Select

    GoSub DrawBoard

    '== check if puzzle solved
    solved = 1: tally = 1
    For row = 0 To 4 - 1
        For col = 0 To 4 - 1
            If board(row, col) <> 0 Then
                If board(row, col) <> tally Then solved = 0
                tally = tally + 1
            End If
        Next
    Next
    If solved = 1 Then Exit Do

Loop

GoSub DrawBoard

Line (0, 0)-(_Width, _Height), _RGBA(0, 0, 0, 150), BF
Text _Width / 4 + 2, _Height / 3 + 2, _Width / 8, _RGB(0, 0, 0), "SOLVED!!"
Text _Width / 4, _Height / 3, _Width / 8, _RGB(255, 255, 0), "SOLVED!!"
_Display

End

'========
DrawBoard:
'========

size = _Width / 4
For row = 0 To 4 - 1
    For col = 0 To 4 - 1
        x1 = (col * size): x2 = x1 + size
        y1 = (row * size): y2 = y1 + size
        If board(row, col) = 0 Then
            Line (x1, y1)-(x2, y2), _RGB(0, 0, 0), BF
        Else
            Line (x1, y1)-(x2, y2), _RGB(200, 0, 0), BF
            Line (x1, y1)-(x2, y2), _RGB(0, 0, 0), B
            p$ = _Trim$(Str$(board(row, col)))
            If Len(p$) = 1 Then x1 = x1 + (size / 4)
            Text x1 + 2, y1 + 2, size, _RGB(0, 0, 0), p$
            Text x1, y1, size, _RGB(255, 255, 255), p$
        End If
    Next
Next
_Display

Return


Sub Text (x, y, textHeight, K As _Unsigned Long, txt$)
    'Text SUB by bplus.
    Dim fg As _Unsigned Long, cur&, I&, multi, xlen
    fg = _DefaultColor
    cur& = _Dest
    I& = _NewImage(8 * Len(txt$), 16, 32)
    _Dest I&
    Color K, _RGBA32(0, 0, 0, 0)
    _PrintString (0, 0), txt$
    multi = textHeight / 16
    xlen = Len(txt$) * 8 * multi
    _PutImage (x, y)-Step(xlen, textHeight), I&, cur&
    Color fg
    _FreeImage I&
End Sub

Find my programs here in Dav's QB64 Corner
Reply
#2
+1 One of my favorites! I have at least 3 versions
1. mini < 30 LOC (with double parking)
2. mouse
3. 3X3 to 9x9 or more?

even a AI solver

but I forgot all about that TEXT sub, sure enough there it is in my toolbox Smile

I or someone else maybe Petr or Steve used images instead of numbers.
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply
#3
Thanks. I’ve been using your Text Sub quite a bit lately. Works faster than the PPRINT SUB I made. 

I have a question about the _DEST use the your SUB.  I noticed that _DEST is changed in the Text SUB and not restored when the SUB ends with _DEST cur&, and doesn’t seem to to matter, DEST seems to go back to cur& anyway.  Does the PUTIMAGE do that for you when using the saved cur& value? 

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#4
cur& is just where-ever you happen to be when you call Text. Usually that would be screen 0 but you could be in another image making sub that you plan on evenetually _PutImage or Rotozoom to main screen.

In short, cur& = the current default destination at moment Text is called.

It is curious I didn't reset _Dest to cur& before leaving, maybe _FreeImage of I& resets _Dest back automatically because I& is gone! after _FreeImage I&
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply
#5
Yeah, that's it.  I made a little test.  Once the _DEST image is freed, the _DEST will reset to 0, not to whatever _DEST was before _DESTing to that image.  I guess _DEST cur& should be added before exiting the Text SUB.

- Dav

Code: (Select All)
Screen _NewImage(640, 480, 32)

num2& = _NewImage(640, 480, 32) 'a second screen
_Dest num2& 'dest to this just for a test

dotest 'call a sub (we are in _DEST num2&...)

Print "Hello" 'This will show in _DEST 0

Sub dotest

    test& = _NewImage(640, 480, 32) 'another screen
    _Dest test& 'point there
    Print "Test page."
    _FreeImage test& 'remove it, DEST will be removed

    '(_DEST will not go back to num&, but 0)

End Sub

Find my programs here in Dav's QB64 Corner
Reply
#6
OK I'm adding that to Text sub, thanks for test.
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  2048 Puzzle Dav 42 6,439 10-27-2024, 10:08 AM
Last Post: bplus
  Simple Sudoku puzzle (updated with 500 puzzles) Dav 7 2,118 06-12-2024, 05:43 PM
Last Post: Dav
  RocoLoco - Row & Column math puzzle game. Dav 3 1,327 06-07-2024, 12:11 PM
Last Post: Dav
  Find the ball - classic shell game Dav 2 995 06-01-2024, 05:37 PM
Last Post: bplus
  UnscramblePic.bas - Rotate picture pieces puzzle Dav 14 2,921 07-15-2023, 07:12 PM
Last Post: Steffan-68

Forum Jump:


Users browsing this thread: 1 Guest(s)