Private requiredCellAddressesArray As Variant 
' Declare at the top of the module

Private Sub Worksheet_Activate()
    ' This event fires when the sheet becomes active.
    ' It's a good place to initialize our array of cell addresses once.
    If IsEmpty(requiredCellAddressesArray) Then 
        ' Only initialize if not already done
        Call InitializeRequiredCellsArray
    End If
    ' Optional: Ensure the first cell in the sequence is activated when the sheet is activated
    If Not IsEmpty(requiredCellAddressesArray) Then
        Me.Range(requiredCellAddressesArray(LBound(requiredCellAddressesArray))).Activate
    End If
End Sub

Private Sub InitializeRequiredCellsArray()
    ' Define your non-contiguous cells in the exact "snake game" order.
    ' Ensure the order is precise as this defines the user's path.
    requiredCellAddressesArray = Array("B4", "B5", "B6", "B7", "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", "B16", "C16", "D16", _
    "E16", "F16", "G16", "G15", "G14", "G13", "G12", "G11", "F11", "E11", "E10", "E9", "E8", "F8", "G8", "H8", "I8", "J8", "J9", "J10", "J11", _
    "J12", "J13", "K13", "L13", "M13", "N13", "N12", "N11", "N10", "O10", "P10", "Q10", "Q9", "Q8", "R8", "S8", "S7", "S6", "S5", "R5", "Q5", _
    "P5", "O5", "N5", "M5", "M4", "L4", "K4", "J4", "I4", "I5", "H5", "G5", "F5", "F4", "F3", "G3", "G2", "H2", "I2", "J2", "K2", "L2", "M2", "N2", _
    "O2", "P2", "Q2", "R2", "R3", "S3", "T3", "U3", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "W9", "X9", "X8", "X7", "Y7", "Y6", "Y5", "Y4", "X4", _
    "X3", "X2", "Y2", "Z2", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AA8", "AA9", "AA10", "Z10", "Z11", "Z12", "Z13", "Z14", "Z15", "Y15", "X15", _
    "W15", "V15", "U15", "U16", "T16", "S16", "R16", "Q16", "P16", "O16", "N16", "M16")
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim currentCellAddress As String
    Dim previousCellAddressInSequence As String 
    ' Renamed for clarity
    Dim currentCellIndexInArray As Long 
    ' Renamed for clarity
    Dim i As Long
    Dim blnTargetIsInRequiredPath As Boolean
    Dim rngPreviousCell As Range 
    ' To hold the actual Range object of the previous cell
    ' Turn off events to prevent re-triggering this macro during our own actions
    Application.EnableEvents = False
    On Error GoTo CleanUp
    If IsEmpty(requiredCellAddressesArray) Then 
        ' Ensure array is initialized
        Call InitializeRequiredCellsArray
    End If
    ' 1. Determine if the selected cell (Target) is part of our required path
    blnTargetIsInRequiredPath = False
    currentCellIndexInArray = -1 
    ' Initialize to not found
    For i = LBound(requiredCellAddressesArray) To UBound(requiredCellAddressesArray)
        ' Compare the full address to ensure exact match (e.g., $A$1 vs $A$1)
        If Target.Address = Me.Range(requiredCellAddressesArray(i)).Address Then
            currentCellIndexInArray = i
            blnTargetIsInRequiredPath = True
            Exit For
        End If
    Next i
    ' 2. Handle invalid selections (multi-cell or outside the path) 
    If Not blnTargetIsInRequiredPath Or Target.Cells.Count > 1 Then
        Dim firstEmptyRequiredCell As Range 
        ' Holds the Range object of the first empty cell
        firstEmptyRequiredCellIndex = -1
        ' Find the first empty cell in the defined sequence
        For i = LBound(requiredCellAddressesArray) To UBound(requiredCellAddressesArray)
            Set firstEmptyRequiredCell = Me.Range(requiredCellAddressesArray(i))
            If IsEmpty(firstEmptyRequiredCell.Value) Or Trim(firstEmptyRequiredCell.Value) = "" Then
                firstEmptyRequiredCellIndex = i
                Exit For
            End If
        Next i
        ' If there's an empty required cell, activate it and warn the user
        If firstEmptyRequiredCellIndex <> -1 Then
            MsgBox "Please fill in all preceding mandatory fields. Cell " & firstEmptyRequiredCell.Address(False, False) & " is blank.", vbExclamation, "Mandatory Field"
            firstEmptyRequiredCell.Activate
        Else
            ' All required cells are filled, allow movement freely outside the path.
            ' No action needed, user can move elsewhere.
        End If
        ' 3. Handle valid single cell selection within the required path 
    Else 
        ' User selected a designated single cell in the sequence
        ' Check if the immediately preceding cell IN THE SEQUENCE is filled
        If currentCellIndexInArray > LBound(requiredCellAddressesArray) Then
            ' Get the address of the actual previous cell in the defined sequence
            previousCellAddressInSequence = requiredCellAddressesArray(currentCellIndexInArray - 1)
            Set rngPreviousCell = Me.Range(previousCellAddressInSequence)
            ' Check if that specific previous cell is empty
            If IsEmpty(rngPreviousCell.Value) Or Trim(rngPreviousCell.Value) = "" Then
                MsgBox "Please fill in cell " & rngPreviousCell.Address(False, False) & " before moving to " & Target.Address(False, False) & ".", vbExclamation, "Mandatory Field"
                rngPreviousCell.Activate 
                ' Force user back to the unfilled previous cell
            End If
        End If
        ' Additionally, ensure no cells earlier in the sequence were skipped
        ' This catches cases where they fill the immediate previous, but skipped one even earlier.
        For i = LBound(requiredCellAddressesArray) To currentCellIndexInArray - 1
            Set currentCell = Me.Range(requiredCellAddressesArray(i)) 
            ' Using currentCell to iterate through preceding
            If IsEmpty(currentCell.Value) Or Trim(currentCell.Value) = "" Then
                MsgBox "Please fill in all preceding mandatory fields. Cell " & currentCell.Address(False, False) & " is blank.", vbExclamation, "Mandatory Field"
                currentCell.Activate 
                ' Go back to the first skipped cell
                Exit For 
                ' Stop checking once the first skipped cell is found
            End If
        Next i
    End If
    CleanUp:    
    Application.EnableEvents = True
    If Err.Number <> 0 Then
        MsgBox "An error occurred: " & Err.Description, vbCritical, "Error"
    End If
End Sub