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_balls
var at_bat_strikes
var 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_balls
var away_bases
var away_batter
var away_batter_mod
var away_batter_name
var away_odds
var away_outs
var away_pitcher
var away_pitcher_mod
var away_pitcher_name
var away_score
var away_strikes
var away_team
var away_team_batter_count
var away_team_color
var away_team_emoji
var away_team_name
var away_team_nickname
var away_team_secondary_color
var base_runner_mods
var base_runner_names
var base_runners
var baserunner_count
var bases_occupied
var bottom_inning_score
var 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 day
var end_phase
var finalized
var game_complete
var game_start
var game_start_phase
var half_inning_outs
var half_inning_score
var home_balls
var home_bases
var home_batter
var home_batter_mod
var home_batter_name
var home_odds
var home_outs
var home_pitcher
var home_pitcher_mod
var home_pitcher_name
var home_score
var home_strikes
var home_team
var home_team_batter_count
var home_team_color
var home_team_emoji
var home_team_name
var home_team_nickname
var home_team_secondary_color
var id
var inning
var is_postseason
var is_title_match
var last_update
var 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_phase
var new_inning_phase
var outcomes
var phase
var 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_count
var queued_events
var repeat_count
var rules
var score_ledger
var score_update
var season
var secret_baserunner
var series_index
var series_length
var shame
var stadium
-
Expand source code
@property def stadium(self): # stadium is an alias for stadium_id return self.stadium_id
var stadium_id
var state
var statsheet
var terminology
var top_inning_score
var top_of_inning
var tournament
var weather
var 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)