diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2023-02-19 12:43:56 +0100 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2023-02-19 12:43:56 +0100 |
| commit | af087e34e7a60e75db349aa9b3bb671b2aa70bfc (patch) | |
| tree | ae30374a2db6e936acc1a14ac9ece8f2cf07ec63 /main.py | |
| parent | b4482a2566c649c3daf9210c5a32813c2790aa44 (diff) | |
refactor: Export strategy
Diffstat (limited to 'main.py')
| -rw-r--r-- | main.py | 42 |
1 files changed, 25 insertions, 17 deletions
@@ -31,6 +31,9 @@ class PlayerStatus: def create(player: Player) -> PlayerStatus: return PlayerStatus(player=player, elo=1000, total_games=0) + def update_elo(self, elo_update: int) -> PlayerStatus: + return PlayerStatus(player=self.player, elo=self.elo + elo_update, total_games=self.total_games + 1) + @dataclass(frozen=True) class Game: @@ -43,7 +46,23 @@ class Game: class GameEloChangeStrategy(Protocol): - pass + def proccess_game(self, game: Game, current_elo: dict[Player, int]) -> dict[Player, float]: + ... + +class SimpleEloChangeStrategy(GameEloChangeStrategy): + def proccess_game(self, game: Game, current_elo: dict[Player, int]) -> dict[Player, float]: + players_elo_updates = {player: 0.0 for player in game.scores} + + for player_1, score_1 in game.scores.items(): + for player_2, score_2 in game.scores.items(): + if player_1 != player_2: + expected_score = 1 / (1 + 10 ** ((current_elo[player_2] - current_elo[player_1]) / D)) + result = ( + 1.0 if score_1 > score_2 else 0.0 if score_1 < score_2 else 0.5 + ) + players_elo_updates[player_1] += K * (result - expected_score) + + return players_elo_updates class Ladder: @@ -54,22 +73,10 @@ class Ladder: return {player: player_status.elo for player, player_status in self.players.items()} def proccess_game(self, game: Game) -> dict[Player, float]: - players_elo_updates = {player: 0.0 for player in game.scores} - for player_1, score_1 in game.scores.items(): - for player_2, score_2 in game.scores.items(): - if player_1 != player_2: - expected_score = 1 / (1 + 10 ** ((self.players[player_2].elo - self.players[player_1].elo) / D)) - result = ( - 1.0 if score_1 > score_2 else 0.0 if score_1 < score_2 else 0.5 - ) - players_elo_updates[player_1] += K * (result - expected_score) + players_elo_updates = self.strategy.proccess_game(game, self.current_elo()) for player, elo_update in players_elo_updates.items(): - self.players[player] = PlayerStatus( - player=player, - elo=self.players[player].elo + int(elo_update), - total_games=self.players[player].total_games + 1, - ) + self.players[player] = self.players[player].update_elo(int(elo_update)) return players_elo_updates @@ -80,12 +87,13 @@ class Ladder: sorted(self.players.values(), key=lambda player: player.elo, reverse=True) ): print( - f"{rank+1}.\t{player.player:<20}: {player.elo:>4d} points, {player.total_games:>3d} games" + f"{rank+1}.\t{player.player.value:<20}: {player.elo:>4d} points, {player.total_games:>3d} games" ) ladder = Ladder() +ladder.strategy = SimpleEloChangeStrategy() D = 400 K = 32 @@ -177,6 +185,6 @@ for game in games: players_elo_updates = ladder.proccess_game(game) for (player, elo_update) in players_elo_updates.items(): - print(f"\t{player:<20}{int(elo_update):+}\t({ladder.players[player].elo:>4d})") + print(f"\t{player.value:<20}{int(elo_update):+}\t({ladder.players[player].elo:>4d})") ladder.print_current() |
