refactor(fight): 重构随机数生成器模块并优化战斗技能PP管理
This commit is contained in:
143
common/utils/random/random.go
Normal file
143
common/utils/random/random.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package random
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RandomXS128 实现 xorshift128+ 伪随机数生成器
|
||||
type RandomXS128 struct {
|
||||
seed0 uint64 // 内部状态前半部分
|
||||
seed1 uint64 // 内部状态后半部分
|
||||
}
|
||||
|
||||
// 归一化常数
|
||||
const (
|
||||
normDouble = 1.0 / (1 << 53)
|
||||
normFloat = 1.0 / (1 << 24)
|
||||
)
|
||||
|
||||
// NewRandomXS128 创建一个新的随机数生成器,自动生成初始种子
|
||||
func NewRandomXS128() *RandomXS128 {
|
||||
// 用系统随机数初始化种子(模拟 Java 中 new Random().nextLong() 的行为)
|
||||
// 实际使用中可替换为更安全的种子源(如 crypto/rand)
|
||||
source := rand.NewSource(time.Now().UnixNano()) // 基于时间的种子源
|
||||
r := rand.New(source) // 用种子源创建 Rand 实例
|
||||
|
||||
seed := uint64(r.Int())<<32 | uint64(r.Int())
|
||||
return NewRandomXS128WithSeed(seed)
|
||||
}
|
||||
|
||||
// NewRandomXS128WithSeed 用单个 uint64 种子创建生成器
|
||||
func NewRandomXS128WithSeed(seed uint64) *RandomXS128 {
|
||||
seed0 := murmurHash3(seed)
|
||||
seed1 := murmurHash3(seed0)
|
||||
return &RandomXS128{seed0: seed0, seed1: seed1}
|
||||
}
|
||||
|
||||
// NewRandomXS128WithTwoSeeds 用两个 uint64 种子直接设置状态
|
||||
func NewRandomXS128WithTwoSeeds(seed0, seed1 uint64) *RandomXS128 {
|
||||
return &RandomXS128{seed0: seed0, seed1: seed1}
|
||||
}
|
||||
|
||||
// NextLong 生成下一个 64 位随机整数
|
||||
func (r *RandomXS128) NextLong() uint64 {
|
||||
s1 := r.seed0
|
||||
s0 := r.seed1
|
||||
r.seed0 = s0
|
||||
s1 ^= s1 << 23
|
||||
r.seed1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
|
||||
return r.seed1 + s0
|
||||
}
|
||||
|
||||
// NextInt 生成下一个 32 位随机整数
|
||||
func (r *RandomXS128) NextInt() int {
|
||||
return int(r.NextLong() & 0xFFFFFFFF)
|
||||
}
|
||||
|
||||
// NextIntN 生成 [0, n) 范围内的随机整数
|
||||
func (r *RandomXS128) NextIntN(n int) int {
|
||||
if n <= 0 {
|
||||
panic("n must be positive")
|
||||
}
|
||||
for {
|
||||
bits := int(r.NextLong() >> 1)
|
||||
value := int(bits % n)
|
||||
if bits-value+n-1 >= 0 {
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NextLongN 生成 [0, n) 范围内的随机 64 位整数
|
||||
func (r *RandomXS128) NextLongN(n uint64) uint64 {
|
||||
if n <= 0 {
|
||||
panic("n must be positive")
|
||||
}
|
||||
for {
|
||||
bits := r.NextLong() >> 1
|
||||
value := bits % n
|
||||
if bits-value+(n-1) >= 0 {
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NextDouble 生成 [0.0, 1.0) 范围内的随机浮点数
|
||||
func (r *RandomXS128) NextDouble() float64 {
|
||||
return float64(r.NextLong()>>11) * normDouble
|
||||
}
|
||||
|
||||
// NextFloat 生成 [0.0, 1.0) 范围内的随机单精度浮点数
|
||||
func (r *RandomXS128) NextFloat() float32 {
|
||||
return float32(float64(r.NextLong()>>40) * normFloat)
|
||||
}
|
||||
|
||||
// NextBoolean 生成随机布尔值
|
||||
func (r *RandomXS128) NextBoolean() bool {
|
||||
return (r.NextLong() & 1) != 0
|
||||
}
|
||||
|
||||
// NextBytes 填充字节数组为随机字节
|
||||
func (r *RandomXS128) NextBytes(b []byte) {
|
||||
i := len(b)
|
||||
for i > 0 {
|
||||
n := i
|
||||
if n > 8 {
|
||||
n = 8
|
||||
}
|
||||
bits := r.NextLong()
|
||||
for j := 0; j < n; j++ {
|
||||
b[i-1-j] = byte(bits >> (8 * j))
|
||||
}
|
||||
i -= n
|
||||
}
|
||||
}
|
||||
|
||||
// SetSeed 用单个种子重置生成器状态
|
||||
func (r *RandomXS128) SetSeed(seed uint64) {
|
||||
seed0 := murmurHash3(seed)
|
||||
r.seed0 = seed0
|
||||
r.seed1 = murmurHash3(seed0)
|
||||
}
|
||||
|
||||
// SetState 直接设置内部状态
|
||||
func (r *RandomXS128) SetState(seed0, seed1 uint64) {
|
||||
r.seed0 = seed0
|
||||
r.seed1 = seed1
|
||||
}
|
||||
|
||||
// GetState 获取内部状态
|
||||
func (r *RandomXS128) GetState() (seed0, seed1 uint64) {
|
||||
return r.seed0, r.seed1
|
||||
}
|
||||
|
||||
// murmurHash3 用于种子扩展的哈希函数
|
||||
func murmurHash3(x uint64) uint64 {
|
||||
x ^= x >> 33
|
||||
x *= 0xff51afd7ed558ccd
|
||||
x ^= x >> 33
|
||||
x *= 0xc4ceb9fe1a85ec53
|
||||
x ^= x >> 33
|
||||
return x
|
||||
}
|
||||
Reference in New Issue
Block a user