-
Notifications
You must be signed in to change notification settings - Fork 0
/
targets.go
128 lines (111 loc) · 2.71 KB
/
targets.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package neptune
import (
"bytes"
"encoding/csv"
"log"
"math/rand"
"reflect"
"sort"
"strconv"
"strings"
"time"
_ "embed"
)
type TargetType int
const TARGET_REFRESH TargetType = 0
type TargetInfo struct {
Code string
Name string
Duration time.Duration
Weight float64
CostGain []float64
}
var (
targets []TargetInfo
targetWeights []float64
TargetHeaders = strings.Split("code,duration,rate,cost-Coins,cost-Cube,gain-BP-SSR,gain-BP-UR,gain-EquipBP-UR,gain-Chips", ",")
)
func (t TargetType) Code() string {
return targets[t].Code
}
func (t TargetType) String() string {
info := targets[t]
return info.Code
}
func (t TargetType) Name() string {
return targets[t].Name
}
func (t TargetType) Duration() time.Duration {
return targets[t].Duration
}
func (t TargetType) CostGain() []float64 {
return targets[t].CostGain
}
func toFloat(text string) float64 {
text = strings.Trim(text, " ")
ret, err := strconv.ParseFloat(text, 64)
if err != nil {
panic(err)
}
return ret
}
func toFloats(items []string) []float64 {
nums := make([]float64, len(items))
for i, text := range items {
nums[i] = toFloat(text)
}
return nums
}
//go:embed data.csv
var defaultData []byte
func InitDefaultTargets() {
targets = make([]TargetInfo, 0)
csvLines, err := csv.NewReader(bytes.NewBuffer(defaultData)).ReadAll()
if err != nil {
panic(err)
}
if !reflect.DeepEqual(TargetHeaders, csvLines[0]) {
log.Println(TargetHeaders, csvLines[0])
panic("输入数据不符合需求!")
}
InitTargets(csvLines[1:])
}
func InitTargets(rows [][]string) {
nCols := len(TargetHeaders)
targets = append(targets, TargetInfo{"SKIP", "刷新", 0, 0, make([]float64, nCols-3)})
for _, line := range rows {
if len(line) < nCols {
panic("长度不匹配!")
}
targets = append(targets,
TargetInfo{
Code: line[0],
Duration: time.Duration(toFloat(line[1])) * time.Hour,
Weight: toFloat(line[2]),
CostGain: toFloats(line[3:nCols]),
})
}
targetWeights = make([]float64, len(targets))
cumsum := float64(0)
for i := range targets {
cumsum += targets[i].Weight
targetWeights[i] = cumsum
}
for i := range targets {
targetWeights[i] = targetWeights[i] / cumsum
}
log.Printf("Inited: %v\n", targets)
}
func RandomSample(n int) []TargetType {
// number of random draws
var val float64
indices := make([]TargetType, n)
// loop through indices and draw random values
for i := range indices {
// multiply the sample with the largest CDF value; easier than normalizing to [0,1)
val = rand.Float64()
// Search returns the smallest index i such that cdf[i] > val
indices[i] = TargetType(sort.Search(len(targetWeights), func(i int) bool { return targetWeights[i] > val }))
}
return indices
}