aboutsummaryrefslogtreecommitdiff
path: root/ladder.py
blob: 7351798eae0af161bd44e455dc57760365e606aa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime

from game import Game
from player import Player
from strategy import GameEloChangeStrategy


@dataclass(frozen=True)
class PlayerStatus:
    player: Player
    elo: int
    total_games: int

    @staticmethod
    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,
        )


class Ladder:
    strategy: GameEloChangeStrategy
    players: dict[Player, PlayerStatus] = {
        player: PlayerStatus.create(player) for player in Player
    }

    def current_elo(self) -> dict[Player, int]:
        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 = self.strategy.proccess_game(game, self.current_elo())

        for player, elo_update in players_elo_updates.items():
            self.players[player] = self.players[player].update_elo(int(elo_update))

        return players_elo_updates

    def print_current(self):
        print(f"Ladder ({datetime.now().strftime('%d/%m/%Y %H:%M')}):")
        print("=" * 30)
        for rank, player in enumerate(
            sorted(self.players.values(), key=lambda player: player.elo, reverse=True),
        ):
            print(
                f"{rank+1}.\t{player.player.value:<20}: {player.elo:>4d} points, {player.total_games:>3d} games",
            )