package info import "github.com/gogf/gf/v2/util/grand" // PlayerCaptureContext 用户捕捉上下文(每次登录创建) type PlayerCaptureContext struct { Denominator int // 统一分母=1000 DecayFactor float64 // 衰减系数 MinDecayNum int // 衰减分子最小值 Guarantees map[int]int // 按分母分组的保底分子 map[denominator]numerator } func NewPlayerCaptureContext() *PlayerCaptureContext { return &PlayerCaptureContext{ Denominator: 1000, DecayFactor: 0.10, MinDecayNum: 1, Guarantees: make(map[int]int), } } // Roll 通用概率判定(带共享保底) 返回成功,基础,保底 func (c *PlayerCaptureContext) Roll(numerator, denominator int) (bool, float64, float64) { if denominator <= 0 { return false, 0, 0 } if c == nil { c = NewPlayerCaptureContext() } base := float64(numerator) / float64(denominator) bonusNumerator := c.getGuaranteeNumerator(denominator) bonus := float64(bonusNumerator) / float64(denominator) total := base + bonus if total > 1.0 { total = 1.0 } totalNumerator := numerator + bonusNumerator if totalNumerator > denominator { totalNumerator = denominator } success := grand.Intn(denominator) < totalNumerator if success { c.resetGuarantee(denominator) } else { c.increaseGuarantee(denominator) } return success, base * 100, bonus * 100 } // 保底操作 func (c *PlayerCaptureContext) getGuaranteeNumerator(denominator int) int { if c == nil || c.Guarantees == nil { return 0 } if num, ok := c.Guarantees[denominator]; ok { return num } return 0 } func (c *PlayerCaptureContext) increaseGuarantee(denominator int) { if c == nil { return } if c.Guarantees == nil { c.Guarantees = make(map[int]int) } c.Guarantees[denominator]++ } func (c *PlayerCaptureContext) resetGuarantee(denominator int) { if c == nil { return } if c.Guarantees == nil { c.Guarantees = make(map[int]int) } c.Guarantees[denominator] = 0 }