Skip to content
Snippets Groups Projects
Commit 4e6c2ff3 authored by Hans Moog's avatar Hans Moog
Browse files

Feat: simplified formulas for mana calculations

parent 2909a601
No related branches found
No related tags found
No related merge requests found
......@@ -5,18 +5,18 @@ import (
)
type Balance struct {
calculator *Calculator
currentBalance uint64
lastErosion uint64
roundingErrorInLastErosion float64
calculator *Calculator
currentBalance uint64
lastErosion uint64
accumulatedRoundingError float64
}
func NewBalance(calculator *Calculator) *Balance {
return &Balance{
calculator: calculator,
currentBalance: 0,
lastErosion: 0,
roundingErrorInLastErosion: 0,
calculator: calculator,
currentBalance: 0,
lastErosion: 0,
accumulatedRoundingError: 0,
}
}
......@@ -25,23 +25,33 @@ func (balance *Balance) GetValue() uint64 {
}
func (balance *Balance) AddTransfer(movedCoins uint64, receivedTime uint64, spentTime uint64) {
gainedMana, _ := balance.calculator.GenerateMana(movedCoins, spentTime-receivedTime)
if spentTime >= balance.lastErosion {
balance.Erode(spentTime)
} else {
fmt.Println("empty")
// revert old actions
// apply new
// replay old
gainedMana, roundingError := balance.calculator.GenerateMana(movedCoins, spentTime-receivedTime)
if balance.currentBalance != 0 {
if spentTime >= balance.lastErosion {
balance.Erode(spentTime)
} else {
fmt.Println("empty")
// revert old actions
// apply new
// replay old
}
}
balance.currentBalance += gainedMana
balance.accumulatedRoundingError += roundingError
balance.lastErosion = spentTime
fmt.Println("GENERATE: ", spentTime-receivedTime, movedCoins, gainedMana)
}
func (balance *Balance) Erode(erosionTime uint64) {
if balance.lastErosion <= erosionTime {
balance.currentBalance, _ = balance.calculator.ErodeMana(balance.currentBalance, erosionTime-balance.lastErosion)
erodedMana, _ := balance.calculator.ErodeMana(balance.currentBalance, erosionTime-balance.lastErosion)
fmt.Println("ERODE: ", erosionTime-balance.lastErosion, balance.currentBalance, erodedMana)
balance.currentBalance = erodedMana
} else {
fmt.Println("empty")
// revert old erosions
......
package mana
import (
"fmt"
"testing"
)
func TestBalance_AddTransfer(t *testing.T) {
calculator := NewCalculator(500, 0.1)
balance1 := NewBalance(calculator)
balance1.AddTransfer(1000, 0, 500)
balance1.AddTransfer(1000, 500, 1000)
balance1.AddTransfer(1000, 1000, 1700)
fmt.Println(balance1.GetValue())
balance2 := NewBalance(calculator)
balance2.AddTransfer(1000, 0, 1700)
fmt.Println(balance2.GetValue())
}
......@@ -7,7 +7,7 @@ import (
// A calculator that can be used to calculate the changes of mana due to erosion or mana generation.
type Calculator struct {
decayInterval float64
decayRate float64
decayFactor float64
options *CalculatorOptions
tokenSupplyScalefactor float64
}
......@@ -17,13 +17,13 @@ func NewCalculator(decayInterval float64, decayRate float64, optionalOptions ...
return &Calculator{
// store key settings
decayInterval: decayInterval,
decayRate: decayRate,
// configure optional parameters
options: DEFAULT_OPTIONS.Override(optionalOptions...),
// derive important factors ...
// ... make mana reach exactly the token supply as it's max value (n coins => n mana)
decayFactor: 1 - decayRate,
tokenSupplyScalefactor: decayRate / (1 - decayRate),
}
}
......@@ -31,9 +31,7 @@ func NewCalculator(decayInterval float64, decayRate float64, optionalOptions ...
// Returns the amount of mana that was generated by holding the given amount of coins for the given time.
func (calculator *Calculator) GenerateMana(coins uint64, heldTime uint64) (result uint64, roundingError float64) {
// calculate results
relativeDecayTime := float64(heldTime) / float64(calculator.decayInterval)
erosionFactor := (1 - math.Pow(1-calculator.decayRate, float64(relativeDecayTime+1)) - calculator.decayRate) / calculator.decayRate
gainedMana := float64(coins) * calculator.options.ManaScaleFactor * calculator.tokenSupplyScalefactor * erosionFactor
gainedMana := float64(coins) * calculator.options.ManaScaleFactor * (1 - math.Pow(calculator.decayFactor, float64(heldTime)/calculator.decayInterval))
// assign rounded results & determine roundingErrors
result = uint64(math.Round(gainedMana))
......@@ -52,8 +50,7 @@ func (calculator *Calculator) ErodeMana(mana uint64, decayTime uint64) (result u
}
// calculate results
growthFactor := math.Log(1-calculator.decayRate) / float64(calculator.decayInterval)
erodedMana := float64(mana) * math.Pow(math.E, growthFactor*float64(decayTime))
erodedMana := float64(mana) * math.Pow(calculator.decayFactor, float64(decayTime)/calculator.decayInterval)
// assign rounded results & determine roundingErrors
result = uint64(math.Round(erodedMana))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment