Smallish Games
#1
Smallish Games 100 - 300 LOC with at most a image or sound file.


Bowling
@johnno56 was very helpful with this way back when we were at SmallBASIC forum. I left a copy of that SmallBASIC code (the bas that starts with SB) for nostalgia. This one seems different than usual computer game.


Attached Files Image(s)
   

.zip   Bowling.zip (Size: 365.22 KB / Downloads: 55)
b = b + ...
Reply
#2
MasterMind 2022 update

I went though and refreshed the code in this game since Johnno was asking about it.

Code: (Select All)
Option _Explicit
_Title "MasterMind 2022" ' b+ 2022-06-11 make over b+ trans 2022-06-10
'Mastermind v7.bas 2016-02-27 [B+=MGA] for SmallBASIC 0.12.2
'
Randomize Timer
Const xmax = 800, ymax = 632, cx = xmax / 2, cy = ymax / 2
Const diam = ymax / 10 ' originally SB version was built around the bigger of xmax and ymax
Const radi = ymax / 20 ' and these dimensions all flowed from that
Const BullCowX = cx - 4 * diam - 60
Const FrameLX = BullCowX + 5 * 8 ' frame holds ball guess so Frame Left X
Const ControlPanelLX = cx + 8 ' cp = Control Panel? so Control Panel Left X
Const ControlPanelRX = cx + 2 * 8 + 2 * diam
Const black = _RGB32(0, 0, 0)
Const white = _RGB32(255, 255, 255)
Const gray = _RGB32(190, 190, 205)
Const boardC = _RGB32(150, 150, 165)
Const boardC2 = _RGB32(80, 80, 95)
Const deck$ = "RGBYOP" 'here are 6 color initials Red Green Blue Yellow Orange Purple
Dim Shared secret$, gues$(1 To 4), clr$ '  globals
Dim Shared As Long restartF, guesses, lc ' globals yes need both lc and guesses, I guess
Dim As Long i, quit, mx, my, mb '          locals

Screen _NewImage(xmax, ymax, 32)
_ScreenMove 200, 20

restart:
restartF = 0: lc = 0: guesses = 0
secret$ = "": For i = 1 To 4: secret$ = secret$ + Mid$(deck$, Int(Rnd * 6) + 1, 1): Next 'one line to make secret$
'_Title secret$ ' for debugging
Line (cx - ymax / 2, 0)-(cx + ymax / 2, ymax), boardC, BF
clr$ = "R" 'screen prep and initialization
drawcontrols
Color white, boardC
_PrintString (cx + 66, 20), "MasterMind: 4 Color Code"
_PrintString (cx + 10, 16 + 30), "B = Bull, Right Color and Right Spot"
_PrintString (cx + 10, 2 * 16 + 35), "C = Cow, Right Color and Wrong Spot"
Line (FrameLX - 4, 0)-(cx - 4, ymax), boardC2, BF
drawframe

quit = 0
While quit = 0 'the game begins
    While _MouseInput: Wend
    mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
    If mb Then
        If mx > ControlPanelLX And mx < ControlPanelRX And my > 1.5 * diam And my < 9 * diam Then 'click in control panel
            If my < 2.5 * diam Then 'guess button clicked
                handleGuess
                If restartF Then GoTo restart
            ElseIf my < 4 * diam Then 'clicked a color update in control panel or quit
                clr$ = "R": updatecolor
            ElseIf my < 5 * diam Then
                clr$ = "G": updatecolor
            ElseIf my < 6 * diam Then
                clr$ = "B": updatecolor
            ElseIf my < 7 * diam Then
                clr$ = "Y": updatecolor
            ElseIf my < 8 * diam Then
                clr$ = "O": updatecolor
            ElseIf my < 9 * diam Then
                clr$ = "P": updatecolor
            End If 'mouse in control box
        ElseIf mx > FrameLX And mx < FrameLX + 4 * diam And my > lc * diam And my < lc * diam + diam Then 'mouse click in the guess boxes
            If mx < FrameLX + diam Then
                gues$(1) = clr$
                ball FrameLX + radi, lc * diam + radi, clr$
            ElseIf mx < FrameLX + 2 * diam Then
                gues$(2) = clr$
                ball FrameLX + 1.5 * diam, lc * diam + radi, clr$
            ElseIf mx < FrameLX + 3 * diam Then
                gues$(3) = clr$
                ball FrameLX + 2.5 * diam, lc * diam + radi, clr$
            ElseIf mx < FrameLX + 4 * diam Then
                gues$(4) = clr$
                ball FrameLX + 3.5 * diam, lc * diam + radi, clr$
            End If 'mouse in guess frame
        End If ' mouse positions on click
    End If 'mousebutton
    checkguess
    _Limit 100
Wend

