Exceptional Averages

Counting up numbers into an Average takes time, but recently I developed a method of doing this without using a loop. Essentially once the Pile of numbers is full, we need to remove the oldest number from the Pile and add the new one.

Also, if you’re tracking over a long period of time, you want it to be accurate from the beginning. The JEOZ.Average Structure solves those issues.

The Average.Smooth Field is a GoNumber that helps even out the Average Value. When displaying numbers on screen it’s hard to follow if they move too quickly.

Public Structure Average
Public Pile() As Single
Public Average As Single
Public Digits, Total As Integer
Public Smooth As GoNumber
Public SmoothSpeed As Single
Private Index, NextIndex, Count, Available As Integer
Private Sum As Single

Public Sub New(_Count As Integer, Optional _Digits As Integer = 1,
Optional _Smooth As Single = 0.1)
Setup(_Count, _Digits)
End Sub
Public Sub Setup(_Count As Integer, Optional _Digits As Integer = 1,
Optional _Smooth As Single = 0.1)
Digits = _Digits
Count = _Count - 1
SmoothSpeed = _Smooth
ReDim Numbers(Count)
Smooth = New GoNumber(0)
End Sub

Public ReadOnly Property Value As Single
Get
Return Math.Round(Smooth.Now, Digits)
End Get
End Property

Public Overrides Function ToString() As String
Return Math.Round(Smooth.Now, Digits)
End Function

Use the AddValue Function on each Frame of the GameLoop to add another value to the Pile.

Public Sub AddValue(Value As Single)
Total += Value
'// Increase NextIndex until Count, then wrap to 0. In other words,
'// "If NextIndex = Count Then NextIndex = 0 Else NextIndex += 1"
NextIndex = If(NextIndex = Count, 0, NextIndex + 1)
'// Remove previous value at the current index, because this index
'// will be the oldest value, which is 0 if this is the first time.
Sum -= Pile(NextIndex)
'// Store Current Value into the Pile
Pile(Index) = Value
'// Move the Index forward
Index = NextIndex
'// Increase Available until we reach total Count
'// to make the Average accurate from the start
Available += If(Available <= Count, 1, 0)
'// Add the new Value to the Sum Total
Sum += Value
'// Calculate the new Average
Average = Sum / Available
'// Set the Smooth GoNumber to follow the Average
Smooth.Go = Average
Smooth.Slide(SmoothSpeed)
End Sub
End Structure

Use the [Average].Average Field to get the exact state, or the [Average].Value Property to Get the value Smoothed out over time.

MyBBXP is having trouble with the MyBB database connection, perhaps re-check your settings
?