@@ -17,36 +17,42 @@ class ModelEloProfile:
1717 rounds_played : int = 0
1818
1919
20- def expected_score (rating_a , rating_b ) :
20+ def expected_score (rating_a : float , rating_b : float ) -> float :
2121 return 1 / (1 + 10 ** ((rating_b - rating_a ) / 400 ))
2222
2323
24- def calculate_round_weight_linear (round_num , total_rounds ) :
24+ def calculate_round_weight_linear (round_num : int , total_rounds : int ) -> float :
2525 """Calculate linear weight for a round, with average weight = 1.0 across all rounds
2626
2727 Args:
28- round_num: Current round number (1-indexed)
28+ round_num: Current round number (1-indexed. the first round that we show in the viewer
29+ is 0, but it's not a real round, so not included here)
2930 total_rounds: Total number of rounds in the game
3031
3132 Returns:
3233 Weight value where early rounds have weight ~0.5 and late rounds have weight ~1.5
3334 """
35+ assert round_num >= 1
36+ assert round_num <= total_rounds
3437 # Linear: weight = 0.5 + (round_num / total_rounds)
3538 # This gives range [0.5, 1.5] with average = 1.0
3639 return 0.5 + (round_num / total_rounds )
3740
3841
39- def calculate_round_weight_exponential (round_num , total_rounds , alpha = 2.0 ):
42+ def calculate_round_weight_exponential (round_num : int , total_rounds : int , alpha : float = 2.0 ) -> float :
4043 """Calculate exponential weight for a round, with average weight = 1.0 across all rounds
4144
4245 Args:
43- round_num: Current round number (1-indexed)
46+ round_num: Current round number (1-indexed. the first round that we show in the viewer
47+ is 0, but it's not a real round, so not included here)
4448 total_rounds: Total number of rounds in the game
4549 alpha: Exponential factor (default 2.0 for quadratic weighting)
4650
4751 Returns:
4852 Weight value with exponential progression favoring later rounds
4953 """
54+ assert round_num >= 1
55+ assert round_num <= total_rounds
5056 # Raw weight (exponential)
5157 raw_weight = (round_num / total_rounds ) ** alpha
5258
@@ -57,7 +63,7 @@ def calculate_round_weight_exponential(round_num, total_rounds, alpha=2.0):
5763 return raw_weight * norm_factor
5864
5965
60- def update_profiles (prof_and_score , round_weight , k_factor ) :
66+ def update_profiles (prof_and_score : list [ tuple [ ModelEloProfile , float ]], round_weight : float , k_factor : float ) -> None :
6167 """Update ELO profiles for two players based on their scores and round weight
6268
6369 Args:
@@ -92,7 +98,7 @@ def update_profiles(prof_and_score, round_weight, k_factor):
9298 p2_prof .rating -= rating_change # Zero-sum property
9399
94100
95- def main (log_dir : Path , k_factor : int , starting_elo : int , weighting_function : str , alpha : float ):
101+ def main (log_dir : Path , k_factor : float , starting_elo : float , weighting_function : str , alpha : float ) -> None :
96102 print (f"Calculating weighted ELO ratings from logs in { log_dir } ..." )
97103 print (f"Using K_FACTOR={ k_factor } , STARTING_ELO={ starting_elo } " )
98104 print (
@@ -196,9 +202,9 @@ def main(log_dir: Path, k_factor: int, starting_elo: int, weighting_function: st
196202if __name__ == "__main__" :
197203 parser = argparse .ArgumentParser (description = "Calculate weighted ELO ratings with configurable weighting functions" )
198204 parser .add_argument ("-d" , "--log_dir" , type = Path , help = "Path to game logs (Default: logs/)" , default = LOCAL_LOG_DIR )
199- parser .add_argument ("-k" , "--k_factor" , type = int , help = "K-Factor for ELO calculation (Default: 32)" , default = 32 )
205+ parser .add_argument ("-k" , "--k_factor" , type = float , help = "K-Factor for ELO calculation (Default: 32)" , default = 32 )
200206 parser .add_argument (
201- "-s" , "--starting_elo" , type = int , help = "Starting ELO for new players (Default: 1200)" , default = 1200
207+ "-s" , "--starting_elo" , type = float , help = "Starting ELO for new players (Default: 1200)" , default = 1200
202208 )
203209 parser .add_argument (
204210 "-w" ,
0 commit comments