Sub handleGuess ()
    Dim guess$, s$, tx, ty
    Dim As Long OK, i
    OK = 1: guess$ = ""
    For i = 1 To 4
        If gues$(i) = "" Then
            OK = 0
        Else
            guess$ = guess$ + gues$(i)
        End If
    Next
    If OK Then
        Color black, boardC
        guesses = guesses + 1
        _PrintString (BullCowX, lc * diam + radi - .5 * 16), countingCattle$(secret$, guess$)
        If guess$ = secret$ Or guesses = 10 Then
            Line (ControlPanelLX, 1.5 * diam)-(ControlPanelRX, 2.5 * diam), boardC, BF 'erase button
            Color black, boardC
            If guess$ = secret$ Then
                s$ = "You won after" + Str$(guesses) + " guesses!"
                tx = ControlPanelLX + 60
                ty = 2 * diam - 8
            End If
            If guesses = 10 Then
                s$ = "The code was: " + secret$
                tx = ControlPanelLX + 76
                ty = 2 * diam - 8
            End If
            _PrintString (tx, ty), s$
            s$ = "zzz... press any"
            tx = ControlPanelLX + 85
            ty = 2 * diam + 16
            _PrintString (tx, ty), s$
            Sleep
            Color white, black: Cls: restartF = -1
        End If
        lc = lc + 1 ' do I need lc if guesses is keeping count too? yeah it's too confusing taking it out
        drawframe
        For i = 1 To 4: gues$(i) = "": Next
    End If 'guess$ OK ends handling guess$
End Sub

Sub checkguess
    Dim As Long OK, i
    Dim s$, tx, ty
    OK = 1
    For i = 1 To 4
        If gues$(i) = "" Then OK = 0
    Next
    If OK = 1 Then
        Line (ControlPanelLX, 1.5 * diam)-(ControlPanelRX, 2.5 * diam), white, BF
        Line (ControlPanelLX + 1, 1.5 * diam + 1)-(ControlPanelRX, 2.5 * diam), gray, BF 'guess box
        Color black, gray
        s$ = "Guess"
        tx = ControlPanelLX + (ControlPanelRX - ControlPanelLX) / 2 - 8 * (Len(s$)) / 2
        ty = 2 * diam - 8
        _PrintString (tx, ty), s$
    Else
        Line (ControlPanelLX, 1.5 * diam)-(ControlPanelRX, 2.5 * diam), boardC, BF
    End If
End Sub

Sub drawframe ()
    Dim sc, i, rr, cc
    sc = 64 / (radi - 5)
    For i = 0 To 3
        For rr = radi - 5 To 0 Step -1
            cc = rr * sc
            fcirc FrameLX + diam * i + radi, lc * diam + radi, rr, _RGB32(cc, cc, cc + 15)
        Next
    Next
End Sub

Sub drawcontrols
    Dim As Long cplr
    cplr = ControlPanelLX + radi
    ball cplr, 3.5 * diam, "R"
    ball cplr, 4.5 * diam, "G"
    ball cplr, 5.5 * diam, "B"
    ball cplr, 6.5 * diam, "Y"
    ball cplr, 7.5 * diam, "O"
    ball cplr, 8.5 * diam, "P"
    updatecolor
End Sub

Sub updatecolor ()
    Dim As Long ymult
    Line (ControlPanelLX + diam + 8, 3 * diam)-(cx + ymax / 2, 9 * diam), boardC, BF
    ymult = InStr(deck$, clr$)
    Color black, boardC
    _PrintString (ControlPanelLX + diam + 8, (ymult + 2) * diam + radi - .5 * 16), "< = Selected Color"
End Sub

Function countingCattle$ (secrt$, guss$) ' 2022 reworked and fixed
    Dim build$, copyS$, copyG$
    Dim As Long bulls, cows, i, j
    copyS$ = secrt$: copyG$ = guss$ ' don't mess with originals
    For i = 1 To 4 ' remove matching letters from both by changing the letters
        If Mid$(copyS$, i, 1) = Mid$(copyG$, i, 1) Then bulls = bulls + 1: Mid$(copyS$, i, 1) = " ": Mid$(copyG$, i, 1) = "_"
    Next
    For i = 1 To 4 ' go through letters of guess
        For j = 1 To 4 'every match with secret is removed from copy of secret and of guess
            If Mid$(copyS$, j, 1) = Mid$(copyG$, i, 1) Then
                cows = cows + 1: Mid$(copyS$, j, 1) = " ": Mid$(copyG$, i, 1) = "_"
                Exit For
            End If
        Next
    Next
    build$ = String$(bulls, "B") + String$(cows, "C")
    If build$ = "" Then build$ = "X"
    countingCattle$ = build$
End Function

Sub ball (x, y, c$)
    Dim sc, start, r
    sc = 32 / radi: start = Int(32 / sc) - 2
    For r = start To 0 Step -1
        If c$ = "R" Then
            fcirc x, y, r, _RGB32(255 - 6 * r * sc, 0, 0)
        ElseIf c$ = "B" Then
            fcirc x, y, r, _RGB32(0, 0, 255 - 6 * r * sc)
        ElseIf c$ = "G" Then
            fcirc x, y, r, _RGB32(0, 220 - 6 * r * sc, 0)
        ElseIf c$ = "O" Then
            fcirc x, y, r, _RGB32(255 - 3 * r * sc, 150 - 3 * r * sc, 0)
        ElseIf c$ = "Y" Then
            fcirc x, y, r, _RGB32(255 - 4 * r * sc, 255 - 4 * r * sc, 0)
        ElseIf c$ = "P" Then
            fcirc x, y, r, _RGB32(255 - 7 * r * sc, 0, 130 - 2 * r * sc)
        End If
    Next
End Sub

