Share My Creation Original Slider Game

Hi, this was the original Slider game that I subsequently went on to create the Image Slider using images instead of the numbers used in the original plastic game of the seventies.
As i mentioned before I'm 68 years young, and coming from an IT background, my programming is mainly old school, PDP's and UNIX running the best language (in my opinion) MUMPS :), I then moved onto IT Support before retiring early and buying a Pub.

I have created numerous programs that I used to make life a bit easier, including a Pub Quiz app, Bingo, and calculators for optimal profit on various beers, etc. Darts ScoreBoard and games, and lots for my hobby at the time of Sea Fishing, which included weather apps, tide tables, navigation aids, Charts, fishing marks, knots and rigs.

All the above have one thing in common, B4A and B4J, and I believe keeping the old grey matter fresh by coding and solving problems along the way help me mentally and keep me fresh enough to be worn out by the grandkids, anyway, I rant on...

So back to the slider, No additional libraries or files required in this version so here is the code.

B4X:
#Region  Project Attributes
    #ApplicationLabel: DITL Sliders
    #VersionCode: 1
    #VersionName: 1.2

    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
    #BridgeLogger: true
#End Region

Sub Process_Globals
    Private Timer1 As Timer
End Sub

Sub Globals
    Private pnlMain As Panel
    Private btnTiles() As Button ' Dynamic array for tiles
    Private gameGrid(8,8) As Int ' Dynamic 2D grid
    Private emptyRow, emptyCol As Int
    Private lblMoves As Label
    Private lblLevel As Label
    Private lblLevelInfo As Label
    Private btnShuffle As Button
    Private btnNewGame As Button
    Private btnRestart As Button
    Private moveCount As Int
    Private tileSize As Int
    Private margin As Int = 8dip
    Private currentLevel As Int
    Private gridSize As Int
    Private totalMoves As Int
    Private maxLevel As Int = 8
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Timer1.Initialize("Timer1", 2000)
    InitializeGame
    StartLevel(3)
End Sub

Sub InitializeGame
    ' Create main panel
    pnlMain.Initialize("")
    Activity.AddView(pnlMain, margin, 140dip, 100%x - (2 * margin), 100%x - (2 * margin))
    pnlMain.Color = Colors.DarkGray
    ' Create level info label
    lblLevel.Initialize("")
    lblLevel.Text = "Level 1 (3x3)"
    lblLevel.TextSize = 24
    lblLevel.TextColor = Colors.Blue
    lblLevel.Gravity = Gravity.CENTER
    Activity.AddView(lblLevel, margin, 20dip, 100%x - (2 * margin), 40dip)
    ' Create level description
    lblLevelInfo.Initialize("")
    lblLevelInfo.Text = "Complete this level to advance!"
    lblLevelInfo.TextSize = 16
    lblLevelInfo.TextColor = Colors.Black
    lblLevelInfo.Gravity = Gravity.CENTER
    Activity.AddView(lblLevelInfo, margin, 65dip, 100%x - (2 * margin), 30dip)
    ' Create move counter label
    lblMoves.Initialize("")
    lblMoves.Text = "Moves: 0 | Total: 0"
    lblMoves.TextSize = 18
    lblMoves.TextColor = Colors.Black
    lblMoves.Gravity = Gravity.CENTER
    Activity.AddView(lblMoves, margin, 100dip, 100%x - (2 * margin), 35dip)
    ' Create buttons
    btnShuffle.Initialize("btnShuffle")
    btnShuffle.Text = "Shuffle"
    btnShuffle.TextSize = 16
    btnShuffle.Color = Colors.Blue
    btnShuffle.TextColor = Colors.White
    Activity.AddView(btnShuffle, margin, 100%y - 120dip, 110dip, 60dip)
    btnRestart.Initialize("btnRestart")
    btnRestart.Text = "Restart Level"
    btnRestart.TextSize = 16
    btnRestart.Color = Colors.Blue
    btnRestart.TextColor = Colors.White
    Activity.AddView(btnRestart, margin + 120dip, 100%y - 120dip, 140dip, 60dip)
    btnNewGame.Initialize("btnNewGame")
    btnNewGame.Text = "New Game"
    btnNewGame.TextSize = 16
    btnNewGame.Color = Colors.Blue
    btnNewGame.TextColor = Colors.White
    Activity.AddView(btnNewGame, 100%x - 150dip, 100%y - 120dip, 140dip, 60dip)
    currentLevel = 1
    totalMoves = 0
End Sub

