| 38 | } |
| 39 | |
| 40 | |
| 41 | class RoundStats: |
| 42 | def __init__(self, round_num: int, agents: list[Player]): |
| 43 | self.winner = None |
| 44 | self.round_num = round_num |
| 45 | # Map of player to game metric (e.g. # of wins, assets accumulated) |
| 46 | self.scores: dict[str, float] = {a.name: 0.0 for a in agents} |
| 47 | self.player_stats: dict[str, PlayerStats] = {agent.name: PlayerStats(name=agent.name) for agent in agents} |
| 48 | self.details: list[str] = [] |
| 49 | |
| 50 | def __str__(self) -> str: |
| 51 | rv = [f"In round {self.round_num}, the winner is {self.winner}.", "\nSummary of player performance:"] |
| 52 | for player, stats in self.player_stats.items(): |
| 53 | if stats.valid_submit: |
| 54 | rv.append(f"- {player}: submission compiled successfully, score={stats.score}") |
| 55 | else: |
| 56 | rv.append(f"- {player}: submission failed with error: {stats.invalid_reason}") |
| 57 | if self.details: |
| 58 | rv.extend(["Details:"] + [f"- {line}" for line in self.details]) |
| 59 | return "\n".join(rv) |
| 60 | |
| 61 | def to_dict(self) -> dict[str, Any]: |
| 62 | # Going through some pain to ensure that the scores dict is always complete |
| 63 | player_names = set(self.player_stats.keys()) | set(self.scores.keys()) |
| 64 | return { |
| 65 | "round_num": self.round_num, |
| 66 | "winner": self.winner, |
| 67 | "details": self.details, |
| 68 | "scores": {name: self.scores.get(name, 0.0) for name in player_names}, |
| 69 | "player_stats": {name: stats.to_dict() for name, stats in self.player_stats.items()}, |
| 70 | } |
| 71 | |
| 72 |
no outgoing calls