mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-14 03:52:14 +00:00
feat: add ranked season rollover policy
This commit is contained in:
+57
-26
@@ -7,29 +7,29 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
MaxPlacementRTT = 100.0
|
||||
MaxPlacementRTT = 100.0
|
||||
MinRatingTolerance = 100.0
|
||||
MaxRatingTolerance = 400.0
|
||||
RatingWidenStep = 25.0
|
||||
RatingWidenPeriod = 30.0
|
||||
RatingWidenStep = 25.0
|
||||
RatingWidenPeriod = 30.0
|
||||
)
|
||||
|
||||
// Candidate is the server-side projection of a verified, live queue ticket.
|
||||
// RTT values come from backend probes, never from the client request body.
|
||||
type Candidate struct {
|
||||
TicketID string
|
||||
PlayerID string
|
||||
Rating float64
|
||||
EnqueuedAt time.Time
|
||||
TicketID string
|
||||
PlayerID string
|
||||
Rating float64
|
||||
EnqueuedAt time.Time
|
||||
PredictedRTT map[string]float64
|
||||
}
|
||||
|
||||
type Selection struct {
|
||||
Players []Candidate
|
||||
Region string
|
||||
WorstRTT float64
|
||||
TotalRTT float64
|
||||
RatingRange float64
|
||||
Players []Candidate
|
||||
Region string
|
||||
WorstRTT float64
|
||||
TotalRTT float64
|
||||
RatingRange float64
|
||||
TotalWaitSeconds float64
|
||||
}
|
||||
|
||||
@@ -153,38 +153,69 @@ func scoreSelection(players []Candidate, now time.Time) (Selection, bool) {
|
||||
wait := 0.0
|
||||
for _, player := range players {
|
||||
rtt := player.PredictedRTT[region]
|
||||
if rtt > worst { worst = rtt }
|
||||
if rtt > worst {
|
||||
worst = rtt
|
||||
}
|
||||
total += rtt
|
||||
if player.Rating < minRating { minRating = player.Rating }
|
||||
if player.Rating > maxRating { maxRating = player.Rating }
|
||||
if seconds := now.Sub(player.EnqueuedAt).Seconds(); seconds > 0 { wait += seconds }
|
||||
if player.Rating < minRating {
|
||||
minRating = player.Rating
|
||||
}
|
||||
if player.Rating > maxRating {
|
||||
maxRating = player.Rating
|
||||
}
|
||||
if seconds := now.Sub(player.EnqueuedAt).Seconds(); seconds > 0 {
|
||||
wait += seconds
|
||||
}
|
||||
}
|
||||
candidate := Selection{Players: append([]Candidate(nil), players...), Region: region, WorstRTT: worst, TotalRTT: total, RatingRange: maxRating - minRating, TotalWaitSeconds: wait}
|
||||
if best.Players == nil || betterSelection(candidate, best) {
|
||||
best = candidate
|
||||
}
|
||||
candidate := Selection{Players: append([]Candidate(nil), players...), Region: region, WorstRTT: worst, TotalRTT: total, RatingRange: maxRating-minRating, TotalWaitSeconds: wait}
|
||||
if best.Players == nil || betterSelection(candidate, best) { best = candidate }
|
||||
}
|
||||
return best, true
|
||||
}
|
||||
|
||||
func betterSelection(a, b Selection) bool {
|
||||
if a.WorstRTT != b.WorstRTT { return a.WorstRTT < b.WorstRTT }
|
||||
if a.TotalRTT != b.TotalRTT { return a.TotalRTT < b.TotalRTT }
|
||||
if a.RatingRange != b.RatingRange { return a.RatingRange < b.RatingRange }
|
||||
if a.TotalWaitSeconds != b.TotalWaitSeconds { return a.TotalWaitSeconds > b.TotalWaitSeconds }
|
||||
if a.WorstRTT != b.WorstRTT {
|
||||
return a.WorstRTT < b.WorstRTT
|
||||
}
|
||||
if a.TotalRTT != b.TotalRTT {
|
||||
return a.TotalRTT < b.TotalRTT
|
||||
}
|
||||
if a.RatingRange != b.RatingRange {
|
||||
return a.RatingRange < b.RatingRange
|
||||
}
|
||||
if a.TotalWaitSeconds != b.TotalWaitSeconds {
|
||||
return a.TotalWaitSeconds > b.TotalWaitSeconds
|
||||
}
|
||||
return ticketIDs(a.Players) < ticketIDs(b.Players)
|
||||
}
|
||||
|
||||
func containsTicket(players []Candidate, ticketID string) bool {
|
||||
for _, player := range players { if player.TicketID == ticketID { return true } }
|
||||
for _, player := range players {
|
||||
if player.TicketID == ticketID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ticketIDs(players []Candidate) string {
|
||||
ids := make([]string, 0, len(players))
|
||||
for _, player := range players { ids = append(ids, player.TicketID) }
|
||||
for _, player := range players {
|
||||
ids = append(ids, player.TicketID)
|
||||
}
|
||||
sort.Strings(ids)
|
||||
result := ""
|
||||
for _, id := range ids { result += id + "\x00" }
|
||||
for _, id := range ids {
|
||||
result += id + "\x00"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func abs(value float64) float64 { if value < 0 { return -value }; return value }
|
||||
func abs(value float64) float64 {
|
||||
if value < 0 {
|
||||
return -value
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user