Module blaseball_mike.models.game
Expand source code
from .base import Base
from .modification import Modification
from .player import Player
from .statsheet import GameStatsheet
from .team import Team
from .stadium import Stadium
from .weather import Weather
from .. import database, chronicler
class Game(Base):
"""
Represents one blaseball game
"""
@classmethod
def _get_fields(cls):
p = cls.load_by_id("1cbd9d82-89e6-46b2-9082-815f59e1a130")
return [cls._from_api_conversion(x) for x in p.fields]
@classmethod
def load_by_id(cls, id_):
"""
Load by ID
"""
return cls(database.get_game_by_id(id_))
@classmethod
def load_by_day(cls, season, day):
"""
Load by in-game season and day. Season and Day are 1-indexed
"""
return {
id_: cls(game) for id_, game in database.get_games(season, day).items()
}
@classmethod
def load_tournament_by_day(cls, tournament, day):
"""
Loads all games played in a tournament on a given in-game day. Day is 1-indexed
Tournament refers to things such as the Coffee Cup which exist outside the normal blaseball timeline.
"""
return {
id_: cls(game) for id_, game in database.get_tournament(tournament, day).items()
}
@classmethod
def load_by_season(cls, season, team_id=None, day=None):
"""
Return dictionary of games for a given season keyed by game ID.
Can optionally be filtered by in-game day or team ID. Season and Day are 1-indexed
"""
return {
game["gameId"]: cls(game["data"]) for game in chronicler.get_games(team_ids=team_id, season=season, day=day)
}
@classmethod
def load_by_tournament(cls, tournament, team_id=None, day=None):
"""
Return dictionary of games for a given tournament keyed by game ID.
Can optionally be filtered by in-game day or team ID. Day is 1-indexed
"""
return {
game["gameId"]: cls(game["data"]) for game in
chronicler.get_games(team_ids=team_id, tournament=tournament, day=day)
}
@property
def winning_team(self):
return self.home_team if self.home_score > self.away_score else self.away_team
@property
def winning_team_name(self):
return self.home_team_name if self.home_score > self.away_score else self.away_team_name
@property
def winning_team_nickname(self):
return self.home_team_nickname if self.home_score > self.away_score else self.away_team_nickname
@property
def losing_team(self):
return self.home_team if self.home_score < self.away_score else self.away_team
@property
def losing_team_name(self):
return self.home_team_name if self.home_score < self.away_score else self.away_team_name
@property
def losing_team_nickname(self):
return self.home_team_nickname if self.home_score < self.away_score else self.away_team_nickname
@property
def winning_score(self):
return self.home_score if self.home_score > self.away_score else self.away_score
@property
def losing_score(self):
return self.home_score if self.home_score < self.away_score else self.away_score
@Base.lazy_load("_base_runner_ids", cache_name="_base_runners", default_value=list())
def base_runners(self):
players = Player.load(*self._base_runner_ids)
return [players.get(id_) for id_ in self._base_runner_ids]
@Base.lazy_load("_weather", use_default=False)
def weather(self):
return Weather.load_one(self._weather)
@Base.lazy_load("_home_team_id", cache_name="_home_team")
def home_team(self):
return Team.load(self._home_team_id)
@Base.lazy_load("_away_team_id", cache_name="_away_team")
def away_team(self):
return Team.load(self._away_team_id)
@Base.lazy_load("_home_pitcher_id", cache_name="_home_pitcher")
def home_pitcher(self):
return Player.load_one(self._home_pitcher_id)
@Base.lazy_load("_away_pitcher_id", cache_name="_away_pitcher")
def away_pitcher(self):
return Player.load_one(self._away_pitcher_id)
@Base.lazy_load("_home_batter_id", cache_name="_home_batter")
def home_batter(self):
return Player.load_one(self._home_batter_id)
@Base.lazy_load("_away_batter_id", cache_name="_away_batter")
def away_batter(self):
return Player.load_one(self._away_batter_id)
@property
def at_bat_team(self):
if self.top_of_inning:
return self.away_team
else:
return self.home_team
@property
def at_bat_team_name(self):
if self.top_of_inning:
return self.away_team_name
else:
return self.home_team_name
@property
def at_bat_team_nickname(self):
if self.top_of_inning:
return self.away_team_nickname
else:
return self.home_team_nickname
@property
def pitching_team(self):
if self.top_of_inning:
return self.home_team
else:
return self.away_team
@property
def pitching_team_name(self):
if self.top_of_inning:
return self.home_team_name
else:
return self.away_team_name
@property
def pitching_team_nickname(self):
if self.top_of_inning:
return self.home_team_nickname
else:
return self.away_team_nickname
@property
def current_pitcher(self):
if self.top_of_inning:
return self.home_pitcher
else:
return self.away_pitcher
@property
def current_pitcher_name(self):
if self.top_of_inning:
return self.home_pitcher_name
else:
return self.away_pitcher_name
@property
def current_batter(self):
if self.top_of_inning:
return self.away_batter
else:
return self.home_batter
@property
def current_batter_name(self):
if self.top_of_inning:
return self.away_batter_name
else:
return self.home_batter_name
@Base.lazy_load("_season", use_default=False)
def season(self):
return self._season + 1
@Base.lazy_load("_day", use_default=False)
def day(self):
return self._day + 1
@Base.lazy_load("_inning", use_default=False)
def inning(self):
return self._inning + 1
@Base.lazy_load("_statsheet_id", cache_name="_statsheet")
def statsheet(self):
return GameStatsheet.load(self._statsheet_id)[self._statsheet_id]
@Base.lazy_load("_stadium_id", cache_name="_stadium")
def stadium_id(self):
return Stadium.load_one(self._stadium_id)
@property
def stadium(self):
# stadium is an alias for stadium_id
return self.stadium_id
@Base.lazy_load("_base_runner_mod_ids", cache_name="_base_runner_mods", default_value=list())
def base_runner_mods(self):
return Modification.load(*self._base_runner_mod_ids)
@Base.lazy_load("_home_pitcher_mod_id", cache_name="_home_pitcher_mod", use_default=False)
def home_pitcher_mod(self):
return Modification.load_one(getattr(self, "_home_pitcher_mod_id", None))
@Base.lazy_load("_home_batter_mod_id", cache_name="_home_batter_mod", use_default=False)
def home_batter_mod(self):
return Modification.load_one(getattr(self, "_home_batter_mod_id", None))
@Base.lazy_load("_away_pitcher_mod_id", cache_name="_away_pitcher_mod", use_default=False)
def away_pitcher_mod(self):
return Modification.load_one(getattr(self, "_away_pitcher_mod_id", None))
@Base.lazy_load("_away_batter_mod_id", cache_name="_away_batter_mod", use_default=False)
def away_batter_mod(self):
return Modification.load_one(getattr(self, "_away_batter_mod_id", None))
@staticmethod
def _payout_calc_discipline(odds, amount):
if odds == 0.5:
return round(2 * amount)
elif odds < 0.5:
return round(amount * (2 + 0.000555 * (100 * (0.5 - odds)) ** 2.4135))
else:
return round(amount * (2 - 0.000335 * (100 * (odds - 0.5)) ** 2.045))
@staticmethod
def _payout_calc_s12(odds, amount):
if odds == 0.5:
return round(2 * amount)
elif odds < 0.5:
return round(amount * (2 + 0.0015 * (100 * (0.5 - odds)) ** 2.2))
else:
return round(amount * (0.571 + 1.429 / (1 + (3 * (odds - 0.5)) ** 0.77)))
@staticmethod
def _payout_calc(odds, amount):
if odds == 0.5:
return round(2 * amount)
elif odds < 0.5:
return round(amount * (2 + 0.0015 * (100 * (0.5 - odds)) ** 2.2))
else:
return round(amount * (3.206 / (1 + ((0.443 * (odds - 0.5)) ** 0.95)) - 1.206))
def home_payout(self, bet, season=None):
"""
Calculate the payout if the home team wins
"""
if season is None:
season = self.season
if season < 12:
return self._payout_calc_discipline(self.home_odds, bet)
elif season == 12:
return self._payout_calc_s12(self.home_odds, bet)
else:
return self._payout_calc(self.home_odds, bet)
def away_payout(self, bet, season=None):
"""
Calculate the payout if the away team wins
"""
if season is None:
season = self.season
if season < 12:
return self._payout_calc_discipline(self.away_odds, bet)
elif season == 12:
return self._payout_calc_s12(self.away_odds, bet)
else:
return self._payout_calc(self.away_odds, bet)
Classes
class Game (data, strict=False)-
Represents one blaseball game
Expand source code
class Game(Base): """ Represents one blaseball game """ @classmethod def _get_fields(cls): p = cls.load_by_id("1cbd9d82-89e6-46b2-9082-815f59e1a130") return [cls._from_api_conversion(x) for x in p.fields] @classmethod def load_by_id(cls, id_): """ Load by ID """ return cls(database.get_game_by_id(id_)) @classmethod def load_by_day(cls, season, day): """ Load by in-game season and day. Season and Day are 1-indexed """ return { id_: cls(game) for id_, game in database.get_games(season, day).items() } @classmethod def load_tournament_by_day(cls, tournament, day): """ Loads all games played in a tournament on a given in-game day. Day is 1-indexed Tournament refers to things such as the Coffee Cup which exist outside the normal blaseball timeline. """ return { id_: cls(game) for id_, game in database.get_tournament(tournament, day).items() } @classmethod def load_by_season(cls, season, team_id=None, day=None): """ Return dictionary of games for a given season keyed by game ID. Can optionally be filtered by in-game day or team ID. Season and Day are 1-indexed """ return { game["gameId"]: cls(game["data"]) for game in chronicler.get_games(team_ids=team_id, season=season, day=day) } @classmethod def load_by_tournament(cls, tournament, team_id=None, day=None): """ Return dictionary of games for a given tournament keyed by game ID. Can optionally be filtered by in-game day or team ID. Day is 1-indexed """ return { game["gameId"]: cls(game["data"]) for game in chronicler.get_games(team_ids=team_id, tournament=tournament, day=day) } @property def winning_team(self): return self.home_team if self.home_score > self.away_score else self.away_team @property def winning_team_name(self): return self.home_team_name if self.home_score > self.away_score else self.away_team_name @property def winning_team_nickname(self): return self.home_team_nickname if self.home_score > self.away_score else self.away_team_nickname @property def losing_team(self): return self.home_team if self.home_score < self.away_score else self.away_team @property def losing_team_name(self): return self.home_team_name if self.home_score < self.away_score else self.away_team_name @property def losing_team_nickname(self): return self.home_team_nickname if self.home_score < self.away_score else self.away_team_nickname @property def winning_score(self): return self.home_score if self.home_score > self.away_score else self.away_score @property def losing_score(self): return self.home_score if self.home_score < self.away_score else self.away_score @Base.lazy_load("_base_runner_ids", cache_name="_base_runners", default_value=list()) def base_runners(self): players = Player.load(*self._base_runner_ids) return [players.get(id_) for id_ in self._base_runner_ids] @Base.lazy_load("_weather", use_default=False) def weather(self): return Weather.load_one(self._weather) @Base.lazy_load("_home_team_id", cache_name="_home_team") def home_team(self): return Team.load(self._home_team_id) @Base.lazy_load("_away_team_id", cache_name="_away_team") def away_team(self): return Team.load(self._away_team_id) @Base.lazy_load("_home_pitcher_id", cache_name="_home_pitcher") def home_pitcher(self): return Player.load_one(self._home_pitcher_id) @Base.lazy_load("_away_pitcher_id", cache_name="_away_pitcher") def away_pitcher(self): return Player.load_one(self._away_pitcher_id) @Base.lazy_load("_home_batter_id", cache_name="_home_batter") def home_batter(self): return Player.load_one(self._home_batter_id) @Base.lazy_load("_away_batter_id", cache_name="_away_batter") def away_batter(self): return Player.load_one(self._away_batter_id) @property def at_bat_team(self): if self.top_of_inning: return self.away_team else: return self.home_team @property def at_bat_team_name(self): if self.top_of_inning: return self.away_team_name else: return self.home_team_name @property def at_bat_team_nickname(self): if self.top_of_inning: return self.away_team_nickname else: return self.home_team_nickname @property def pitching_team(self): if self.top_of_inning: return self.home_team else: return self.away_team @property def pitching_team_name(self): if self.top_of_inning: return self.home_team_name else: return self.away_team_name @property def pitching_team_nickname(self): if self.top_of_inning: return self.home_team_nickname else: return self.away_team_nickname @property def current_pitcher(self): if self.top_of_inning: return self.home_pitcher else: return self.away_pitcher @property def current_pitcher_name(self): if self.top_of_inning: return self.home_pitcher_name else: return self.away_pitcher_name @property def current_batter(self): if self.top_of_inning: return self.away_batter else: return self.home_batter @property def current_batter_name(self): if self.top_of_inning: return self.away_batter_name else: return self.home_batter_name @Base.lazy_load("_season", use_default=False) def season(self): return self._season + 1 @Base.lazy_load("_day", use_default=False) def day(self): return self._day + 1 @Base.lazy_load("_inning", use_default=False) def inning(self): return self._inning + 1 @Base.lazy_load("_statsheet_id", cache_name="_statsheet") def statsheet(self): return GameStatsheet.load(self._statsheet_id)[self._statsheet_id] @Base.lazy_load("_stadium_id", cache_name="_stadium") def stadium_id(self): return Stadium.load_one(self._stadium_id) @property def stadium(self): # stadium is an alias for stadium_id return self.stadium_id @Base.lazy_load("_base_runner_mod_ids", cache_name="_base_runner_mods", default_value=list()) def base_runner_mods(self): return Modification.load(*self._base_runner_mod_ids) @Base.lazy_load("_home_pitcher_mod_id", cache_name="_home_pitcher_mod", use_default=False) def home_pitcher_mod(self): return Modification.load_one(getattr(self, "_home_pitcher_mod_id", None)) @Base.lazy_load("_home_batter_mod_id", cache_name="_home_batter_mod", use_default=False) def home_batter_mod(self): return Modification.load_one(getattr(self, "_home_batter_mod_id", None)) @Base.lazy_load("_away_pitcher_mod_id", cache_name="_away_pitcher_mod", use_default=False) def away_pitcher_mod(self): return Modification.load_one(getattr(self, "_away_pitcher_mod_id", None)) @Base.lazy_load("_away_batter_mod_id", cache_name="_away_batter_mod", use_default=False) def away_batter_mod(self): return Modification.load_one(getattr(self, "_away_batter_mod_id", None)) @staticmethod def _payout_calc_discipline(odds, amount): if odds == 0.5: return round(2 * amount) elif odds < 0.5: return round(amount * (2 + 0.000555 * (100 * (0.5 - odds)) ** 2.4135)) else: return round(amount * (2 - 0.000335 * (100 * (odds - 0.5)) ** 2.045)) @staticmethod def _payout_calc_s12(odds, amount): if odds == 0.5: return round(2 * amount) elif odds < 0.5: return round(amount * (2 + 0.0015 * (100 * (0.5 - odds)) ** 2.2)) else: return round(amount * (0.571 + 1.429 / (1 + (3 * (odds - 0.5)) ** 0.77))) @staticmethod def _payout_calc(odds, amount): if odds == 0.5: return round(2 * amount) elif odds < 0.5: return round(amount * (2 + 0.0015 * (100 * (0.5 - odds)) ** 2.2)) else: return round(amount * (3.206 / (1 + ((0.443 * (odds - 0.5)) ** 0.95)) - 1.206)) def home_payout(self, bet, season=None): """ Calculate the payout if the home team wins """ if season is None: season = self.season if season < 12: return self._payout_calc_discipline(self.home_odds, bet) elif season == 12: return self._payout_calc_s12(self.home_odds, bet) else: return self._payout_calc(self.home_odds, bet) def away_payout(self, bet, season=None): """ Calculate the payout if the away team wins """ if season is None: season = self.season if season < 12: return self._payout_calc_discipline(self.away_odds, bet) elif season == 12: return self._payout_calc_s12(self.away_odds, bet) else: return self._payout_calc(self.away_odds, bet)Ancestors
- Base
- abc.ABC
Subclasses
Static methods
def load_by_day(season, day)-
Load by in-game season and day. Season and Day are 1-indexed
Expand source code
@classmethod def load_by_day(cls, season, day): """ Load by in-game season and day. Season and Day are 1-indexed """ return { id_: cls(game) for id_, game in database.get_games(season, day).items() } def load_by_id(id_)-
Load by ID
Expand source code
@classmethod def load_by_id(cls, id_): """ Load by ID """ return cls(database.get_game_by_id(id_)) def load_by_season(season, team_id=None, day=None)-
Return dictionary of games for a given season keyed by game ID. Can optionally be filtered by in-game day or team ID. Season and Day are 1-indexed
Expand source code
@classmethod def load_by_season(cls, season, team_id=None, day=None): """ Return dictionary of games for a given season keyed by game ID. Can optionally be filtered by in-game day or team ID. Season and Day are 1-indexed """ return { game["gameId"]: cls(game["data"]) for game in chronicler.get_games(team_ids=team_id, season=season, day=day) } def load_by_tournament(tournament, team_id=None, day=None)-
Return dictionary of games for a given tournament keyed by game ID. Can optionally be filtered by in-game day or team ID. Day is 1-indexed
Expand source code
@classmethod def load_by_tournament(cls, tournament, team_id=None, day=None): """ Return dictionary of games for a given tournament keyed by game ID. Can optionally be filtered by in-game day or team ID. Day is 1-indexed """ return { game["gameId"]: cls(game["data"]) for game in chronicler.get_games(team_ids=team_id, tournament=tournament, day=day) } def load_tournament_by_day(tournament, day)-
Loads all games played in a tournament on a given in-game day. Day is 1-indexed Tournament refers to things such as the Coffee Cup which exist outside the normal blaseball timeline.
Expand source code
@classmethod def load_tournament_by_day(cls, tournament, day): """ Loads all games played in a tournament on a given in-game day. Day is 1-indexed Tournament refers to things such as the Coffee Cup which exist outside the normal blaseball timeline. """ return { id_: cls(game) for id_, game in database.get_tournament(tournament, day).items() }
Instance variables
var at_bat_ballsvar at_bat_strikesvar at_bat_team-
Expand source code
@property def at_bat_team(self): if self.top_of_inning: return self.away_team else: return self.home_team var at_bat_team_name-
Expand source code
@property def at_bat_team_name(self): if self.top_of_inning: return self.away_team_name else: return self.home_team_name var at_bat_team_nickname-
Expand source code
@property def at_bat_team_nickname(self): if self.top_of_inning: return self.away_team_nickname else: return self.home_team_nickname var away_ballsvar away_basesvar away_battervar away_batter_modvar away_batter_namevar away_oddsvar away_outsvar away_pitchervar away_pitcher_modvar away_pitcher_namevar away_scorevar away_strikesvar away_teamvar away_team_batter_countvar away_team_colorvar away_team_emojivar away_team_namevar away_team_nicknamevar away_team_secondary_colorvar base_runner_modsvar base_runner_namesvar base_runnersvar baserunner_countvar bases_occupiedvar bottom_inning_scorevar current_batter-
Expand source code
@property def current_batter(self): if self.top_of_inning: return self.away_batter else: return self.home_batter var current_batter_name-
Expand source code
@property def current_batter_name(self): if self.top_of_inning: return self.away_batter_name else: return self.home_batter_name var current_pitcher-
Expand source code
@property def current_pitcher(self): if self.top_of_inning: return self.home_pitcher else: return self.away_pitcher var current_pitcher_name-
Expand source code
@property def current_pitcher_name(self): if self.top_of_inning: return self.home_pitcher_name else: return self.away_pitcher_name var dayvar end_phasevar finalizedvar game_completevar game_startvar game_start_phasevar half_inning_outsvar half_inning_scorevar home_ballsvar home_basesvar home_battervar home_batter_modvar home_batter_namevar home_oddsvar home_outsvar home_pitchervar home_pitcher_modvar home_pitcher_namevar home_scorevar home_strikesvar home_teamvar home_team_batter_countvar home_team_colorvar home_team_emojivar home_team_namevar home_team_nicknamevar home_team_secondary_colorvar idvar inningvar is_postseasonvar is_title_matchvar last_updatevar losing_score-
Expand source code
@property def losing_score(self): return self.home_score if self.home_score < self.away_score else self.away_score var losing_team-
Expand source code
@property def losing_team(self): return self.home_team if self.home_score < self.away_score else self.away_team var losing_team_name-
Expand source code
@property def losing_team_name(self): return self.home_team_name if self.home_score < self.away_score else self.away_team_name var losing_team_nickname-
Expand source code
@property def losing_team_nickname(self): return self.home_team_nickname if self.home_score < self.away_score else self.away_team_nickname var new_half_inning_phasevar new_inning_phasevar outcomesvar phasevar pitching_team-
Expand source code
@property def pitching_team(self): if self.top_of_inning: return self.home_team else: return self.away_team var pitching_team_name-
Expand source code
@property def pitching_team_name(self): if self.top_of_inning: return self.home_team_name else: return self.away_team_name var pitching_team_nickname-
Expand source code
@property def pitching_team_nickname(self): if self.top_of_inning: return self.home_team_nickname else: return self.away_team_nickname var play_countvar queued_eventsvar repeat_countvar rulesvar score_ledgervar score_updatevar seasonvar secret_baserunnervar series_indexvar series_lengthvar shamevar stadium-
Expand source code
@property def stadium(self): # stadium is an alias for stadium_id return self.stadium_id var stadium_idvar statevar statsheetvar terminologyvar top_inning_scorevar top_of_inningvar tournamentvar weathervar winning_score-
Expand source code
@property def winning_score(self): return self.home_score if self.home_score > self.away_score else self.away_score var winning_team-
Expand source code
@property def winning_team(self): return self.home_team if self.home_score > self.away_score else self.away_team var winning_team_name-
Expand source code
@property def winning_team_name(self): return self.home_team_name if self.home_score > self.away_score else self.away_team_name var winning_team_nickname-
Expand source code
@property def winning_team_nickname(self): return self.home_team_nickname if self.home_score > self.away_score else self.away_team_nickname
Methods
def away_payout(self, bet, season=None)-
Calculate the payout if the away team wins
Expand source code
def away_payout(self, bet, season=None): """ Calculate the payout if the away team wins """ if season is None: season = self.season if season < 12: return self._payout_calc_discipline(self.away_odds, bet) elif season == 12: return self._payout_calc_s12(self.away_odds, bet) else: return self._payout_calc(self.away_odds, bet) def home_payout(self, bet, season=None)-
Calculate the payout if the home team wins
Expand source code
def home_payout(self, bet, season=None): """ Calculate the payout if the home team wins """ if season is None: season = self.season if season < 12: return self._payout_calc_discipline(self.home_odds, bet) elif season == 12: return self._payout_calc_s12(self.home_odds, bet) else: return self._payout_calc(self.home_odds, bet)