Results 1 to 6 of 6

Thread: Randomizing Indexes in an Array

  1. #1

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Randomizing Indexes in an Array

    Well... it's ugly but this is what I came up with.

    Max Attribute is always 0 so don't need to generate a starting stat for it. This is to randomize the order stats get starting points rolled for so that it's not always biased in favor of the Index-order of the stats. I talked about it in chit-chat but now it's actual code.

    This is just the part where I'm randomizing in the Indexes, not the rolling values for the stats part. This is what I was being vexxed by. It's orders of magnitude better than what I was doing but still probably absolutely the wrong way to do it.

    What I'm trying to achieve is one and done rolling for stats (which calls this first).

    It's returning 0 through 5 (MIN_ATTRIBUTE = 0, MAX_ATTRIBUTE - 1 = 5)

    If someone can show me a better way I'd appreciate it.

    Code:
    Public Function RandomizeAttributeIndexes() As Long()
    Dim m_Callstacker As New cCallStacker
    Dim nAttributeIndex(MIN_PLAYER_ATTRIBUTE To MAX_PLAYER_ATTRIBUTE - 1) As Long
    Dim fSuccess As Boolean
    Dim nRnd As Long
    Dim n As Long
    Dim m As Long
    
    ' Does not include Development which always starts at 0.
    
    m_Callstacker.Add NAME & ".RandomizeAttributeIndexes(Public Function)"
    
    For n = LBound(nAttributeIndex) To UBound(nAttributeIndex)
    
      nAttributeIndex(n) = -1
    
    Next n
    
    Do
    
      fSuccess = True
    
      For n = LBound(nAttributeIndex) To UBound(nAttributeIndex)
    
        nRnd = RollDie(MAX_PLAYER_ATTRIBUTE - MIN_PLAYER_ATTRIBUTE) - 1
    
        If nAttributeIndex(n) = -1 Then
    
          For m = LBound(nAttributeIndex) To UBound(nAttributeIndex)
    
            If nAttributeIndex(m) = nRnd Then
    
              fSuccess = False
    
              Exit For
    
            End If
    
          Next m
    
          If fSuccess Then nAttributeIndex(n) = nRnd
    
        End If
    
      Next n
    
    Loop Until fSuccess
    
    For n = LBound(nAttributeIndex) To UBound(nAttributeIndex)
    
        Debug.Print "nAttributeIndex(" & n & ") = " & nAttributeIndex(n)
    
    Next n
    
    RandomizeAttributeIndexes = nAttributeIndex
    
    Stop
    
    End Function
    Last edited by cafeenman; Jun 18th, 2024 at 06:26 PM.

  2. #2

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Randomizing Indexes in an Array

    Forgot an Exit For in there. No reason to keep looping through the m loop after fSuccess is already false.

    This is the results of three quick runs:

    nattributeindex(n) = 2
    nattributeindex(n) = 1
    nattributeindex(n) = 3
    nattributeindex(n) = 0
    nattributeindex(n) = 4
    nattributeindex(n) = 5

    nattributeindex(n) = 4
    nattributeindex(n) = 0
    nattributeindex(n) = 2
    nattributeindex(n) = 1
    nattributeindex(n) = 5
    nattributeindex(n) = 3

    nattributeindex(n) = 0
    nattributeindex(n) = 1
    nattributeindex(n) = 3
    nattributeindex(n) = 4
    nattributeindex(n) = 5
    nattributeindex(n) = 2

    Edit: Oops... did the debug.print string wrong.

    This is the correct output:

    nAttributeIndex(0) = 0
    nAttributeIndex(1) = 1
    nAttributeIndex(2) = 4
    nAttributeIndex(3) = 3
    nAttributeIndex(4) = 5
    nAttributeIndex(5) = 2
    Last edited by cafeenman; Jun 18th, 2024 at 06:26 PM.

  3. #3

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Randomizing Indexes in an Array

    Next thing.

    Now I just have to marry these two procedures (the one above and this one).

    Then I can test it and see if it actually works.

    This is the rolling part.

    Code:
    Private Function RollStartingAttributeValue(ByRef AttributeID As PLAYER_ATTRIBUTES, ByRef AvailablePoints As Long) As Long
    Dim m_Callstacker As New cCallStacker
    Dim nMaxValue As Long
    Dim nMinStart As Long
    Dim nValue As Long
    
    ' Returns remaining Available Points.
    
    ' Caller needs to Initialize Min Values for each Attribute before calling this procedure so that
    ' all Attributes have at least the minimum required and those points are removed from the pool.
    
    m_Callstacker.Add NAME & ".RollStartingAttributeValue(Private Function)"
    
    nMinStart = nMinStartingAttributePoints(AttributeID)
    
    'AvailablePoints = AvailablePoints - nMinStart ' Oops.  Was subtracting them twice.  Once before here.
    
    
    If AvailablePoints < 0 Then Exit Function ' Somebody screwed up initialization of Mins and Maxes and should probably fix that.
    
    
    If AvailablePoints + nMinStart >= nMaxStartingAttributePoints(AttributeID) Then ' Enough Points Available to Max the Starting Value for Attribute.
    
      nMaxValue = nMaxStartingAttributePoints(AttributeID) - nMinStart
    
    Else ' Not enough Available Points to Max Attribute.
    
      nMaxValue = AvailablePoints
    
    End If
    
    
    nValue = RollDie(nMaxValue + 1) - 1
    
    nStartingAttributePoints(AttributeID) = nMinStart + nValue
    
    RollStartingAttributeValue = AvailablePoints - nValue
    
    End Function
    Last edited by cafeenman; Jun 18th, 2024 at 07:28 PM.

  4. #4

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Randomizing Indexes in an Array

    crap... and now I just realized this will not distribute all the points necessarily. I mean it could roll a bunch of 1's and leave hundreds of points. So now I'm back to the same problem I started with.

    crap....

  5. #5

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Randomizing Indexes in an Array

    I think this solves the above problem. Really a brute-force way to do it but basically just gonna take any left-over points and distribute them point-by-point to Attributes that haven't reached their Max allowed starting value.

    Thus:

    Code:
    Private Sub DistributeRemainingStartingPoints(ByRef AvailablePoints As Long)
    Dim m_Callstacker As New cCallStacker
    Dim nCounter As Long
    Dim n As Long
    
    m_Callstacker.Add NAME & ".DistributeRemainingStartingPoints(Private Sub)"
    
    Do
    
      nCounter = nCounter + 1 ' Should be adding at least one point each time through.
    
      For n = LBound(nStartingAttributePoints) To UBound(nStartingAttributePoints)
    
        If AvailablePoints < 1 Then Exit Sub
    
        If nStartingAttributePoints(n) < nMaxStartingAttributePoints(n) Then
    
          nStartingAttributePoints(n) = nStartingAttributePoints(n) + 1
    
          AvailablePoints = AvailablePoints - 1
    
        End If
    
      Next n
    
      If nCounter >= nSumStartingAttributesMustEqual Then Exit Sub ' Bail out.  Something went wrong.
      
    Loop
    
    End Sub
    Last edited by cafeenman; Jun 18th, 2024 at 07:46 PM.

  6. #6

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Randomizing Indexes in an Array

    GOT IT! (Still not resolved because of original post - better way to shuffle an array)

    But it works and it's so way much faster and better than what I had before.

    This is the Call that starts it all. I think I've edited all the above posts to show their current version.

    Code:
    Private Function RollRandomStartingAttributes() As Long
    Dim m_Callstacker As New cCallStacker
    Dim nAttributeIndex() As Long
    Dim nAvailableStartingPoints As Long
    Dim n As Long
    
    m_Callstacker.Add NAME & ".RollRandomStartingAttributes(Private Function)"
    
    nAvailableStartingPoints = nTotalStartingPoints
    
    For n = MIN_PLAYER_ATTRIBUTE To MAX_PLAYER_ATTRIBUTE - 1
    
      nStartingAttributePoints(n) = nMinStartingAttributePoints(n)
      nAvailableStartingPoints = nAvailableStartingPoints - nMinStartingAttributePoints(n)
    
    Next n
    
    nAttributeIndex = RandomizeAttributeIndexes
    
    For n = LBound(nAttributeIndex) To UBound(nAttributeIndex)
    
      nAvailableStartingPoints = RollStartingAttributeValue(nAttributeIndex(n), nAvailableStartingPoints)
    
    Next n
    
    DistributeRemainingStartingPoints nAvailableStartingPoints
    
    RollRandomStartingAttributes = 0
    
    End Function

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width