Sub StartLevel(size As Int)
    gridSize = size
    moveCount = 0
    ' Update level display
    lblLevel.Text = "Level " & currentLevel & " (" & gridSize & "x" & gridSize & ")"
    If currentLevel = 1 Then
        lblLevelInfo.Text = "Complete this level to advance!"
    Else
        lblLevelInfo.Text = "Level " & (currentLevel - 1) & " completed! New challenge:"
    End If
    ' Calculate tile size for current grid
    tileSize = (pnlMain.Width - ((gridSize + 1) * margin)) / gridSize
    ' Clear existing tiles
    pnlMain.RemoveAllViews
    ' Initialize dynamic arrays
    Dim totalTiles As Int = gridSize * gridSize
    Dim btnTilesTemp(totalTiles) As Button
    btnTiles = btnTilesTemp
    Dim gridTemp(gridSize, gridSize) As Int
    gameGrid = gridTemp
    CreateGameBoard
    NewLevel
End Sub

Sub CreateGameBoard
    Dim row, col As Int
    ' Initialize tiles
    For row = 0 To gridSize - 1
        For col = 0 To gridSize - 1
            Dim index As Int = row * gridSize + col
            btnTiles(index).Initialize("btnTile")
            ' center the grid
            Dim boardWidth As Int = gridSize * tileSize + (gridSize - 1) * margin
            Dim startX As Int = (pnlMain.Width - boardWidth) / 2
            Dim startY As Int = (pnlMain.Height - boardWidth) / 2
            Dim left As Int = startX + col * (tileSize + margin)
            Dim top As Int = startY + row * (tileSize + margin)
            pnlMain.AddView(btnTiles(index), left, top, tileSize, tileSize)
            ' Style the button
            Dim textSize As Int
            If gridSize <= 3 Then
                textSize = tileSize / 3.5
            Else If gridSize <= 4 Then
                textSize = tileSize / 4.5
            Else If gridSize <= 5 Then
                textSize = tileSize / 5.5
            Else If gridSize <= 6 Then
                textSize = tileSize / 6.5
            Else If gridSize <= 7 Then
                textSize = tileSize / 7.5
            Else
                textSize = tileSize / 8.5
            End If
            textSize = Max(8, textSize) ' Minimum readable size
            btnTiles(index).TextSize = textSize
            btnTiles(index).Color = Colors.LightGray
            btnTiles(index).TextColor = Colors.Black
        Next
    Next
End Sub

Sub NewLevel
    ' Initialize solved state
    Dim row, col As Int
    For row = 0 To gridSize - 1
        For col = 0 To gridSize - 1
            gameGrid(row, col) = row * gridSize + col + 1
        Next
    Next
    ' Set empty space (last position becomes 0)
    gameGrid(gridSize - 1, gridSize - 1) = 0
    emptyRow = gridSize - 1
    emptyCol = gridSize - 1
    UpdateDisplay
    ShuffleBoard
End Sub

Sub ShuffleBoard
    ' Perform random valid moves to shuffle
    Dim shuffleMoves As Int = gridSize * gridSize * 200
    Dim i As Int
    For i = 1 To shuffleMoves
        Dim validMoves As List
        validMoves.Initialize
        ' Find all valid moves
        If emptyRow > 0 Then validMoves.Add(Array(emptyRow - 1, emptyCol)) ' Up
        If emptyRow < gridSize - 1 Then validMoves.Add(Array(emptyRow + 1, emptyCol)) ' Down
        If emptyCol > 0 Then validMoves.Add(Array(emptyRow, emptyCol - 1)) ' Left
        If emptyCol < gridSize - 1 Then validMoves.Add(Array(emptyRow, emptyCol + 1)) ' Right
        ' Pick random valid move
        If validMoves.Size > 0 Then
            Dim randomIndex As Int = Rnd(0, validMoves.Size)
            Dim move(2) As Int
            Dim tempArray() As Object = validMoves.Get(randomIndex)
            move(0) = tempArray(0)
            move(1) = tempArray(1)
            MakeMoveInternal(move(0), move(1))
        End If
    Next
    moveCount = 0 ' Reset move counter after shuffle
    UpdateDisplay
End Sub

Sub MakeMoveInternal(row As Int, col As Int)
    ' Internal move without incrementing counter
    gameGrid(emptyRow, emptyCol) = gameGrid(row, col)
    gameGrid(row, col) = 0
    emptyRow = row
    emptyCol = col
End Sub

