60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
package voiceroomredpacket
|
|
|
|
import (
|
|
"math/rand"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// splitRandomAmounts 按二倍均值法预拆拼手气金额。
|
|
func splitRandomAmounts(total int64, count int, seed int64) ([]int64, error) {
|
|
if total <= 0 {
|
|
return nil, NewAppError(http.StatusBadRequest, "voice_room_red_packet_amount_invalid", "totalAmount must be greater than 0")
|
|
}
|
|
if count <= 0 {
|
|
return nil, NewAppError(http.StatusBadRequest, "voice_room_red_packet_count_invalid", "totalCount must be greater than 0")
|
|
}
|
|
if total < int64(count) {
|
|
return nil, NewAppError(http.StatusBadRequest, "voice_room_red_packet_amount_invalid", "totalAmount must be greater than or equal to totalCount")
|
|
}
|
|
if seed == 0 {
|
|
seed = time.Now().UnixNano()
|
|
}
|
|
|
|
random := rand.New(rand.NewSource(seed))
|
|
amounts := make([]int64, 0, count)
|
|
remainAmount := total
|
|
remainCount := count
|
|
for remainCount > 1 {
|
|
avg := remainAmount / int64(remainCount)
|
|
maxAmount := avg * 2
|
|
keepForRest := int64(remainCount - 1)
|
|
if maxAmount > remainAmount-keepForRest {
|
|
maxAmount = remainAmount - keepForRest
|
|
}
|
|
if maxAmount < 1 {
|
|
maxAmount = 1
|
|
}
|
|
amount := int64(1)
|
|
if maxAmount > 1 {
|
|
amount = random.Int63n(maxAmount) + 1
|
|
}
|
|
amounts = append(amounts, amount)
|
|
remainAmount -= amount
|
|
remainCount--
|
|
}
|
|
amounts = append(amounts, remainAmount)
|
|
random.Shuffle(len(amounts), func(i, j int) {
|
|
amounts[i], amounts[j] = amounts[j], amounts[i]
|
|
})
|
|
return amounts, nil
|
|
}
|
|
|
|
func sumAmounts(values []int64) int64 {
|
|
var total int64
|
|
for _, value := range values {
|
|
total += value
|
|
}
|
|
return total
|
|
}
|