package main import ( "encoding/json" "fmt" "math" "math/rand" "sort" "time" ) type Prize struct { PlayerId int64 Weight int } func main() { //設置獎項名稱、權重等數組 var prizes = make([]*Prize, 0) for i := 0; i < 4; i++ { prize := &Prize{ PlayerId: int64(i) + 10000, Weight: (5 - i) * 10, } prizes = append(prizes, prize) } for _, v := range prizes { fmt.Println(v.PlayerId, v.Weight) } RandomDraw(prizes) } // 權重隨機抽獎 func RandomDraw(prizes []*Prize) int64 { //權重累加求和 var weightSum int for _, v := range prizes { weightSum += v.Weight } //生成一個權重隨機數,介於0-weightSum之間 rand.Seed(time.Now().UnixNano()) randomNum := rand.Intn(weightSum) //權重數組重組並排序 randomNumTmp := &Prize{PlayerId: -1, Weight: randomNum} concatWeightArr := make([]*Prize, 0) aa, _ := json.Marshal(prizes) _ = json.Unmarshal(aa, &concatWeightArr) fmt.Println("concatWeightArr:", concatWeightArr) concatWeightArr = append(concatWeightArr, randomNumTmp) //將隨機數加入權重數組 //將包含隨機數的新權重數組按從小到大(升序)排序 sort.Slice(concatWeightArr, func(i, j int) bool { return concatWeightArr[i].Weight < concatWeightArr[j].Weight }) sort.Slice(prizes, func(i, j int) bool { return prizes[i].Weight < prizes[j].Weight }) for _, v := range prizes { fmt.Println(*v) } //索引權重隨機數的數組下標 var randomNumIndex = -1 //索引隨機數在新權重數組中的位置 for p, v := range concatWeightArr { if v.Weight == randomNum { randomNumIndex = p } } randomNumIndexTmp := math.Min(float64(randomNumIndex), float64(len(prizes)-1)) //權重隨機數的下標不得超過獎項數組的長度-1,重新計算隨機數在獎項數組中的索引位置 randomNumIndex = int(randomNumIndexTmp) //取出對應獎項 res := prizes[randomNumIndex] //從獎項數組中取出本次抽獎結果 fmt.Println("本次抽獎結果:", res.PlayerId) return res.PlayerId }