Files
bl/modules/config/model/glow.go
xinian f6aa0c3339
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
feat: 重构任务奖励系统并增加宠物技能和皮肤奖励
将任务奖励逻辑重构到单独的文件中,增加对宠物技能和皮肤奖励的支持,优化任务完成处理流程
2026-04-11 19:25:59 +08:00

536 lines
18 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"math"
"math/rand"
"time"
"unsafe"
)
// ---------------- 结构体定义(保持不变) ----------------
type MonsterMatrix struct {
Matrix [4][5]float32 `json:"matrix"` // 4×5颜色矩阵唯一输入输出对象
Hash string `json:"hash"` // 矩阵唯一哈希(基于矩阵数据生成)
Type string `json:"type"` // random(父母矩阵)/merged(后代矩阵)
Seed int64 `json:"seed"` // 随机种子父母矩阵有效后代矩阵为0
Parents [2]string `json:"parents"` // 父母矩阵哈希(后代矩阵填写,父母矩阵为空)
Weight [2]float32 `json:"weight"` // 融合权重(后代矩阵有效,父母矩阵为[0,0]
}
func (m MonsterMatrix) Get() [20]float32 {
oneDArr := *(*[20]float32)(unsafe.Pointer(&m.Matrix))
return oneDArr
}
type SplitResult struct {
Father MonsterMatrix `json:"father"` // 拆分出的父亲矩阵(纯矩阵输出)
Mother MonsterMatrix `json:"mother"` // 拆分出的母亲矩阵(纯矩阵输出)
InputOffspring MonsterMatrix `json:"input_offspring"` // 输入的后代矩阵(纯矩阵输入,随机/自定义)
ProcessedOffspring MonsterMatrix `json:"processed_offspring"` // 预处理后的合规后代矩阵
SplitWeight [2]float32 `json:"split_weight"` // 实际拆分权重默认0.5:0.5平均权重)
IsReversible bool `json:"is_reversible"` // 父母融合=预处理后代矩阵确保为true
Hash string `json:"hash"` // 拆分结果唯一哈希
}
// ---------------- 配置常量(贴合示例参数范围,微调界限) ----------------
const (
FloatPrecision = 6 // 浮点精度保留小数位
MaxCalibrateIter = 300 // 最大校准迭代次数
ErrorThreshold = 1e-3 // 融合误差阈值
MatrixMinVal = -1.0 // 贴合示例前3行前3列参数大多在[-1,2]之间
MatrixMaxVal = 2.0 // 贴合示例:避免参数过度偏离
BrightnessMinVal = -30.0 // 贴合示例:亮度大多在[-30, 30]之间,避免过低亮度
BrightnessMaxVal = 60.0 // 适度提高最大亮度,减少暗色
)
// ---------------- 通用工具函数(保持不变) ----------------
func newIdentityMatrix() [4][5]float32 {
return [4][5]float32{
{1, 0, 0, 0, 0},
{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
}
}
func clampFloat32(val, min, max float32) float32 {
if val < min {
return min
}
if val > max {
return max
}
return val
}
func roundFloat32(val float32, decimals int) float32 {
shift := float32(math.Pow10(decimals))
return float32(math.Round(float64(val*shift))) / shift
}
func randomFloat32Range(r *rand.Rand, min, max float32) float32 {
return min + float32(r.Float64())*(max-min)
}
// 预处理矩阵:自动修正越界参数,确保合规
func ProcessOffspringMatrix(mat [4][5]float32) [4][5]float32 {
var processedMat [4][5]float32
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
// 透明通道保持不变
if i == 3 {
processedMat[i][j] = mat[i][j]
continue
}
// 亮度列单独钳制
if j == 4 {
processedMat[i][j] = clampFloat32(roundFloat32(mat[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
} else {
processedMat[i][j] = clampFloat32(roundFloat32(mat[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
}
}
}
return processedMat
}
// hashString 计算字符串哈希值(保持高熵种子逻辑)
func hashString(s string) uint64 {
h := sha256.New()
h.Write([]byte(s))
sum := h.Sum(nil)
return uint64(sum[0])<<56 | uint64(sum[1])<<48 | uint64(sum[2])<<40 | uint64(sum[3])<<32 |
uint64(sum[4])<<24 | uint64(sum[5])<<16 | uint64(sum[6])<<8 | uint64(sum[7])
}
// ---------------- 矩阵核心操作函数(关键:调整随机参数范围,贴合你的示例) ----------------
func calculateMatrixHash(mm MonsterMatrix) string {
h := sha256.New()
for _, row := range mm.Matrix {
for _, val := range row {
h.Write([]byte(fmt.Sprintf("%.6f", roundFloat32(val, FloatPrecision))))
}
}
if mm.Type == "merged" {
h.Write([]byte(mm.Parents[0]))
h.Write([]byte(mm.Parents[1]))
h.Write([]byte(fmt.Sprintf("%.6f", mm.Weight[0])))
h.Write([]byte(fmt.Sprintf("%.6f", mm.Weight[1])))
}
return hex.EncodeToString(h.Sum(nil))
}
// GenerateRandomParentMatrix 生成色域更大的父矩阵,同时抬高黑场避免整只精灵发黑
func GenerateRandomParentMatrix() MonsterMatrix {
salt := "player-matrix-random-seed"
now := time.Now().UnixNano()
randomNum := rand.Int63()
seed := now ^ randomNum ^ int64(hashString(salt))
r := rand.New(rand.NewSource(seed))
matrix := newIdentityMatrix()
dominant := r.Intn(3)
accent := (dominant + 1 + r.Intn(2)) % 3
baseLift := randomFloat32Range(r, 10, 24)
for row := 0; row < 3; row++ {
for col := 0; col < 3; col++ {
value := randomFloat32Range(r, -0.22, 0.22)
if row == col {
value = randomFloat32Range(r, 0.8, 1.45)
}
if row == dominant && col == dominant {
value += randomFloat32Range(r, 0.35, 0.7)
}
if row == accent && col == accent {
value += randomFloat32Range(r, 0.1, 0.3)
}
if row == dominant && col != row {
value += randomFloat32Range(r, -0.12, 0.28)
}
matrix[row][col] = clampFloat32(roundFloat32(value, FloatPrecision), MatrixMinVal, MatrixMaxVal)
}
}
matrix[0][4] = baseLift + randomFloat32Range(r, -5, 10)
matrix[1][4] = baseLift + randomFloat32Range(r, -5, 10)
matrix[2][4] = baseLift + randomFloat32Range(r, -5, 10)
matrix[dominant][4] += randomFloat32Range(r, 8, 18)
matrix[accent][4] += randomFloat32Range(r, 2, 8)
avgBrightness := (matrix[0][4] + matrix[1][4] + matrix[2][4]) / 3
if avgBrightness < 12 {
lift := 12 - avgBrightness + randomFloat32Range(r, 0, 6)
for row := 0; row < 3; row++ {
matrix[row][4] += lift
}
}
if matrix[dominant][4] < 16 {
matrix[dominant][4] = 16 + randomFloat32Range(r, 0, 10)
}
for row := 0; row < 3; row++ {
for col := 0; col < 3; col++ {
matrix[row][col] = clampFloat32(roundFloat32(matrix[row][col], FloatPrecision), MatrixMinVal, MatrixMaxVal)
}
matrix[row][4] = clampFloat32(roundFloat32(matrix[row][4], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
}
parent := MonsterMatrix{
Matrix: matrix,
Hash: "",
Type: "random",
Seed: seed,
Parents: [2]string{"", ""},
Weight: [2]float32{0, 0},
}
parent.Hash = calculateMatrixHash(parent)
return parent
}
// GenerateRandomOffspringMatrix 保持不变(依赖调整后的父矩阵,参数分布更贴合示例)
func GenerateRandomOffspringMatrix() MonsterMatrix {
father := GenerateRandomParentMatrix()
mother := GenerateRandomParentMatrix()
weight := [2]float32{0.5, 0.5}
var offspringMat [4][5]float32
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if i == 3 {
offspringMat[i][j] = father.Matrix[i][j]
continue
}
mergedVal := roundFloat32(weight[0]*father.Matrix[i][j]+weight[1]*mother.Matrix[i][j], FloatPrecision)
if j == 4 {
offspringMat[i][j] = clampFloat32(mergedVal, BrightnessMinVal, BrightnessMaxVal)
} else {
offspringMat[i][j] = clampFloat32(mergedVal, MatrixMinVal, MatrixMaxVal)
}
}
}
offspring := MonsterMatrix{
Matrix: offspringMat,
Hash: "",
Type: "merged",
Seed: 0,
Parents: [2]string{father.Hash, mother.Hash},
Weight: weight,
}
offspring.Hash = calculateMatrixHash(offspring)
return offspring
}
// MergeParentMatrices 保持不变
func MergeParentMatrices(father, mother MonsterMatrix, weight [2]float32) MonsterMatrix {
w1, w2 := weight[0], weight[1]
if w1 <= 0 || w2 <= 0 || math.Abs(float64(w1+w2)-1) > ErrorThreshold {
w1, w2 = 0.5, 0.5
}
var mergedMat [4][5]float32
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if i == 3 {
mergedMat[i][j] = father.Matrix[i][j]
continue
}
mergedVal := roundFloat32(w1*father.Matrix[i][j]+w2*mother.Matrix[i][j], FloatPrecision)
if j == 4 {
mergedMat[i][j] = clampFloat32(mergedVal, BrightnessMinVal, BrightnessMaxVal)
} else {
mergedMat[i][j] = clampFloat32(mergedVal, MatrixMinVal, MatrixMaxVal)
}
}
}
offspring := MonsterMatrix{
Matrix: mergedMat,
Hash: "",
Type: "merged",
Seed: 0,
Parents: [2]string{father.Hash, mother.Hash},
Weight: [2]float32{w1, w2},
}
offspring.Hash = calculateMatrixHash(offspring)
return offspring
}
// IterativeCalibrateParentMatrices 保持不变
func IterativeCalibrateParentMatrices(father, mother MonsterMatrix, targetOffspring MonsterMatrix, weight [2]float32) (calibFather, calibMother MonsterMatrix) {
w1, w2 := weight[0], weight[1]
calibFather, calibMother = father, mother
iter := 0
totalError := 1.0
for iter < MaxCalibrateIter && totalError > ErrorThreshold {
totalError = 0.0
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if i == 3 {
continue
}
currentMerged := w1*calibFather.Matrix[i][j] + w2*calibMother.Matrix[i][j]
delta := targetOffspring.Matrix[i][j] - currentMerged
totalError += math.Abs(float64(delta))
damping := 0.95
calibFather.Matrix[i][j] += delta * w1 * float32(damping)
calibMother.Matrix[i][j] += delta * w2 * float32(damping)
// 实时钳制(贴合新的参数范围)
if j == 4 {
calibFather.Matrix[i][j] = clampFloat32(roundFloat32(calibFather.Matrix[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
calibMother.Matrix[i][j] = clampFloat32(roundFloat32(calibMother.Matrix[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
} else {
calibFather.Matrix[i][j] = clampFloat32(roundFloat32(calibFather.Matrix[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
calibMother.Matrix[i][j] = clampFloat32(roundFloat32(calibMother.Matrix[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
}
}
}
iter++
}
calibFather.Hash = calculateMatrixHash(calibFather)
calibMother.Hash = calculateMatrixHash(calibMother)
return
}
// ---------------- 核心拆分函数(保持不变) ----------------
func SplitOffspringMatrix(inputOffspring MonsterMatrix, optionalWeights ...[2]float32) (SplitResult, error) {
// 1. 确定拆分权重
var splitWeight [2]float32
if len(optionalWeights) > 0 {
splitWeight = optionalWeights[0]
} else {
splitWeight = [2]float32{0.5, 0.5}
}
w1, w2 := splitWeight[0], splitWeight[1]
if w1 <= 0 || w2 <= 0 || math.Abs(float64(w1+w2)-1) > ErrorThreshold {
splitWeight = [2]float32{0.5, 0.5}
w1, w2 = 0.5, 0.5
}
// 2. 预处理输入矩阵,修正越界参数
processedMat := ProcessOffspringMatrix(inputOffspring.Matrix)
processedOffspring := MonsterMatrix{
Matrix: processedMat,
Hash: calculateMatrixHash(MonsterMatrix{Matrix: processedMat, Type: "merged"}),
Type: "merged",
Seed: 0,
Parents: inputOffspring.Parents,
Weight: splitWeight,
}
// 3. 补全输入矩阵信息
if inputOffspring.Hash == "" {
inputOffspring.Hash = calculateMatrixHash(inputOffspring)
}
if inputOffspring.Type != "merged" {
inputOffspring.Type = "merged"
}
// 4. 初始化父母矩阵
var initialFather, initialMother MonsterMatrix
initialFather.Type = "random"
initialMother.Type = "random"
initialFather.Seed = time.Now().UnixNano()
initialMother.Seed = time.Now().UnixNano()
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if i == 3 {
initialFather.Matrix[i][j] = processedMat[i][j]
initialMother.Matrix[i][j] = processedMat[i][j]
continue
}
// 初始父亲矩阵:基于预处理后代矩阵推导
initialFather.Matrix[i][j] = clampFloat32(roundFloat32(processedMat[i][j]*w1, FloatPrecision), MatrixMinVal, MatrixMaxVal)
if j == 4 {
initialFather.Matrix[i][j] = clampFloat32(roundFloat32(processedMat[i][j]*w1, FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
}
// 反推母亲矩阵
motherVal := (processedMat[i][j] - w1*initialFather.Matrix[i][j]) / w2
if j == 4 {
initialMother.Matrix[i][j] = clampFloat32(roundFloat32(motherVal, FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
} else {
initialMother.Matrix[i][j] = clampFloat32(roundFloat32(motherVal, FloatPrecision), MatrixMinVal, MatrixMaxVal)
}
}
}
initialFather.Hash = calculateMatrixHash(initialFather)
initialMother.Hash = calculateMatrixHash(initialMother)
// 5. 迭代校准
calibFather, calibMother := IterativeCalibrateParentMatrices(initialFather, initialMother, processedOffspring, splitWeight)
// 6. 验证可逆性(基于预处理后的合规矩阵)
mergedOffspring := MergeParentMatrices(calibFather, calibMother, splitWeight)
isReversible := isMatrixEqualWithTolerance(mergedOffspring.Matrix, processedMat, ErrorThreshold)
// 7. 组装结果
splitResult := SplitResult{
Father: calibFather,
Mother: calibMother,
InputOffspring: inputOffspring,
ProcessedOffspring: processedOffspring,
SplitWeight: splitWeight,
IsReversible: isReversible,
Hash: "",
}
splitResult.Hash = calculateSplitResultHash(splitResult)
return splitResult, nil
}
// ---------------- 辅助验证函数(保持不变) ----------------
func isMatrixEqualWithTolerance(mat1, mat2 [4][5]float32, tolerance float64) bool {
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
if math.Abs(float64(mat1[i][j]-mat2[i][j])) > tolerance {
return false
}
}
}
return true
}
func calculateSplitResultHash(sr SplitResult) string {
h := sha256.New()
h.Write([]byte(sr.Father.Hash))
h.Write([]byte(sr.Mother.Hash))
h.Write([]byte(sr.InputOffspring.Hash))
h.Write([]byte(fmt.Sprintf("%.6f%.6f", sr.SplitWeight[0], sr.SplitWeight[1])))
h.Write([]byte(fmt.Sprintf("%t", sr.IsReversible)))
return hex.EncodeToString(h.Sum(nil))
}
// ---------------- 测试函数(新增:输出扁平化矩阵,贴合你的前后端需求) ----------------
func TestPureMatrixSplit() {
fmt.Println("==================== 模式1拆分随机生成的后代矩阵 ====================")
randomOffspring := GenerateRandomOffspringMatrix()
// 输出扁平化矩阵+哈希(贴合你的前后端格式)
var flat []string
for _, row := range randomOffspring.Matrix {
for _, val := range row {
flat = append(flat, fmt.Sprintf("%.3f", val))
}
}
fmt.Printf("扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", flat), randomOffspring.Hash[:8])
fmt.Println("随机后代矩阵参数:")
printMatrix(randomOffspring.Matrix)
splitResult1, err := SplitOffspringMatrix(randomOffspring)
if err != nil {
fmt.Printf("随机后代矩阵拆分失败:%v\n", err)
return
}
fmt.Printf("\n拆分权重%.2f : %.2f\n", splitResult1.SplitWeight[0], splitResult1.SplitWeight[1])
fmt.Printf("父亲矩阵哈希:%s\n", splitResult1.Father.Hash[:8])
fmt.Println("父亲矩阵参数:")
printMatrix(splitResult1.Father.Matrix)
fmt.Printf("\n母亲矩阵哈希%s\n", splitResult1.Mother.Hash[:8])
fmt.Println("母亲矩阵参数:")
printMatrix(splitResult1.Mother.Matrix)
fmt.Printf("\n是否可逆父母融合=预处理随机后代):%t\n\n", splitResult1.IsReversible)
fmt.Println("==================== 模式2拆分用户指定的越界自定义矩阵 ====================")
// 用户原始越界自定义矩阵
customMat := [4][5]float32{
{0.110, -0.336, 1.956, 0.000, 30.160},
{0.795, 0.933, -0.829, 0.000, 30.160},
{-1.209, 2.808, 0.363, 0.000, 30.160},
{0.000, 0.000, 0.000, 1.000, 0.000},
}
customOffspring := MonsterMatrix{
Matrix: customMat,
Type: "merged",
}
// 扁平化输出自定义矩阵
var customFlat []string
for _, row := range customMat {
for _, val := range row {
customFlat = append(customFlat, fmt.Sprintf("%.3f", val))
}
}
fmt.Printf("原始自定义扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", customFlat), calculateMatrixHash(customOffspring)[:8])
fmt.Println("原始自定义矩阵参数:")
printMatrix(customMat)
splitResult2, err := SplitOffspringMatrix(customOffspring)
if err != nil {
fmt.Printf("自定义矩阵拆分失败:%v\n", err)
return
}
fmt.Printf("\n拆分权重%.2f : %.2f\n", splitResult2.SplitWeight[0], splitResult2.SplitWeight[1])
fmt.Printf("预处理后合规矩阵参数:\n")
printMatrix(splitResult2.ProcessedOffspring.Matrix)
// 扁平化输出预处理矩阵
var processedFlat []string
for _, row := range splitResult2.ProcessedOffspring.Matrix {
for _, val := range row {
processedFlat = append(processedFlat, fmt.Sprintf("%.3f", val))
}
}
fmt.Printf("预处理后扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", processedFlat), splitResult2.ProcessedOffspring.Hash[:8])
fmt.Printf("\n父亲矩阵哈希%s\n", splitResult2.Father.Hash[:8])
fmt.Println("父亲矩阵参数:")
printMatrix(splitResult2.Father.Matrix)
fmt.Printf("\n母亲矩阵哈希%s\n", splitResult2.Mother.Hash[:8])
fmt.Println("母亲矩阵参数:")
printMatrix(splitResult2.Mother.Matrix)
fmt.Printf("\n是否可逆父母融合=预处理合规矩阵):%t\n", splitResult2.IsReversible)
// 验证融合一致性
mergedCustom := MergeParentMatrices(splitResult2.Father, splitResult2.Mother, splitResult2.SplitWeight)
fmt.Printf("融合矩阵与预处理矩阵一致性:%t\n", isMatrixEqualWithTolerance(mergedCustom.Matrix, splitResult2.ProcessedOffspring.Matrix, ErrorThreshold))
fmt.Printf("融合矩阵与原始自定义矩阵一致性:%t原始矩阵存在越界参数此为正常现象\n", isMatrixEqualWithTolerance(mergedCustom.Matrix, customMat, ErrorThreshold))
}
// 批量生成扁平化矩阵(方便前后端直接使用)
func GenerateBatchFlatMatrices(batchSize int) []string {
var result []string
for i := 0; i < batchSize; i++ {
mat := GenerateRandomOffspringMatrix()
var flat []string
for _, row := range mat.Matrix {
for _, val := range row {
flat = append(flat, fmt.Sprintf("%.3f", val))
}
}
result = append(result, fmt.Sprintf("%s | 哈希前缀: %s", fmt.Sprintf("%s", flat), mat.Hash[:8]))
}
return result
}
func printMatrix(mat [4][5]float32) {
for _, row := range mat {
fmt.Printf("%.3f, %.3f, %.3f, %.3f, %.3f\n", row[0], row[1], row[2], row[3], row[4])
}
}
// 主函数:可单独运行测试或批量生成
func TestPureMatrixSplit1() {
rand.Seed(time.Now().UnixNano())
// 测试拆分功能
// TestPureMatrixSplit()
// 批量生成5个扁平化矩阵贴合你的需求
fmt.Println("\n==================== 批量生成扁平化矩阵(前后端可用) ====================")
batchMatrices := GenerateBatchFlatMatrices(5)
for idx, matStr := range batchMatrices {
fmt.Printf("矩阵%d%s\n", idx+1, matStr)
}
}