Sub fcirc (CX As Long, CY As Long, R As Long, C As _Unsigned Long)
    Dim Radius As Long, RadiusError As Long
    Dim X As Long, Y As Long
    Radius = Abs(R): RadiusError = -Radius: X = Radius: Y = 0
    If Radius = 0 Then PSet (CX, CY), C: Exit Sub
    Line (CX - X, CY)-(CX + X, CY), C, BF
    While X > Y
        RadiusError = RadiusError + Y * 2 + 1
        If RadiusError >= 0 Then
            If X <> Y + 1 Then
                Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
                Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
            End If
            X = X - 1
            RadiusError = RadiusError - X * 2
        End If
        Y = Y + 1
        Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
        Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    Wend
End Sub


   
b = b + ...
Reply
#3
Cannot beat the classics... Well, you can... by winning... But you knew what I meant, right? lol
May your journey be free of incident. Live long and prosper.
Reply
#4
Nonogram Trainer

Inspired and made aware of Nonograms by RokCoder here:
https://staging.qb64phoenix.com/showthre...7#pid12467

I made a Nonogram Trainer here to get up to speed on solving these kinds of puzzles. You can start with trivial 1x1 and work your way up to 9x9 puzzles. Then you might be ready for RokCoder's puzzle with the works!

Instructions: after choosing the number of cells per side you want to try, you will be presented a grid with number along each row and col. Those numbers represent a run of white squares in that row or col. By clicking the cells on or off, your goal is to match those runs in rows and cols.

Code: (Select All)
_Title "Nonogram Trainer" ' b+ 2023-01-12
DefLng A-Z
Randomize Timer
Dim Shared As _Unsigned Long White, Black, Blue
White = &HFFFFFFFF: Black = &HFF000000: Blue = &HFF0000FF
ReDim Shared Sq, Game(1 To 1, 1 To 1), Board(1 To 1, 1 To 1), RowRuns$(1 To 1), ColRuns$(1 To 1)
Screen _NewImage(800, 600, 32)
makeGame
Do
    10 If _MouseInput Then GoTo 10
    mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
    If mb Then
        _Delay .2
        If mx > 20 And mx <= Sq * 20 + 40 Then
            If my > 20 And my <= Sq * 20 + 40 Then
                x = Int(mx / 20): y = Int(my / 20)
                If Board(x, y) Then Board(x, y) = 0 Else Board(x, y) = 1
                If Board(x, y) Then Color White Else Color Black
                Line (x * 20, y * 20)-Step(20, 20), , BF
                Line (x * 20, y * 20)-Step(20, 20), Blue, B
            End If
        End If
    End If
    If Solved Then _MessageBox "Solved", "Hurray you've solved the puzzle!": makeGame
    _Limit 60
Loop Until _KeyDown(27)

Sub makeGame
    Cls
    inputAgain:
    Input "How many cells per square side (1 to 9) "; test
    If test < 1 Or test > 9 Then GoTo inputAgain Else Cls: Sq = test
    ReDim Game(1 To Sq, 1 To Sq), Board(1 To Sq, 1 To Sq), RowRuns$(1 To Sq), ColRuns$(1 To Sq)
    Line (18, 18)-(Sq * 20 + 22, Sq * 20 + 22), White, B
    For y = 1 To Sq
        For x = 1 To Sq
            If Rnd < .5 Then Game(x, y) = 0 Else Game(x, y) = 1
            Line (x * 20, y * 20)-Step(20, 20), Blue, B
        Next
    Next
    Color White
    For i = 1 To Sq
        RowRuns$(i) = Runs$(1, i, Game())
        _PrintString (Sq * 20 + 30, i * 20 + 4), RowRuns$(i)
        ColRuns$(i) = Runs$(0, i, Game())
    Next
    For i = 1 To Sq
        row = Sq + 1: lastp = 1: start = 1
        p = InStr(ColRuns$(i), " ")
        While p
            _PrintString (i * 20 + 6, row * 20 + 10), Mid$(ColRuns$(i), start, 1)
            start = start + 2: row = row + 1
            p = InStr(start, ColRuns$(i), " ")
        Wend
        _PrintString (i * 20 + 6, row * 20 + 10), Mid$(ColRuns$(i), start)
    Next
End Sub

Function Runs$ (rowTF, number, arr())
    If rowTF Then
        If arr(1, number) Then flag = 1
        For i = 2 To Sq
            If arr(i, number) Then
                If flag Then flag = flag + 1 Else flag = 1
            Else
                If flag Then
                    If Len(b$) Then b$ = b$ + " " + _Trim$(Str$(flag)) Else b$ = _Trim$(Str$(flag))
                    flag = 0
                End If
            End If
        Next
        If flag Then
            If Len(b$) Then b$ = b$ + " " + _Trim$(Str$(flag)) Else b$ = _Trim$(Str$(flag))
        End If
    Else
        If arr(number, 1) Then flag = 1
        For i = 2 To Sq
            If arr(number, i) Then
                If flag Then flag = flag + 1 Else flag = 1
            Else
                If flag Then
                    If Len(b$) Then b$ = b$ + " " + _Trim$(Str$(flag)) Else b$ = _Trim$(Str$(flag))
                    flag = 0
                End If
            End If
        Next
        If flag Then
            If Len(b$) Then b$ = b$ + " " + _Trim$(Str$(flag)) Else b$ = _Trim$(Str$(flag))
        End If
    End If
    Runs$ = b$
End Function

Function Solved
    For i = 1 To Sq
        If RowRuns$(i) <> Runs$(1, i, Board()) Then Exit Function 'not done
        If ColRuns$(i) <> Runs$(0, i, Board()) Then Exit Function
    Next
    Solved = -1
