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