Spaces:
Running
Running
| # -*- coding: utf-8 -*- | |
| from core.kick_off_event import KickOffEvent | |
| class Step: | |
| """Represents a single replay step, potentially containing major events.""" | |
| def __init__(self, step_number=None, game_turn=None, team0_score=0, team1_score=0, active_team_id=None): | |
| self.step_number = step_number # Sequential replay step counter | |
| self.game_turn = game_turn # GameTurn value from replay | |
| self.team0_score = team0_score | |
| self.team1_score = team1_score | |
| self.active_team_id = active_team_id # 0 or 1, from PlayerStep | |
| self.turn_owner_team_id = None | |
| self.kick_off = None # KickOffEvent if one occurred in this step | |
| self.touchdown = None # Touchdown details if one occurred in this step | |
| self.weather = None # Weather snapshot after this step, if known | |
| self.roll_events = [] # All non-kickoff dice roll events found in this step | |
| self.explicit_turn_end = False # True when replay emitted EventEndTurn in this step | |
| self.end_turn_reason = None # Replay EventEndTurn.Reason | |
| self.end_turn_type = None # Replay EventEndTurn.FinishingTurnType | |
| self.next_active_team_id = None # Replay next active gamer, when explicit | |
| self.acting_player_id = None # Replay-resolved acting player for this step | |
| self.acting_player_name = None | |
| self.acting_player_team_id = None | |
| def has_kick_off(self): | |
| """Check if this step has a kickoff event.""" | |
| return self.kick_off is not None | |
| def set_kick_off(self, kick_off_event): | |
| """Set the kickoff event for this step.""" | |
| if isinstance(kick_off_event, KickOffEvent): | |
| self.kick_off = kick_off_event | |
| else: | |
| raise ValueError("kick_off_event must be a KickOffEvent instance") | |
| def has_touchdown(self): | |
| """Check if this step records a touchdown.""" | |
| return self.touchdown is not None | |
| def set_touchdown(self, player_id, player_name, team_id): | |
| """Store touchdown details for this step.""" | |
| self.touchdown = { | |
| 'player_id': player_id, | |
| 'player_name': player_name, | |
| 'team_id': team_id, | |
| } | |
| def set_weather(self, weather): | |
| """Store weather snapshot for this step.""" | |
| if isinstance(weather, dict) or weather is None: | |
| self.weather = weather | |
| else: | |
| raise ValueError("weather must be a dict or None") | |
| def add_roll_event(self, roll_event): | |
| """Add a parsed dice roll event for this step.""" | |
| if isinstance(roll_event, dict): | |
| self.roll_events.append(roll_event) | |
| else: | |
| raise ValueError("roll_event must be a dict") | |
| def set_turn_boundary(self, explicit_turn_end=False, end_turn_reason=None, end_turn_type=None, next_active_team_id=None): | |
| """Store explicit turn-boundary metadata extracted from replay events.""" | |
| self.explicit_turn_end = bool(explicit_turn_end) | |
| self.end_turn_reason = end_turn_reason | |
| self.end_turn_type = end_turn_type | |
| self.next_active_team_id = next_active_team_id | |
| def set_turn_owner(self, team_id): | |
| """Store canonical team-turn ownership for this step.""" | |
| self.turn_owner_team_id = team_id | |
| def set_acting_player(self, player_id=None, player_name=None, team_id=None): | |
| """Store replay-resolved acting player metadata for this step.""" | |
| self.acting_player_id = player_id | |
| self.acting_player_name = player_name | |
| self.acting_player_team_id = team_id | |
| def __repr__(self) -> str: | |
| kick_off_str = f", KickOff: {self.kick_off}" if self.kick_off else "" | |
| touchdown_str = f", Touchdown: {self.touchdown}" if self.touchdown else "" | |
| weather_str = f", Weather: {self.weather}" if self.weather else "" | |
| turn_end_str = "" | |
| if self.explicit_turn_end: | |
| turn_end_str = ( | |
| f", TurnEnd(reason={self.end_turn_reason}, type={self.end_turn_type}, " | |
| f"next={self.next_active_team_id})" | |
| ) | |
| return f"Step(#{self.step_number}, GameTurn={self.game_turn}, Team{self.active_team_id} active, Score {self.team0_score}-{self.team1_score}{kick_off_str}{touchdown_str}{weather_str}{turn_end_str})" | |
| def to_dict(self): | |
| return { | |
| 'step_number': self.step_number, | |
| 'game_turn': self.game_turn, | |
| 'team0_score': self.team0_score, | |
| 'team1_score': self.team1_score, | |
| 'active_team_id': self.active_team_id, | |
| 'turn_owner_team_id': self.turn_owner_team_id, | |
| 'kick_off': self.kick_off.to_dict() if self.kick_off else None, | |
| 'touchdown': self.touchdown, | |
| 'weather': self.weather, | |
| 'roll_events': self.roll_events, | |
| 'explicit_turn_end': self.explicit_turn_end, | |
| 'end_turn_reason': self.end_turn_reason, | |
| 'end_turn_type': self.end_turn_type, | |
| 'next_active_team_id': self.next_active_team_id, | |
| 'acting_player_id': self.acting_player_id, | |
| 'acting_player_name': self.acting_player_name, | |
| 'acting_player_team_id': self.acting_player_team_id, | |
| } | |