···
-
// Get all active player IDs
-
rows, err := DB.Query("SELECT id FROM submissions WHERE is_active = 1 AND status = 'completed'")
-
if err := rows.Scan(&id); err != nil {
-
playerIDs = append(playerIDs, id)
// For each player, collect ALL their match results and update once (proper rating period)
-
for _, playerID := range playerIDs {
-
// Get player's current rating
-
var rating, rd, volatility float64
-
"SELECT glicko_rating, glicko_rd, glicko_volatility FROM submissions WHERE id = ?",
-
).Scan(&rating, &rd, &volatility)
// Collect ALL match results for this player in this rating period
var results []Glicko2Result
···
-
// Get opponent's rating at the START of this rating period (not current)
-
var oppRating, oppRD float64
-
"SELECT glicko_rating, glicko_rd FROM submissions WHERE id = ?",
-
).Scan(&oppRating, &oppRD)
···
score := float64(myWins) / float64(totalGames)
results = append(results, Glicko2Result{
-
OpponentRating: oppRating,
···
// Update this player's rating based on ALL results at once (proper rating period)
-
player := Glicko2Player{Rating: rating, RD: rd, Volatility: volatility}
newPlayer := updateGlicko2(player, results)
···
+
// Snapshot all player ratings BEFORE any updates (critical for proper rating period)
+
initialRatings := make(map[int]Glicko2Player)
+
rows, err := DB.Query("SELECT id, glicko_rating, glicko_rd, glicko_volatility FROM submissions WHERE is_active = 1 AND status = 'completed'")
+
var rating, rd, volatility float64
+
if err := rows.Scan(&id, &rating, &rd, &volatility); err != nil {
+
initialRatings[id] = Glicko2Player{Rating: rating, RD: rd, Volatility: volatility}
// For each player, collect ALL their match results and update once (proper rating period)
+
for playerID, player := range initialRatings {
// Collect ALL match results for this player in this rating period
var results []Glicko2Result
···
+
// Get opponent's rating from initial snapshot (not from DB which may be updated)
+
opponent, ok := initialRatings[opponentID]
···
score := float64(myWins) / float64(totalGames)
results = append(results, Glicko2Result{
+
OpponentRating: opponent.Rating,
+
OpponentRD: opponent.RD,
···
// Update this player's rating based on ALL results at once (proper rating period)
newPlayer := updateGlicko2(player, results)