From a198694a6fae0dca03194d8474e2a6976d3e9779 Mon Sep 17 00:00:00 2001 From: "Dr. Groove" <166350737+DrGrooveDev@users.noreply.github.com> Date: Sun, 7 Apr 2024 23:23:58 -0700 Subject: [PATCH] Refactor random tier function for clarity. Add simulations. --- .../pick-random-tier.go | 84 +++++++++++++------ 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/cmd/microservice-ethereum-create-transaction-lootboxes/pick-random-tier.go b/cmd/microservice-ethereum-create-transaction-lootboxes/pick-random-tier.go index ae368017a..7fee5d7f0 100644 --- a/cmd/microservice-ethereum-create-transaction-lootboxes/pick-random-tier.go +++ b/cmd/microservice-ethereum-create-transaction-lootboxes/pick-random-tier.go @@ -9,46 +9,78 @@ import ( "math/rand" ) -// PayoutChances to pick the random number between +// PayoutChances to pick the random number between 0 and this value const PayoutChances = 1_000_000_000 const ( - // PayoutTier1 that the random number must fall below to win - PayoutTier1 = 400_000_000 - // PayoutTier2 that the payout must be below, but above PayoutTier1, to win - PayoutTier2 = 500_000_000 + // The probabilities of a Tier being drawn (out of PayoutChances draws) + Tier1Prob = 400_000_000 // this is 400_000_000 / 1_000_000_000 + Tier2Prob = 100_000_000 // this is 100_000_000 / 1_000_000_000 + Tier3Prob = 50_000_000 //etc... + Tier4Prob = 10_000_000 + Tier5Prob = 100 + //The probability of NoBottle is: (PayoutChances - (The Sum of all TierXProb values above)) / PayoutChances - // PayoutTier3 - PayoutTier3 = 550_000_000 + // Thresholds that the random number must fall below to win a tier + PayoutTier1 = Tier1Prob + PayoutTier2 = Tier2Prob + PayoutTier1 + PayoutTier3 = Tier3Prob + PayoutTier2 + PayoutTier4 = Tier4Prob + PayoutTier3 + PayoutTier5 = Tier5Prob + PayoutTier4 + //Anything above PayoutTier5 is NoBottle - // PayoutTier4 - PayoutTier4 = 560_000_000 - - // PayoutNoBottle is awarded when no bottle is sent to the user - PayoutNoBottle = 999_999_000 - - // PayoutTier5 (very low probability) - PayoutTier5 = 1_000_000_000 ) -// pickRandomReward, 0 being no rewards. +// pickRandomReward. Returns Lootbox Tier 0-5, 0 being no rewards. func pickRandomNumber() int { n := rand.Int31n(PayoutChances) switch { - case n >= PayoutNoBottle && n <= PayoutTier5: - return 5 - case n >= PayoutTier4 && n <= PayoutNoBottle: - return 0 - case n >= PayoutTier3 && n <= PayoutTier4: - return 4 - case n >= PayoutTier2 && n <= PayoutTier3: - return 3 - case n >= PayoutTier1 &&n <= PayoutTier2: - return 2 case n <= PayoutTier1: return 1 + case n <= PayoutTier2: + return 2 + case n <= PayoutTier3: + return 3 + case n <= PayoutTier4: + return 4 + case n <= PayoutTier5: + return 5 + case n > PayoutTier5 && n <= PayoutChances: + return 0 //NoBottle default: panic(fmt.Sprintf("bad pickRandomNumber impl: %v", n)) } } + +// getExpectedTierPcts. Returns the expected percentage chance of being drawn for all tiers +func getExpectedTierPcts() map[int]float64 { + expectedMap := make(map[int]float64) + expectedMap[0] = float64((PayoutChances - PayoutTier5)) / float64(PayoutChances) * 100 + expectedMap[1] = float64(Tier1Prob) / float64(PayoutChances) * 100 + expectedMap[2] = float64(Tier2Prob) / float64(PayoutChances) * 100 + expectedMap[3] = float64(Tier3Prob) / float64(PayoutChances) * 100 + expectedMap[4] = float64(Tier4Prob) / float64(PayoutChances) * 100 + expectedMap[5] = float64(Tier5Prob) / float64(PayoutChances) * 100 + return expectedMap +} + +// simulate a large number of draws and compare to the expected probabilities. +func simulateDraws() { + simIterations := 100000 + expectedResults := getExpectedTierPcts() + simResults := make(map[int]int) + for i := 0; i < 6; i++ { + simResults[i] = 0 + } + + for i := 0; i < simIterations; i++ { + lootboxRewardTier := pickRandomNumber() + simResults[lootboxRewardTier] += 1 + } + + fmt.Printf("\nIterations: %v", simIterations) + for i := 0; i < 6; i++ { + fmt.Printf("\nTier %v Got: %v = %v%% Expected:%v%%", i, simResults[i], (float64(simResults[i])/float64(simIterations))*100, expectedResults[i]) + } +}