예제 #1
0
 def test_can_get_the_default_score_from_a_single_match(self):
     # given a match report
     filename = "tests/logs/L0409001.log"
     match_report = LogParser.from_filename(filename).get_match_report()
     # when given to the stats extractor
     scorer = DefaultScorer()
     stats = MatchReportCollection([match_report])
     # we can know the best player
     player = Player("Mcd.", 538382878)
     assert stats.get_best_player(scorer)[0] == player
예제 #2
0
 def test_can_filter_players_with_less_than_n_rounds(self):
     # given a list of matches
     logs = "tests/logs"
     match_reports = LogDirectoryParser(logs).get_all_match_reports()
     # when given to the stats extractor with a filter
     scorer = WinRateScorer(filter_less_than=10)
     stats = MatchReportCollection(match_reports)
     # then the confidence in a player with less than the filter rounds played is zero
     score_table = stats.get_full_player_scores(scorer)
     print(score_table)
     player = Player("El Bromas", 538649250)
     assert score_table[player].confidence == 0
예제 #3
0
 def test_can_get_glicko_ranking_per_player(self):
     # given a list of matches
     logs = "tests/logs"
     match_reports = LogDirectoryParser(logs).get_all_match_reports()
     # when given to the stats extractor
     scorer = GlickoScorer()
     stats = MatchReportCollection(match_reports)
     # we can know the player that has the best ranking
     score_table = stats.get_sorted_score_table(scorer)
     print(score_table)
     player = Player("Mcd.", 538382878)
     best_player = score_table[0][0]
     assert best_player == player
예제 #4
0
 def test_can_get_time_spent_in_the_server_per_player(self):
     # given a list of matches
     logs = "tests/logs"
     match_reports = LogDirectoryParser(logs).get_all_match_reports()
     # when given to the stats extractor
     scorer = TimeSpentScorer()
     stats = MatchReportCollection(match_reports)
     # we can know the player that spent more time in the server
     score_table = stats.get_sorted_score_table(scorer)
     print(score_table)
     player = Player("Rocho", 86787335)
     best_player = score_table[0][0]
     assert best_player == player
예제 #5
0
 def test_can_get_the_default_score_from_many_matches(self):
     # given a list of matches
     logs = "tests/logs"
     match_reports = LogDirectoryParser(logs).get_all_match_reports()
     # when given to the stats extractor
     scorer = DefaultScorer()
     stats = MatchReportCollection(match_reports)
     # we can know the best player
     score_table = stats.get_sorted_score_table(scorer)
     print(score_table)
     player = Player("Mcd.", 538382878)
     best_player = score_table[0][0]
     assert best_player == player
예제 #6
0
 def __init__(
     self,
     match_reports: Collection[MatchReport],
     scorer: Optional[ScorerStrategy] = None,
 ):
     self._match_reports = MatchReportCollection(match_reports)
     self._scorer = scorer or DefaultScorer()
예제 #7
0
class StatsTable:
    """
    The stats table can construct a table of stats about the players, based on many different scoring strategies.
    """
    def __init__(self, match_reports: Collection[MatchReport],
                 scorers: Collection[ScorerStrategy]):
        self._match_reports = MatchReportCollection(match_reports)
        self._scorers = scorers

    def get_full_table(self) -> Mapping[Player, StatsRow]:
        table = defaultdict(dict)
        stats = {}
        for scorer in self._scorers:
            stat_name = scorer.stat_name
            stats[stat_name] = scorer.stat_explanation
            scores = self._match_reports.get_full_player_scores(scorer)
            for player, value in scores.items():
                table[player][stat_name] = value
        filtered_table = {
            player: row
            for player, row in table.items() if len(row) == len(self._scorers)
        }
        return filtered_table

    def get_stats_explanations(self) -> Mapping[str, str]:
        return {
            scorer.stat_name: scorer.stat_explanation
            for scorer in self._scorers
        }
예제 #8
0
def get_stats_for_season(season_logs_path):
    match_reports = parse_logs(season_logs_path)
    total_amount_of_rounds = MatchReportCollection(
        match_reports).get_total_number_of_rounds()
    filter_threshold = max(100, total_amount_of_rounds / 100)
    scorers = [
        GlickoScorer(filter_threshold),
        DefaultScorer(filter_threshold),
        KillsScorer(filter_threshold),
        DeathsScorer(filter_threshold),
        WinRateScorer(filter_threshold),
        TotalRoundsScorer(filter_threshold),
        TimeSpentScorer(filter_threshold),
    ]
    stats = StatsTable(match_reports, scorers)
    table = stats.get_full_table()
    stat_names = [scorer.stat_name for scorer in scorers]
    stat_details = [(scorer.stat_name, scorer.stat_explanation)
                    for scorer in scorers]

    def flatten_player_row(table, player):
        return [table[player].get(stat_name) for stat_name in stat_names]

    flat_table = {
        player.get_nickname(): flatten_player_row(table, player)
        for player in table
    }
    return stat_details, flat_table
예제 #9
0
 def get_player_scores(
         self,
         match_reports: MatchReportCollection) -> Mapping[Player, float]:
     scores: Dict[Player, int] = defaultdict(int)
     stats_by_player: PlayerTable = match_reports.collect_stats()
     for player, stats in stats_by_player.items():
         scores[player] += stats.kills
         scores[player] -= stats.deaths
     return scores
예제 #10
0
 def get_player_scores(
         self,
         match_reports: MatchReportCollection) -> Mapping[Player, float]:
     stats_by_player: PlayerTable = match_reports.collect_stats()
     scores = {
         player: stats.total_rounds_played()
         for player, stats in stats_by_player.items()
     }
     return scores
예제 #11
0
def get_or_create_stats_for_current_season(season_logs_path):
    match_reports = parse_logs(season_logs_path)
    total_amount_of_rounds = MatchReportCollection(
        match_reports).get_total_number_of_rounds()
    if total_amount_of_rounds in CURRENT_SEASON_CACHE:
        return CURRENT_SEASON_CACHE[total_amount_of_rounds]
    else:
        CURRENT_SEASON_CACHE[total_amount_of_rounds] = get_stats_for_season(
            season_logs_path)
        return CURRENT_SEASON_CACHE[total_amount_of_rounds]
예제 #12
0
 def get_player_scores(
         self,
         match_reports: MatchReportCollection) -> Mapping[Player, float]:
     scores: Dict[Player, float] = defaultdict(int)
     stats_by_player: PlayerTable = match_reports.collect_stats()
     for player, stats in stats_by_player.items():
         rounds_played = stats.total_rounds_played()
         if rounds_played:
             rounds_won = stats.rounds_won
             scores[player] = rounds_won / rounds_played
     return scores
예제 #13
0
    def get_confidence_in_player_scores(
            self,
            match_reports: MatchReportCollection) -> Mapping[Player, float]:
        """
        Returns a level of confidence in the score returned (a number between 0 and 1).
        Default calculation is 1 if the number of rounds the player was involved in is more than the filter_less_than
        parameter (and 0 otherwise).
        Other scorers may override this value, usually with  the percentage of rounds this player was involved in.
        """
        stats_by_player: PlayerTable = match_reports.collect_stats()

        confidence_table = {}
        for player, stats in stats_by_player.items():
            player_rounds = stats.total_rounds_played()
            confidence_table[
                player] = 1 if player_rounds >= self.filter_treshold else 0
        return confidence_table
예제 #14
0
 def __init__(self, match_reports: Collection[MatchReport],
              scorers: Collection[ScorerStrategy]):
     self._match_reports = MatchReportCollection(match_reports)
     self._scorers = scorers