def __init__(self, city, league=None): """Initialize a Team object.""" self.cosmos = city.cosmos # Attribute the team's league; if None, this means this is an independent # club (or something like that) self.league = league self.league.teams.add(self) # Prepare geographic and organizational attributes, which get set by # .establish_base_in_city(), a method that will also be called in the case # that this franchise relocates self.city = None self.state = None self.country = None self.organization = None # This gets set by .establish_base_in_city() self.nickname = None # Prepare attributes that hold team personnel; these will also be updated by # .establish_base_in_city() self.personnel = set() self.owner = None self.manager = None self.scout = None # Prepare a ballpark attribute, which is set by establish_base_in_city() as well self.ballpark = None # Finally actually establish operations in the city self.establish_base_in_city(city=city) # Set various attributes self.founded = self.cosmos.year self.ceased = None self.expansion = True if self.cosmos.year > self.league.founded else False self.charter_team = True if not self.expansion else False # Set history object self.history = FranchiseHistory(franchise=self) # Prepare various attributes self.season = None # Gets set by TeamSeason.__init__() self.defunct = False # Assemble a roster of players self.players = set() self.roster = None self._sign_players() self._assemble_roster() if self.expansion: print '{team} have been enfranchised in the {league}.'.format( team=self.name, league=self.league.name)
def __init__(self, city, league=None): """Initialize a Team object.""" self.cosmos = city.cosmos # Attribute the team's league; if None, this means this is an independent # club (or something like that) self.league = league self.league.teams.add(self) # Prepare geographic and organizational attributes, which get set by # .establish_base_in_city(), a method that will also be called in the case # that this franchise relocates self.city = None self.state = None self.country = None self.organization = None # This gets set by .establish_base_in_city() self.nickname = None # Prepare attributes that hold team personnel; these will also be updated by # .establish_base_in_city() self.personnel = set() self.owner = None self.manager = None self.scout = None # Prepare a ballpark attribute, which is set by establish_base_in_city() as well self.ballpark = None # Finally actually establish operations in the city self.establish_base_in_city(city=city) # Set various attributes self.founded = self.cosmos.year self.ceased = None self.expansion = True if self.cosmos.year > self.league.founded else False self.charter_team = True if not self.expansion else False # Set history object self.history = FranchiseHistory(franchise=self) # Prepare various attributes self.season = None # Gets set by TeamSeason.__init__() self.defunct = False # Assemble a roster of players self.players = set() self.roster = None self._sign_players() self._assemble_roster() if self.expansion: print '{team} have been enfranchised in the {league}.'.format(team=self.name, league=self.league.name)
class Team(object): """A baseball team in a baseball cosmos.""" def __init__(self, city, league=None): """Initialize a Team object.""" self.cosmos = city.cosmos # Attribute the team's league; if None, this means this is an independent # club (or something like that) self.league = league self.league.teams.add(self) # Prepare geographic and organizational attributes, which get set by # .establish_base_in_city(), a method that will also be called in the case # that this franchise relocates self.city = None self.state = None self.country = None self.organization = None # This gets set by .establish_base_in_city() self.nickname = None # Prepare attributes that hold team personnel; these will also be updated by # .establish_base_in_city() self.personnel = set() self.owner = None self.manager = None self.scout = None # Prepare a ballpark attribute, which is set by establish_base_in_city() as well self.ballpark = None # Finally actually establish operations in the city self.establish_base_in_city(city=city) # Set various attributes self.founded = self.cosmos.year self.ceased = None self.expansion = True if self.cosmos.year > self.league.founded else False self.charter_team = True if not self.expansion else False # Set history object self.history = FranchiseHistory(franchise=self) # Prepare various attributes self.season = None # Gets set by TeamSeason.__init__() self.defunct = False # Assemble a roster of players self.players = set() self.roster = None self._sign_players() self._assemble_roster() if self.expansion: print '{team} have been enfranchised in the {league}.'.format(team=self.name, league=self.league.name) def __str__(self): """Return string representation.""" return self.name @property def name(self): """Return the name of this franchise.""" return "{city} {nickname}".format(city=self.city.name, nickname=self.nickname) @property def random_player(self): """Return a random player on this team.""" return random.choice(list(self.players)) def establish_base_in_city(self, city, employees_to_relocate=None): """Establish operations in a city, either due to enfranchisement or relocation.""" # Determine whether this is part of a relocation procedure, which is signaled by # employees_to_relocate being passed relocating = True if employees_to_relocate else False tradition_in_the_old_city = None if not relocating else self.history.tradition # Set geographic attributes self.city = city self.state = city.state self.country = city.country # Update teams listing of new city self.city.teams.add(self) # Form a corresponding baseball organization, which will be a Business object that # handles business and other considerations if not relocating: self.organization = BaseballOrganization(team=self) else: self.organization = RelocatedBaseballOrganization(team=self, employees_to_relocate=employees_to_relocate) # Come up with a nickname self.nickname = self._determine_nickname(tradition_in_the_old_city=tradition_in_the_old_city) # Update the organization's name accordingly self.organization.set_name() # Set your team personnel self.set_team_personnel() # Set the team's ballpark, which will have been procured by the organization's # __init__() method self.ballpark = self.organization.ballpark def _determine_nickname(self, tradition_in_the_old_city): """Determine a nickname for this team.""" # If you're relocating, consider retaining the name of the team if self._decide_to_retain_nickname(tradition_in_the_old_city=tradition_in_the_old_city): return self.nickname else: return self._come_up_with_nickname() def _decide_to_retain_nickname(self, tradition_in_the_old_city): """Decide whether to retain the nickname of this relocating franchise.""" if tradition_in_the_old_city: # This signals relocation chance_we_retain_name = self.cosmos.config.chance_a_relocated_team_retains_name( tradition_in_the_old_city=tradition_in_the_old_city ) if random.random() < chance_we_retain_name: # Make sure the name is not already taken if not any(t for t in self.city.teams if t.nickname == self.nickname): return True return False def _come_up_with_nickname(self): """Come up with a nickname for this team.""" # TODO CITY APT NICKNAMES AND NAMES OF HISTORICAL TEAMS IN THE CITY name_already_taken = True nickname = None while name_already_taken: nickname = Names.a_baseball_team_nickname(year=self.city.cosmos.year) # Make sure the name is not already taken if not any(t for t in self.city.teams if t.nickname == nickname): name_already_taken = False else: # TODO fix this duct tape here return "Generics" return nickname def set_team_personnel(self): """Set the personnel working for this team. In this method, we set attributes pertaining to the actual baseball-class objects corresponding to the employees of this organization. This method may be called any time an employee in the organization quits, retires, is fired, or dies. """ # Set team owner owner_person = next(e for e in self.organization.employees if isinstance(e, BaseballTeamOwner)).person self.owner = Owner(person=owner_person) if not owner_person.team_owner else owner_person.team_owner # Set manager manager_person = next(e for e in self.organization.employees if isinstance(e, BaseballManager)).person self.manager = ( Manager(person=manager_person, team=self) if not manager_person.manager else manager_person.manager ) # Set scout scout_person = next(e for e in self.organization.employees if isinstance(e, BaseballScout)).person self.scout = Scout(person=scout_person, team=self) if not scout_person.scout else scout_person.scout # Set personnel attribute self.personnel = {self.owner, self.manager, self.scout} for p in self.personnel: p.team = self def _sign_players(self): """Sign players until you have a full roster.""" roster_limit = self.league.classification.roster_limit if len(self.players) < roster_limit: print "\t{scout} is signing players...".format(scout=self.scout.person.name) while len(self.players) < roster_limit: position_of_need = self.manager.decide_position_of_greatest_need() secured_player = self.scout.secure_a_player(position=position_of_need) self._sign_player(player=secured_player, position=position_of_need) # Update the team's roster self._assemble_roster() def _sign_player(self, player, position): """Sign the given player to play at the given position.""" print "\t\tsigning {}...".format(player.person.name) player.career.team = self player.position = position self.players.add(player) # Actually hire the player as an employee in the organization self.organization.hire(occupation_of_need=BaseballPlayer, shift="special", selected_candidate=player.person) def _assemble_roster(self): """Assemble a roster for this team.""" # Prepare some variables that we'll need roster_order = ('P', 'C', '1B', '2B', '3B', 'SS', 'LF', 'CF', 'RF') lineup = [] available_players = list(self.players) # Assemble starters for position_to_slot in roster_order: available_players_at_that_position = [p for p in available_players if p.position == position_to_slot] best_available_at_that_position = max( available_players_at_that_position, key=lambda player: self.scout.grade(prospect=player, position=position_to_slot) ) lineup.append(best_available_at_that_position) available_players.remove(best_available_at_that_position) # Assemble bullpen and bench bullpen = [] bench = [] for bench_player in available_players: if bench_player.position == 'P': bullpen.append(bench_player) else: bench.append(bench_player) # Instantiate and set a Roster object self.roster = Roster(lineup=tuple(lineup), bullpen=tuple(bullpen), bench=tuple(bench)) def process_a_retirement(self, player): """Handle the retirement of a player.""" # TODO DETERMINE CEREMONIES, ETC., IF EXCEPTIONAL CAREER self._terminate_contract(player=player) self.history.former_players.add(player) # Let the league know self.league.process_a_retirement(player=player) def _terminate_contract(self, player): """Terminate the contract of a player.""" self.players.remove(player) player.career.team = None # If this is during a season, potentially sign a replacement if self.season: self._sign_players() def conduct_offseason_activity(self): """Conduct this team's offseason procedures.""" config = self.cosmos.config # If you're a fairly established team in a very established league, consider relocating; # newer teams won't consider relocating, since they're still establishing a fan base in # their current cities; teams in leagues that aren't established don't relocate because # they would have no more value to another city than an expansion team would team_is_established_in_town = ( self.history.number_of_years_in_town > config.minimum_number_of_years_in_city_before_considering_relocation(year=self.cosmos.year) ) league_is_established_enough_for_relocation = ( self.league.history.years_in_existence > config.minimum_number_of_years_before_league_established_enough_for_team_relocation() ) if team_is_established_in_town and league_is_established_enough_for_relocation: self._potentially_relocate() # Otherwise, if you aren't a brand new team and the league isn't established yet, # then consider folding elif self.history.seasons and not league_is_established_enough_for_relocation: self._potentially_fold() def _potentially_fold(self): """Potentially _fold this franchise.""" chance_of_folding = self.cosmos.config.chance_of_folding( franchise_winning_percentage=self.history.cumulative_winning_percentage, league_years_in_existence=self.league.history.years_in_existence ) if random.random() < chance_of_folding: self._fold() def _fold(self): """Cease operations of this franchise.""" # Have the organization go out of business, which will officially terminate # all of the organization's employee occupations -- have to do this first so # that the BaseballFranchiseTermination object gets all the attributes it needs self.organization.go_out_of_business(reason=BaseballFranchiseTermination(franchise=self)) # Sever ties with the city you're located in self._sever_ties_with_city() # Sever ties with the league you're in self._sever_ties_with_league() # Sever ties with players and personnel self._sever_ties_with_players_and_personnel() # Update attributes self.defunct = True self.ceased = self.cosmos.year def _sever_ties_with_city(self): """Sever ties with the city you were located in.""" self.city.teams.remove(self) self.city.former_teams.add(self) def _sever_ties_with_league(self): """Sever ties with the league you were a member of.""" self.league.teams.remove(self) self.league.history.defunct_teams.add(self) def _sever_ties_with_players_and_personnel(self): """Sever ties with your players and personnel.""" for stakeholder in self.players | self.personnel: stakeholder.career.team = None def _potentially_relocate(self): """Potentially _relocate this franchise to a new city.""" config = self.cosmos.config if self._qualified_to_relocate(): if random.random() < config.chance_a_team_that_qualifies_to_relocate_will_relocate: self._relocate() def _qualified_to_relocate(self): """Return whether this franchise is qualified to relocate.""" config = self.cosmos.config # If your last season was a losing season... last_season_was_a_losing_season = self.history.seasons[-1].winning_percentage < 0.5 if not last_season_was_a_losing_season: return False # ...and your franchise isn't too storied to ever relocate... franchise_is_too_storied_to_relocate = config.franchise_too_storied_to_relocate( tradition=self.history.tradition ) if franchise_is_too_storied_to_relocate: return False # ...and you've averaged a losing season over the duration of your fan base's memory... fan_base_memory_window = int(config.fan_base_memory_window()) beginning_of_that_window = self.cosmos.year-fan_base_memory_window winning_percentage_during_fan_base_memory = self.history.winning_percentage_during_window( start_year=beginning_of_that_window, end_year=self.cosmos.year, city=self.city ) averaged_losing_season_during_fan_base_memory = winning_percentage_during_fan_base_memory < 0.5 if not averaged_losing_season_during_fan_base_memory: return False # ..then you are qualified to relocate return True def _relocate(self): """Relocate this franchise to a new city.""" # TODO EMBITTER FANS IN THIS CITY # Sever ties with the city you are departing self._sever_ties_with_city() # Decide where to relocate to city_to_relocate_to = self._decide_where_to_relocate_to() # Shut down the current organization, but save all its employees so # that we can offer them the chance to relocate to the new organization employees_to_relocate = set(self.organization.employees) # Set up operations in the new city self.establish_base_in_city(city=city_to_relocate_to, employees_to_relocate=employees_to_relocate) print "The {old_name} of the {league} have relocated to become the {new_name}".format( # old_name="{} {}".format(self.history.seasons[-1].city.name, self.history.seasons[-1].nickname), old_name='LOL HI!', league=self.league.name, new_name=self.name ) def _decide_where_to_relocate_to(self): """Decide which city to relocate this franchise to.""" cities_ranked_by_utility = self.league.rank_prospective_cities() cities_ranked_by_utility.remove(self.city) # Throw out the city we're leaving # If the hometown of the owner of this franchise is a viable city to relocate # to, then select that city if self.owner.person.hometown in cities_ranked_by_utility: return self.owner.person.hometown most_appealing_city = cities_ranked_by_utility[0] return most_appealing_city def operate(self): """Conduct the regular operations of this franchise.""" # TODO MAKE TRAVEL REALISTIC ONCE TRAVEL SYSTEM IMPLEMENTED if self.season: # Check if you have any games scheduled for this timestep try: next_scheduled_series = self.season.schedule.next_series ordinal_date_of_next_game, timestep_of_next_game = next_scheduled_series.dates_scheduled[0] ballpark_of_next_game = next_scheduled_series.home_team.ballpark game_is_this_timestep = ( ordinal_date_of_next_game == self.cosmos.ordinal_date and timestep_of_next_game == self.cosmos.time_of_day ) # If the game is this timestep... if game_is_this_timestep: # ...then head to the ballpark... for stakeholder in {self.manager, self.scout} | self.players: stakeholder.person.go_to(destination=ballpark_of_next_game, occasion="baseball") # ...and let the league know the game is this timestep; League.operate() will # eventually instantiate the actual Game object self.league.add_to_game_queue(next_scheduled_series) # No game scheduled for this timestep, so just hang out except AttributeError: pass else: # Off-season # Players will have already retired by LeagueSeason.review() calling # TeamSeason.review(); if anyone did retire, this team needs to sign # more players to get to the roster limit self._sign_players()
class Team(object): """A baseball team in a baseball cosmos.""" def __init__(self, city, league=None): """Initialize a Team object.""" self.cosmos = city.cosmos # Attribute the team's league; if None, this means this is an independent # club (or something like that) self.league = league self.league.teams.add(self) # Prepare geographic and organizational attributes, which get set by # .establish_base_in_city(), a method that will also be called in the case # that this franchise relocates self.city = None self.state = None self.country = None self.organization = None # This gets set by .establish_base_in_city() self.nickname = None # Prepare attributes that hold team personnel; these will also be updated by # .establish_base_in_city() self.personnel = set() self.owner = None self.manager = None self.scout = None # Prepare a ballpark attribute, which is set by establish_base_in_city() as well self.ballpark = None # Finally actually establish operations in the city self.establish_base_in_city(city=city) # Set various attributes self.founded = self.cosmos.year self.ceased = None self.expansion = True if self.cosmos.year > self.league.founded else False self.charter_team = True if not self.expansion else False # Set history object self.history = FranchiseHistory(franchise=self) # Prepare various attributes self.season = None # Gets set by TeamSeason.__init__() self.defunct = False # Assemble a roster of players self.players = set() self.roster = None self._sign_players() self._assemble_roster() if self.expansion: print '{team} have been enfranchised in the {league}.'.format( team=self.name, league=self.league.name) def __str__(self): """Return string representation.""" return self.name @property def name(self): """Return the name of this franchise.""" return "{city} {nickname}".format(city=self.city.name, nickname=self.nickname) @property def random_player(self): """Return a random player on this team.""" return random.choice(list(self.players)) def establish_base_in_city(self, city, employees_to_relocate=None): """Establish operations in a city, either due to enfranchisement or relocation.""" # Determine whether this is part of a relocation procedure, which is signaled by # employees_to_relocate being passed relocating = True if employees_to_relocate else False tradition_in_the_old_city = None if not relocating else self.history.tradition # Set geographic attributes self.city = city self.state = city.state self.country = city.country # Update teams listing of new city self.city.teams.add(self) # Form a corresponding baseball organization, which will be a Business object that # handles business and other considerations if not relocating: self.organization = BaseballOrganization(team=self) else: self.organization = RelocatedBaseballOrganization( team=self, employees_to_relocate=employees_to_relocate) # Come up with a nickname self.nickname = self._determine_nickname( tradition_in_the_old_city=tradition_in_the_old_city) # Update the organization's name accordingly self.organization.set_name() # Set your team personnel self.set_team_personnel() # Set the team's ballpark, which will have been procured by the organization's # __init__() method self.ballpark = self.organization.ballpark def _determine_nickname(self, tradition_in_the_old_city): """Determine a nickname for this team.""" # If you're relocating, consider retaining the name of the team if self._decide_to_retain_nickname( tradition_in_the_old_city=tradition_in_the_old_city): return self.nickname else: return self._come_up_with_nickname() def _decide_to_retain_nickname(self, tradition_in_the_old_city): """Decide whether to retain the nickname of this relocating franchise.""" if tradition_in_the_old_city: # This signals relocation chance_we_retain_name = self.cosmos.config.chance_a_relocated_team_retains_name( tradition_in_the_old_city=tradition_in_the_old_city) if random.random() < chance_we_retain_name: # Make sure the name is not already taken if not any(t for t in self.city.teams if t.nickname == self.nickname): return True return False def _come_up_with_nickname(self): """Come up with a nickname for this team.""" # TODO CITY APT NICKNAMES AND NAMES OF HISTORICAL TEAMS IN THE CITY name_already_taken = True nickname = None while name_already_taken: nickname = Names.a_baseball_team_nickname( year=self.city.cosmos.year) # Make sure the name is not already taken if not any(t for t in self.city.teams if t.nickname == nickname): name_already_taken = False else: # TODO fix this duct tape here return "Generics" return nickname def set_team_personnel(self): """Set the personnel working for this team. In this method, we set attributes pertaining to the actual baseball-class objects corresponding to the employees of this organization. This method may be called any time an employee in the organization quits, retires, is fired, or dies. """ # Set team owner owner_person = next(e for e in self.organization.employees if isinstance(e, BaseballTeamOwner)).person self.owner = Owner( person=owner_person ) if not owner_person.team_owner else owner_person.team_owner # Set manager manager_person = next(e for e in self.organization.employees if isinstance(e, BaseballManager)).person self.manager = (Manager(person=manager_person, team=self) if not manager_person.manager else manager_person.manager) # Set scout scout_person = next(e for e in self.organization.employees if isinstance(e, BaseballScout)).person self.scout = Scout( person=scout_person, team=self) if not scout_person.scout else scout_person.scout # Set personnel attribute self.personnel = {self.owner, self.manager, self.scout} for p in self.personnel: p.team = self def _sign_players(self): """Sign players until you have a full roster.""" roster_limit = self.league.classification.roster_limit if len(self.players) < roster_limit: print "\t{scout} is signing players...".format( scout=self.scout.person.name) while len(self.players) < roster_limit: position_of_need = self.manager.decide_position_of_greatest_need() secured_player = self.scout.secure_a_player( position=position_of_need) self._sign_player(player=secured_player, position=position_of_need) # Update the team's roster self._assemble_roster() def _sign_player(self, player, position): """Sign the given player to play at the given position.""" print "\t\tsigning {}...".format(player.person.name) player.career.team = self player.position = position self.players.add(player) # Actually hire the player as an employee in the organization self.organization.hire(occupation_of_need=BaseballPlayer, shift="special", selected_candidate=player.person) def _assemble_roster(self): """Assemble a roster for this team.""" # Prepare some variables that we'll need roster_order = ('P', 'C', '1B', '2B', '3B', 'SS', 'LF', 'CF', 'RF') lineup = [] available_players = list(self.players) # Assemble starters for position_to_slot in roster_order: available_players_at_that_position = [ p for p in available_players if p.position == position_to_slot ] best_available_at_that_position = max( available_players_at_that_position, key=lambda player: self.scout.grade(prospect=player, position=position_to_slot)) lineup.append(best_available_at_that_position) available_players.remove(best_available_at_that_position) # Assemble bullpen and bench bullpen = [] bench = [] for bench_player in available_players: if bench_player.position == 'P': bullpen.append(bench_player) else: bench.append(bench_player) # Instantiate and set a Roster object self.roster = Roster(lineup=tuple(lineup), bullpen=tuple(bullpen), bench=tuple(bench)) def process_a_retirement(self, player): """Handle the retirement of a player.""" # TODO DETERMINE CEREMONIES, ETC., IF EXCEPTIONAL CAREER self._terminate_contract(player=player) self.history.former_players.add(player) # Let the league know self.league.process_a_retirement(player=player) def _terminate_contract(self, player): """Terminate the contract of a player.""" self.players.remove(player) player.career.team = None # If this is during a season, potentially sign a replacement if self.season: self._sign_players() def conduct_offseason_activity(self): """Conduct this team's offseason procedures.""" config = self.cosmos.config # If you're a fairly established team in a very established league, consider relocating; # newer teams won't consider relocating, since they're still establishing a fan base in # their current cities; teams in leagues that aren't established don't relocate because # they would have no more value to another city than an expansion team would team_is_established_in_town = ( self.history.number_of_years_in_town > config. minimum_number_of_years_in_city_before_considering_relocation( year=self.cosmos.year)) league_is_established_enough_for_relocation = ( self.league.history.years_in_existence > config. minimum_number_of_years_before_league_established_enough_for_team_relocation( )) if team_is_established_in_town and league_is_established_enough_for_relocation: self._potentially_relocate() # Otherwise, if you aren't a brand new team and the league isn't established yet, # then consider folding elif self.history.seasons and not league_is_established_enough_for_relocation: self._potentially_fold() def _potentially_fold(self): """Potentially _fold this franchise.""" chance_of_folding = self.cosmos.config.chance_of_folding( franchise_winning_percentage=self.history. cumulative_winning_percentage, league_years_in_existence=self.league.history.years_in_existence) if random.random() < chance_of_folding: self._fold() def _fold(self): """Cease operations of this franchise.""" # Have the organization go out of business, which will officially terminate # all of the organization's employee occupations -- have to do this first so # that the BaseballFranchiseTermination object gets all the attributes it needs self.organization.go_out_of_business( reason=BaseballFranchiseTermination(franchise=self)) # Sever ties with the city you're located in self._sever_ties_with_city() # Sever ties with the league you're in self._sever_ties_with_league() # Sever ties with players and personnel self._sever_ties_with_players_and_personnel() # Update attributes self.defunct = True self.ceased = self.cosmos.year def _sever_ties_with_city(self): """Sever ties with the city you were located in.""" self.city.teams.remove(self) self.city.former_teams.add(self) def _sever_ties_with_league(self): """Sever ties with the league you were a member of.""" self.league.teams.remove(self) self.league.history.defunct_teams.add(self) def _sever_ties_with_players_and_personnel(self): """Sever ties with your players and personnel.""" for stakeholder in self.players | self.personnel: stakeholder.career.team = None def _potentially_relocate(self): """Potentially _relocate this franchise to a new city.""" config = self.cosmos.config if self._qualified_to_relocate(): if random.random( ) < config.chance_a_team_that_qualifies_to_relocate_will_relocate: self._relocate() def _qualified_to_relocate(self): """Return whether this franchise is qualified to relocate.""" config = self.cosmos.config # If your last season was a losing season... last_season_was_a_losing_season = self.history.seasons[ -1].winning_percentage < 0.5 if not last_season_was_a_losing_season: return False # ...and your franchise isn't too storied to ever relocate... franchise_is_too_storied_to_relocate = config.franchise_too_storied_to_relocate( tradition=self.history.tradition) if franchise_is_too_storied_to_relocate: return False # ...and you've averaged a losing season over the duration of your fan base's memory... fan_base_memory_window = int(config.fan_base_memory_window()) beginning_of_that_window = self.cosmos.year - fan_base_memory_window winning_percentage_during_fan_base_memory = self.history.winning_percentage_during_window( start_year=beginning_of_that_window, end_year=self.cosmos.year, city=self.city) averaged_losing_season_during_fan_base_memory = winning_percentage_during_fan_base_memory < 0.5 if not averaged_losing_season_during_fan_base_memory: return False # ..then you are qualified to relocate return True def _relocate(self): """Relocate this franchise to a new city.""" # TODO EMBITTER FANS IN THIS CITY # Sever ties with the city you are departing self._sever_ties_with_city() # Decide where to relocate to city_to_relocate_to = self._decide_where_to_relocate_to() # Shut down the current organization, but save all its employees so # that we can offer them the chance to relocate to the new organization employees_to_relocate = set(self.organization.employees) # Set up operations in the new city self.establish_base_in_city( city=city_to_relocate_to, employees_to_relocate=employees_to_relocate) print "The {old_name} of the {league} have relocated to become the {new_name}".format( # old_name="{} {}".format(self.history.seasons[-1].city.name, self.history.seasons[-1].nickname), old_name='LOL HI!', league=self.league.name, new_name=self.name) def _decide_where_to_relocate_to(self): """Decide which city to relocate this franchise to.""" cities_ranked_by_utility = self.league.rank_prospective_cities() cities_ranked_by_utility.remove( self.city) # Throw out the city we're leaving # If the hometown of the owner of this franchise is a viable city to relocate # to, then select that city if self.owner.person.hometown in cities_ranked_by_utility: return self.owner.person.hometown most_appealing_city = cities_ranked_by_utility[0] return most_appealing_city def operate(self): """Conduct the regular operations of this franchise.""" # TODO MAKE TRAVEL REALISTIC ONCE TRAVEL SYSTEM IMPLEMENTED if self.season: # Check if you have any games scheduled for this timestep try: next_scheduled_series = self.season.schedule.next_series ordinal_date_of_next_game, timestep_of_next_game = next_scheduled_series.dates_scheduled[ 0] ballpark_of_next_game = next_scheduled_series.home_team.ballpark game_is_this_timestep = ( ordinal_date_of_next_game == self.cosmos.ordinal_date and timestep_of_next_game == self.cosmos.time_of_day) # If the game is this timestep... if game_is_this_timestep: # ...then head to the ballpark... for stakeholder in {self.manager, self.scout } | self.players: stakeholder.person.go_to( destination=ballpark_of_next_game, occasion="baseball") # ...and let the league know the game is this timestep; League.operate() will # eventually instantiate the actual Game object self.league.add_to_game_queue(next_scheduled_series) # No game scheduled for this timestep, so just hang out except AttributeError: pass else: # Off-season # Players will have already retired by LeagueSeason.review() calling # TeamSeason.review(); if anyone did retire, this team needs to sign # more players to get to the roster limit self._sign_players()