Sub btnTile_Click
    Dim btn As Button = Sender
    ' Find which tile was clicked
    Dim clickedIndex As Int = -1
    Dim i As Int
    For i = 0 To btnTiles.Length - 1
        If btnTiles(i) = btn Then
            clickedIndex = i
            Exit
        End If
    Next
    If clickedIndex = -1 Then Return
    ' Convert index to row/col
    Dim clickedRow As Int = clickedIndex / gridSize
    Dim clickedCol As Int = clickedIndex Mod gridSize
    ' Check if move is valid (adjacent to empty space)
    If IsValidMove(clickedRow, clickedCol) Then
        ' Make the move
        gameGrid(emptyRow, emptyCol) = gameGrid(clickedRow, clickedCol)
        gameGrid(clickedRow, clickedCol) = 0
        emptyRow = clickedRow
        emptyCol = clickedCol
        moveCount = moveCount + 1
        totalMoves = totalMoves + 1
        UpdateDisplay
        ' Check for win
        If CheckWin Then
            ' Level completed!
            Dim message As String
            If currentLevel < maxLevel Then
                currentLevel = currentLevel + 1
                message = "Level " & (currentLevel - 1) & " completed in " & moveCount & " moves!" & CRLF & "Advancing to " & (gridSize + 1) & "x" & (gridSize + 1) & " grid..."
                ' Advance to next level after short delay
                Timer1.Enabled = True
            Else
                message = "Congratulations! You completed ALL levels!" & CRLF & "Final level completed in " & moveCount & " moves." & CRLF & "Total moves: " & totalMoves
            End If
            ToastMessageShow(message, True)
        End If
    End If
End Sub

' Timer for level transition
Sub Timer1_Tick
    Timer1.Enabled = False
    StartLevel(gridSize + 1)
End Sub

Sub IsValidMove(row As Int, col As Int) As Boolean
    ' Check if the clicked position is adjacent to empty space
    Dim rowDiff As Int = Abs(row - emptyRow)
    Dim colDiff As Int = Abs(col - emptyCol)
    Return (rowDiff = 1 And colDiff = 0) Or (rowDiff = 0 And colDiff = 1)
End Sub

Sub UpdateDisplay
    Dim row, col As Int
    For row = 0 To gridSize - 1
        For col = 0 To gridSize - 1
            Dim index As Int = row * gridSize + col
            Dim value As Int = gameGrid(row, col)
            If value = 0 Then
                ' Empty space
                btnTiles(index).Text = ""
                btnTiles(index).Color = Colors.Transparent
                btnTiles(index).Visible = False
            Else
                ' Numbered tile
                btnTiles(index).Text = value
                btnTiles(index).Visible = True
                ' Color coding based on value ranges
                Dim maxValue As Int = gridSize * gridSize - 1
                If value <= maxValue / 4 Then
                    btnTiles(index).Color = Colors.RGB(173, 216, 230) ' Light blue
                Else if value <= maxValue / 2 Then
                    btnTiles(index).Color = Colors.RGB(144, 238, 144) ' Light green
                Else if value <= (maxValue * 3) / 4 Then
                    btnTiles(index).Color = Colors.RGB(255, 182, 193) ' Light pink
                Else
                    btnTiles(index).Color = Colors.RGB(255, 218, 185) ' Peach
                End If
            End If
        Next
    Next
    lblMoves.Text = "Moves: " & moveCount & " | Total: " & totalMoves
End Sub

Sub CheckWin As Boolean
    Dim row, col As Int

    For row = 0 To gridSize - 1
        For col = 0 To gridSize - 1
            Dim expectedValue As Int
            If row = gridSize - 1 And col = gridSize - 1 Then
                expectedValue = 0 ' Empty space should be at bottom right
            Else
                expectedValue = row * gridSize + col + 1
            End If
            If gameGrid(row, col) <> expectedValue Then
                Return False
            End If
        Next
    Next
    Return True
End Sub

Sub btnShuffle_Click
    ShuffleBoard
End Sub

Sub btnRestart_Click
    NewLevel
End Sub

Sub btnNewGame_Click
    currentLevel = 1
    totalMoves = 0
    StartLevel(3) ' Start over with 3x3
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 

Attachments

  • Screenshot_20250821-105658.png
    Screenshot_20250821-105658.png
    94.9 KB · Views: 299
  • Screenshot_20250821-105745.png
    Screenshot_20250821-105745.png
    95.7 KB · Views: 33
  • Screenshot_20250821-105750.png
    Screenshot_20250821-105750.png
    133.4 KB · Views: 34
Top