End Function

   

Thanks for sharing your Nonogram app RokCoder.
b = b + ...
Reply
#5
Mastermind is a great game, and this is a very nice implementation of it.
I love logic puzzles (as long as they're reasonably solvable).
"Best Scores" are not appropriate, but maybe some sort of acknowledgement of solving it would be Nice?
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#6
Down to 79 Loc

Instructions: after choosing the number of cells per side you want to try, you will be presented a grid with number along each row and col. Those numbers represent a run of white squares in that row or col. By clicking the cells on or off, your goal is to match those runs in rows and cols.

Code: (Select All)
_Title "Nonogram Trainer" ' b+ 2023-01-12
DefLng A-Z
Randomize Timer
Dim Shared As _Unsigned Long White, Black, Blue
White = &HFFFFFFFF: Black = &HFF000000: Blue = &HFF0000FF
ReDim Shared Sq, Game(1 To 1, 1 To 1), Board(1 To 1, 1 To 1), RowRuns$(1 To 1), ColRuns$(1 To 1)
Screen _NewImage(800, 600, 32)
makeGame
Do
    10 If _MouseInput Then GoTo 10
    mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
    If mb Then
        _Delay .2
        If mx > 20 And mx <= Sq * 20 + 40 Then
            If my > 20 And my <= Sq * 20 + 40 Then
                x = Int(mx / 20): y = Int(my / 20)
                If Board(x, y) Then Board(x, y) = 0 Else Board(x, y) = 1
                If Board(x, y) Then Color White Else Color Black
                Line (x * 20, y * 20)-Step(20, 20), , BF
                Line (x * 20, y * 20)-Step(20, 20), Blue, B
            End If
        End If
    End If
    If Solved Then _MessageBox "Solved", "Hurray you've solved the puzzle!": makeGame
    _Limit 60
Loop Until _KeyDown(27)

Sub makeGame
    Cls
    inputAgain:
    Input "How many cells per square side (1 to 9) "; test
    If test < 1 Or test > 9 Then GoTo inputAgain Else Cls: Sq = test
    ReDim Game(1 To Sq, 1 To Sq), Board(1 To Sq, 1 To Sq), RowRuns$(1 To Sq), ColRuns$(1 To Sq)
    Line (18, 18)-(Sq * 20 + 22, Sq * 20 + 22), White, B
    For y = 1 To Sq
        For x = 1 To Sq
            If Rnd < .5 Then Game(x, y) = 0 Else Game(x, y) = 1
            Line (x * 20, y * 20)-Step(20, 20), Blue, B
        Next
    Next
    Color White
    For i = 1 To Sq
        RowRuns$(i) = Runs$(1, i, Game())
        _PrintString (Sq * 20 + 30, i * 20 + 4), RowRuns$(i)
        ColRuns$(i) = Runs$(0, i, Game())
    Next
    For i = 1 To Sq
        row = Sq
        For j = 1 To Len(ColRuns$(i)) Step 2
            row = row + 1
            _PrintString (i * 20 + 6, row * 20 + 10), Mid$(ColRuns$(i), j, 1)
        Next
    Next
End Sub

Function Runs$ (rowTF, number, arr())
    For i = 1 To Sq
        If (arr(i, number) And rowTF) Or (arr(number, i) And rowTF = 0) Then
            If flag Then flag = flag + 1 Else flag = 1
        Else
            If flag Then
                If Len(b$) Then b$ = b$ + " " + _Trim$(Str$(flag)) Else b$ = _Trim$(Str$(flag))
                flag = 0
            End If
        End If
    Next
    If flag Then
        If Len(b$) Then b$ = b$ + " " + _Trim$(Str$(flag)) Else b$ = _Trim$(Str$(flag))
    End If
    Runs$ = b$
End Function

Function Solved
    For i = 1 To Sq
        If RowRuns$(i) <> Runs$(1, i, Board()) Then Exit Function 'not done
        If ColRuns$(i) <> Runs$(0, i, Board()) Then Exit Function
    Next
    Solved = -1
End Function

Best solve yet!
   
b = b + ...
Reply
#7
TriQuad Puzzle from long ago, still like playing once and awhile.
Code: (Select All)
Option _Explicit
_Title "TriQuad Puzzle" 'B+ start 2019-07-17 trans to QB64 from:
' TriQuad.bas  SmallBASIC 0.12.8 [B+=MGA] 2017-03-26
' inspired by rick3137's recent post at Naalaa of cute puzzle
' 2019-07 Complete remake for N X N puzzles, not just 3 X 3's.
' post at QB64 forum 2019-10-14

Randomize Timer

Const xmax = 1000, margin = 50 'screen size, margin that should allow a line above and below the puzzle display
Const topLeftB1X = margin, topLeftB2X = xmax / 2 + .5 * margin, topY = margin

'these have to be decided from user input from Intro screen
Dim Shared ymax, N, Nm1, NxNm1, sq, sq2, sq4
ymax = 500 'for starters in intro screen have resizing in pixels including ymax

ReDim Shared B1(2, 2), B2(2, 2) ' B1() box container for scrambled pieces of C(), B2 box container to build solution
ReDim Shared C(8, 3) '9 squares 4 colored triangles, C() contains the solution as created by code, may not be the only one!

Dim mx, my, mb, bx, by, holdF, ky As String, again As String

Screen _NewImage(xmax, ymax, 32)
_ScreenMove 300, 40
intro
restart:
assignColors
holdF = N * N
While 1
    Cls
    showB (1)
    showB (2)
    While _MouseInput: Wend
    mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
    If mb Then
        Do While mb
            While _MouseInput: Wend
            mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
        Loop
        If topY <= my And my <= topY + N * sq Then
            by = Int((my - topY) / sq)
            If topLeftB1X <= mx And mx <= topLeftB1X + N * sq Then 'mx in b1
                bx = Int((mx - topLeftB1X) / sq)
                If holdF < N * N Then 'trying to put the piece on hold here?
                    If B1(bx, by) = N * N Then
                        B1(bx, by) = holdF: holdF = N * N
                    End If
                ElseIf holdF = N * N Then
                    If B1(bx, by) < N * N Then
                        holdF = B1(bx, by): B1(bx, by) = N * N
                    End If
                End If
            ElseIf topLeftB2X <= mx And mx <= topLeftB2X + N * sq Then 'mx in b2
                bx = Int((mx - topLeftB2X) / sq)
                If holdF < N * N Then
                    If B2(bx, by) = N * N Then
                        B2(bx, by) = holdF: holdF = N * N
                    End If
                ElseIf holdF = N * N Then
                    If B2(bx, by) < N * N Then
                        holdF = B2(bx, by): B2(bx, by) = N * N
                    End If
                End If 'my out of range
            End If
        End If
    End If
    If solved Then
        Color hue(9)
        Locate 2, 1: centerPrint "Congratulations puzzle solved!"
        _Display
        _Delay 3
        Exit While
    End If
    ky = InKey$
    If Len(ky) Then
        If ky = "q" Then
            showSolution
            Color hue(9)
            Locate 2, 1: centerPrint "Here is solution (for 10 secs), Goodbye!"
            _Display
            _Delay 10
            System
        End If
    End If
    _Display
    _Limit 100
Wend
Color hue(9): Locate 2, 1: centerPrint Space$(50): Locate 2, 1
centerPrint "Press enter to play again, any + enter ends... "
_Display
again = InKey$
While Len(again) = 0: again = InKey$: _Limit 200: Wend
If Asc(again) = 13 Then GoTo restart Else System

Function solved
    'since it is possible that a different tile combination could be a valid solution we have to check points
    Dim x, y
    'first check that there is a puzzle piece in every slot of b2
    For y = 0 To Nm1
        For x = 0 To Nm1
            If B2(x, y) = N * N Then Exit Function
        Next
    Next
    'check left and right triangle matches in b2
    For y = 0 To Nm1
        For x = 0 To Nm1 - 1
            If Point(topLeftB2X + x * sq + sq2 + sq4, topY + y * sq + sq2) <> Point(topLeftB2X + (x + 1) * sq + sq4, topY + y * sq + sq2) Then Exit Function
        Next
    Next
    'check to and bottom triangle matches in b2
    For y = 0 To Nm1 - 1
        For x = 0 To Nm1
            'the color of tri4 in piece below = color tri1 of piece above
            If Point(topLeftB2X + x * sq + sq2, topY + y * sq + sq2 + sq4) <> Point(topLeftB2X + x * sq + sq2, topY + (y + 1) * sq + sq4) Then Exit Function
        Next
    Next
    'if made it this far then solved
    solved = -1
End Function

Sub showSolution
    Dim x, y, index
    For y = 0 To Nm1
        For x = 0 To Nm1
            drawSquare index, x * sq + topLeftB2X, y * sq + topY
            index = index + 1
        Next
    Next
End Sub

Sub showB (board)
    Dim x, y, index
    For y = 0 To Nm1
        For x = 0 To Nm1
            If board = 1 Then
                index = B1(x, y)
                drawSquare index, x * sq + topLeftB1X, y * sq + topY
            Else
                index = B2(x, y)
                drawSquare index, x * sq + topLeftB2X, y * sq + topY
            End If
        Next
    Next
End Sub

Sub drawSquare (index, x, y)
    Line (x, y)-Step(sq, sq), &HFF000000, BF
    Line (x, y)-Step(sq, sq), &HFFFFFFFF, B
    If index < N * N Then
        Line (x, y)-Step(sq, sq), &HFFFFFFFF
        Line (x + sq, y)-Step(-sq, sq), &HFFFFFFFF
        Paint (x + sq2 + sq4, y + sq2), hue(C(index, 0)), &HFFFFFFFF
        Paint (x + sq2, y + sq2 + sq4), hue(C(index, 1)), &HFFFFFFFF
        Paint (x + sq4, y + sq2), hue(C(index, 2)), &HFFFFFFFF
        Paint (x + sq2, y + sq4), hue(C(index, 3)), &HFFFFFFFF
    End If
End Sub

Sub assignColors ()
    'the pieces are indexed 0 to N X N -1  (NxNm1)
    ' y(index) = int(index/N) : x(index) = index mod N
    ' index(x, y) = (y - 1) * N + x

    Dim i, j, x, y
    'first assign a random color rc to every triangle
    For i = 0 To NxNm1 'piece index
        For j = 0 To 3 'tri color index for piece
            C(i, j) = rand(1, 9)
        Next
    Next
    'next match c0 to c3 of square to right
    For y = 0 To Nm1
        For x = 0 To Nm1 - 1
            'the color of tri3 of next square piece to right = color of tri0 to left of it
            C(y * N + x + 1, 2) = C(y * N + x, 0)
        Next
    Next
    For y = 0 To Nm1 - 1
        For x = 0 To Nm1
            'the color of tri4 in piece below = color tri1 of piece above
            C((y + 1) * N + x, 3) = C(y * N + x, 1)
        Next
    Next

    ' C() now contains one solution for puzzle, may not be the only one

    ' scramble pieces to box1
    Dim t(0 To NxNm1), index 'temp array
    For i = 0 To NxNm1: t(i) = i: Next
    For i = NxNm1 To 1 Step -1: Swap t(i), t(rand(0, i)): Next
    For y = 0 To Nm1
        For x = 0 To Nm1
            B1(x, y) = t(index)
            index = index + 1
            B2(x, y) = N * N
            'PRINT B1(x, y), B2(x, y)
        Next
    Next
End Sub

Function hue~& (cn)
    Select Case cn
        Case 0: hue~& = &HFF000000
        Case 1: hue~& = &HFFA80062
        Case 2: hue~& = &HFF000050
        Case 3: hue~& = &HFFE3333C
        Case 4: hue~& = &HFFFF0000
        Case 5: hue~& = &HFF008000
        Case 6: hue~& = &HFF0000FF
        Case 7: hue~& = &HFFFF64FF
        Case 8: hue~& = &HFFFFFF00
        Case 9: hue~& = &HFF00EEEE
        Case 10: hue~& = &HFF663311
    End Select
End Function

Function rand% (n1, n2)
    Dim hi, lo
    If n1 > n2 Then hi = n1: lo = n2 Else hi = n2: lo = n1
    rand% = (Rnd * (hi - lo + 1)) \ 1 + lo
End Function

Sub intro 'use intro to select number of pieces
    Dim test As Integer
    Cls: Color hue(8): Locate 3, 1
    centerPrint "TriQuad Instructions:": Print: Color hue(9)
    centerPrint "This puzzle has two boxes that contain up to N x N square pieces of 4 colored triangles."
    centerPrint "The object is to match up the triangle edges from left Box to fill the Box on the right.": Print
    centerPrint "You may move any square piece to an empty space on either board by:"
    centerPrint "1st clicking the piece to disappear it,"
    centerPrint "then clicking any empty space for it to reappear.": Print
    centerPrint "You may press q to quit and see the solution displayed.": Print
    centerPrint "Hint: the colors without matching"
    centerPrint "complement, are edge pieces.": Print
    centerPrint "Good luck!": Color hue(5)
    Locate CsrLin + 2, 1: centerPrint "Press number key for square pieces per side (3 to 9, 1 to quit)..."
    While test < 3 Or test > 9
        test = Val(InKey$)
        If test = 1 Then System
    Wend
    N = test ' pieces per side of 2 boards
    Nm1 = N - 1 ' FOR loops
    NxNm1 = N * N - 1 ' FOR loop of piece index
    'sizing
    sq = (xmax / 2 - 1.5 * margin) / N 'square piece side size
    sq2 = sq / 2: sq4 = sq / 4
    ymax = sq * N + 2 * margin
    ReDim B1(Nm1, Nm1), B2(Nm1, Nm1), C(NxNm1, 3)
    Screen _NewImage(xmax, ymax, 32)
    '_SCREENMOVE 300, 40    'need again?
    'PRINT ymax
End Sub

Sub centerPrint (s$)
    Locate CsrLin, (xmax / 8 - Len(s$)) / 2: Print s$
End Sub

   

   
b = b + ...
Reply
#8
(03-01-2023, 05:19 AM)bplus Wrote: TriQuad Puzzle from long ago, still like playing one and a while.
Code: (Select All)
Option _Explicit
_Title "TriQuad Puzzle" 'B+ start 2019-07-17 trans to QB64 from:
' TriQuad.bas  SmallBASIC 0.12.8 [B+=MGA] 2017-03-26
' inspired by rick3137's recent post at Naalaa of cute puzzle
' 2019-07 Complete remake for N X N puzzles, not just 3 X 3's.
' post at QB64 forum 2019-10-14

Randomize Timer

Const xmax = 1000, margin = 50 'screen size, margin that should allow a line above and below the puzzle display
Const topLeftB1X = margin, topLeftB2X = xmax / 2 + .5 * margin, topY = margin

'these have to be decided from user input from Intro screen
Dim Shared ymax, N, Nm1, NxNm1, sq, sq2, sq4
ymax = 500 'for starters in intro screen have resizing in pixels including ymax

ReDim Shared B1(2, 2), B2(2, 2) ' B1() box container for scrambled pieces of C(), B2 box container to build solution
ReDim Shared C(8, 3) '9 squares 4 colored triangles, C() contains the solution as created by code, may not be the only one!

Dim mx, my, mb, bx, by, holdF, ky As String, again As String

Screen _NewImage(xmax, ymax, 32)
_ScreenMove 300, 40
intro
restart:
assignColors
holdF = N * N
While 1
    Cls
    showB (1)
    showB (2)
    While _MouseInput: Wend
    mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
    If mb Then
        Do While mb
            While _MouseInput: Wend
            mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
        Loop
        If topY <= my And my <= topY + N * sq Then
            by = Int((my - topY) / sq)
            If topLeftB1X <= mx And mx <= topLeftB1X + N * sq Then 'mx in b1
                bx = Int((mx - topLeftB1X) / sq)
                If holdF < N * N Then 'trying to put the piece on hold here?
                    If B1(bx, by) = N * N Then
                        B1(bx, by) = holdF: holdF = N * N
                    End If
                ElseIf holdF = N * N Then
                    If B1(bx, by) < N * N Then
                        holdF = B1(bx, by): B1(bx, by) = N * N
                    End If
                End If
            ElseIf topLeftB2X <= mx And mx <= topLeftB2X + N * sq Then 'mx in b2
                bx = Int((mx - topLeftB2X) / sq)
                If holdF < N * N Then
                    If B2(bx, by) = N * N Then
                        B2(bx, by) = holdF: holdF = N * N
                    End If
                ElseIf holdF = N * N Then
                    If B2(bx, by) < N * N Then
                        holdF = B2(bx, by): B2(bx, by) = N * N
                    End If
                End If 'my out of range
            End If
        End If
    End If
    If solved Then
        Color hue(9)
        Locate 2, 1: centerPrint "Congratulations puzzle solved!"
        _Display
        _Delay 3
        Exit While
    End If
    ky = InKey$
    If Len(ky) Then
        If ky = "q" Then
            showSolution
            Color hue(9)
            Locate 2, 1: centerPrint "Here is solution (for 10 secs), Goodbye!"
            _Display
            _Delay 10
            System
        End If
    End If
    _Display
    _Limit 100
Wend
Color hue(9): Locate 2, 1: centerPrint Space$(50): Locate 2, 1
centerPrint "Press enter to play again, any + enter ends... "
_Display
again = InKey$
While Len(again) = 0: again = InKey$: _Limit 200: Wend
If Asc(again) = 13 Then GoTo restart Else System

Function solved
    'since it is possible that a different tile combination could be a valid solution we have to check points
    Dim x, y
    'first check that there is a puzzle piece in every slot of b2
    For y = 0 To Nm1
        For x = 0 To Nm1
            If B2(x, y) = N * N Then Exit Function
        Next
    Next
    'check left and right triangle matches in b2
    For y = 0 To Nm1
        For x = 0 To Nm1 - 1
            If Point(topLeftB2X + x * sq + sq2 + sq4, topY + y * sq + sq2) <> Point(topLeftB2X + (x + 1) * sq + sq4, topY + y * sq + sq2) Then Exit Function
        Next
    Next
    'check to and bottom triangle matches in b2
    For y = 0 To Nm1 - 1
        For x = 0 To Nm1
            'the color of tri4 in piece below = color tri1 of piece above
            If Point(topLeftB2X + x * sq + sq2, topY + y * sq + sq2 + sq4) <> Point(topLeftB2X + x * sq + sq2, topY + (y + 1) * sq + sq4) Then Exit Function
        Next
    Next
    'if made it this far then solved
    solved = -1
End Function

Sub showSolution
    Dim x, y, index
    For y = 0 To Nm1
        For x = 0 To Nm1
            drawSquare index, x * sq + topLeftB2X, y * sq + topY
            index = index + 1
        Next
    Next
End Sub

Sub showB (board)
    Dim x, y, index
    For y = 0 To Nm1
        For x = 0 To Nm1
            If board = 1 Then
                index = B1(x, y)
                drawSquare index, x * sq + topLeftB1X, y * sq + topY
            Else
                index = B2(x, y)
                drawSquare index, x * sq + topLeftB2X, y * sq + topY
            End If
        Next
    Next
End Sub

Sub drawSquare (index, x, y)
    Line (x, y)-Step(sq, sq), &HFF000000, BF
    Line (x, y)-Step(sq, sq), &HFFFFFFFF, B
    If index < N * N Then
        Line (x, y)-Step(sq, sq), &HFFFFFFFF
        Line (x + sq, y)-Step(-sq, sq), &HFFFFFFFF
        Paint (x + sq2 + sq4, y + sq2), hue(C(index, 0)), &HFFFFFFFF
        Paint (x + sq2, y + sq2 + sq4), hue(C(index, 1)), &HFFFFFFFF
        Paint (x + sq4, y + sq2), hue(C(index, 2)), &HFFFFFFFF
        Paint (x + sq2, y + sq4), hue(C(index, 3)), &HFFFFFFFF
    End If
End Sub

Sub assignColors ()
    'the pieces are indexed 0 to N X N -1  (NxNm1)
    ' y(index) = int(index/N) : x(index) = index mod N
    ' index(x, y) = (y - 1) * N + x

    Dim i, j, x, y
    'first assign a random color rc to every triangle
    For i = 0 To NxNm1 'piece index
        For j = 0 To 3 'tri color index for piece
            C(i, j) = rand(1, 9)
        Next
    Next
    'next match c0 to c3 of square to right
    For y = 0 To Nm1
        For x = 0 To Nm1 - 1
            'the color of tri3 of next square piece to right = color of tri0 to left of it
            C(y * N + x + 1, 2) = C(y * N + x, 0)
        Next
    Next
    For y = 0 To Nm1 - 1
        For x = 0 To Nm1
            'the color of tri4 in piece below = color tri1 of piece above
            C((y + 1) * N + x, 3) = C(y * N + x, 1)
        Next
    Next

    ' C() now contains one solution for puzzle, may not be the only one

    ' scramble pieces to box1
    Dim t(0 To NxNm1), index 'temp array
    For i = 0 To NxNm1: t(i) = i: Next
    For i = NxNm1 To 1 Step -1: Swap t(i), t(rand(0, i)): Next
    For y = 0 To Nm1
        For x = 0 To Nm1
            B1(x, y) = t(index)
            index = index + 1
            B2(x, y) = N * N
            'PRINT B1(x, y), B2(x, y)
        Next
    Next
End Sub

Function hue~& (cn)
    Select Case cn
        Case 0: hue~& = &HFF000000
        Case 1: hue~& = &HFFA80062
        Case 2: hue~& = &HFF000050
        Case 3: hue~& = &HFFE3333C
        Case 4: hue~& = &HFFFF0000
        Case 5: hue~& = &HFF008000
        Case 6: hue~& = &HFF0000FF
        Case 7: hue~& = &HFFFF64FF
        Case 8: hue~& = &HFFFFFF00
        Case 9: hue~& = &HFF00EEEE
        Case 10: hue~& = &HFF663311
    End Select
End Function

Function rand% (n1, n2)
    Dim hi, lo
    If n1 > n2 Then hi = n1: lo = n2 Else hi = n2: lo = n1
    rand% = (Rnd * (hi - lo + 1)) \ 1 + lo
End Function

Sub intro 'use intro to select number of pieces
    Dim test As Integer
    Cls: Color hue(8): Locate 3, 1
    centerPrint "TriQuad Instructions:": Print: Color hue(9)
    centerPrint "This puzzle has two boxes that contain up to N x N square pieces of 4 colored triangles."
    centerPrint "The object is to match up the triangle edges from left Box to fill the Box on the right.": Print
    centerPrint "You may move any square piece to an empty space on either board by:"
    centerPrint "1st clicking the piece to disappear it,"
    centerPrint "then clicking any empty space for it to reappear.": Print
    centerPrint "You may press q to quit and see the solution displayed.": Print
    centerPrint "Hint: the colors without matching"
    centerPrint "complement, are edge pieces.": Print
    centerPrint "Good luck!": Color hue(5)
    Locate CsrLin + 2, 1: centerPrint "Press number key for square pieces per side (3 to 9, 1 to quit)..."
    While test < 3 Or test > 9
        test = Val(InKey$)
        If test = 1 Then System
    Wend
    N = test ' pieces per side of 2 boards
    Nm1 = N - 1 ' FOR loops
    NxNm1 = N * N - 1 ' FOR loop of piece index
    'sizing
    sq = (xmax / 2 - 1.5 * margin) / N 'square piece side size
    sq2 = sq / 2: sq4 = sq / 4
    ymax = sq * N + 2 * margin
    ReDim B1(Nm1, Nm1), B2(Nm1, Nm1), C(NxNm1, 3)
    Screen _NewImage(xmax, ymax, 32)
    '_SCREENMOVE 300, 40    'need again?
    'PRINT ymax
End Sub

Sub centerPrint (s$)
    Locate CsrLin, (xmax / 8 - Len(s$)) / 2: Print s$
End Sub

Nice one (again!)
I haven't mastered it yet, but hope to soon - I solved it once already (with 3x3) Rolleyes
I experimented with adding a "tries" counter, but it's a bit hard to check if it works when I can't even solve it!  Sad
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#9
Hi @PhilOfPerth,

The trick is to find the edges that don't have a matching opposite color, those go along the edges.

If you don't find a couple of those a 4X4 is pretty hard, for me anyway.
b = b + ...
Reply
#10
Again Charlie's post causes me to dig into my files Smile

4x4 Sliding Blocks Puzzle: use arrow keys to move the block to fill the hole ie right arrow to slide the block left of hole, up arrow to move block below hole... actually we just have numbers here not tiles.

No fancy graphics in this 34 LOC game:
Code: (Select All)
_Title "Sliding Blocks MOD 4x4 Galileo" 'rev 2019-04-20
Randomize Timer
Dim Shared delta(4)
delta(1) = 4: delta(2) = 1: delta(3) = -1: delta(4) = -4
Dim Shared board$, hole
board$ = "123456789ABCDEF0": solve$ = board$: hole = 16
For i = 1 To 200: move Int(Rnd * 4 + 1): Next
Do
    print_board
    If board$ = solve$ Then Locate 8, 4: Print "solved!": Exit Do
    KH& = _KeyHit
    Select Case KH&
        Case 18432: move 1 'up
        Case 20480: move 4 'down
        Case 19200: move 2 'left
        Case 19712: move 3 'right
    End Select
    _Display
    _Limit 30
Loop
Sub print_board ()
    Cls: Locate 2, 1: Print " ";
    For i = 1 To Len(board$)
        If i = hole Then Print "    "; Else n$ = Right$("  " + Str$(Val("&H" + Mid$(board$, i, 1))) + " ", 4): Print n$;
        If i Mod 4 = 0 Then Print: Print " ";
    Next
    Print
End Sub
Sub move (d)
    newHole = hole + delta(d)
    If newHole >= 1 And newHole <= 16 And (hole Mod 4 = newHole Mod 4) Or Int((hole - 1) / 4) = Int((newHole - 1) / 4) Then
        Mid$(board$, hole, 1) = Mid$(board$, newHole, 1): Mid$(board$, newHole, 1) = "0": hole = newHole
    End If
End Sub

Working the puzzle:
   

Solved:
   
b = b + ...
Reply




Users browsing this thread: 3 Guest(s)