a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: fix rating periods

+12 -26
+12 -26
internal/storage/database.go
··· 749 749 return err 750 750 } 751 751 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'") 755 755 if err != nil { 756 756 return err 757 757 } 758 758 for rows.Next() { 759 759 var id int 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 { 761 762 return err 762 763 } 763 - playerIDs = append(playerIDs, id) 764 + initialRatings[id] = Glicko2Player{Rating: rating, RD: rd, Volatility: volatility} 764 765 } 765 766 rows.Close() 766 767 767 768 // 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 = ?", 773 - playerID, 774 - ).Scan(&rating, &rd, &volatility) 775 - if err != nil { 776 - continue 777 - } 778 - 769 + for playerID, player := range initialRatings { 779 770 // Collect ALL match results for this player in this rating period 780 771 var results []Glicko2Result 781 772 ··· 799 790 continue 800 791 } 801 792 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 = ?", 806 - opponentID, 807 - ).Scan(&oppRating, &oppRD) 808 - if err != nil { 793 + // Get opponent's rating from initial snapshot (not from DB which may be updated) 794 + opponent, ok := initialRatings[opponentID] 795 + if !ok { 809 796 continue 810 797 } 811 798 ··· 813 800 score := float64(myWins) / float64(totalGames) 814 801 815 802 results = append(results, Glicko2Result{ 816 - OpponentRating: oppRating, 817 - OpponentRD: oppRD, 803 + OpponentRating: opponent.Rating, 804 + OpponentRD: opponent.RD, 818 805 Score: score, 819 806 }) 820 807 } ··· 822 809 823 810 // Update this player's rating based on ALL results at once (proper rating period) 824 811 if len(results) > 0 { 825 - player := Glicko2Player{Rating: rating, RD: rd, Volatility: volatility} 826 812 newPlayer := updateGlicko2(player, results) 827 813 828 814 DB.Exec(