Early pass at matchup sim and added is_fatigued to Lineup

This commit is contained in:
Cal Corum 2024-07-07 23:13:22 -05:00
parent 76e990390b
commit 701e89eaf2
4 changed files with 391 additions and 309 deletions

View File

@ -2768,7 +2768,7 @@ class Gameplay(commands.Cog):
@app_commands.describe(
new_player='Enter the Card ID (a number)',
batting_order='Only enter this if you are forfeiting the DH')
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
@commands.has_any_role(PD_PLAYERS_ROLE_NAME)
async def sub_pitcher_command(
self, interaction: discord.Interaction, new_player: int,
batting_order: Literal['this-spot', '1', '2', '3', '4', '5', '6', '7', '8', '9'] = None):
@ -2861,6 +2861,14 @@ class Gameplay(commands.Cog):
embed=await self.initialize_play_plus_embed(this_game)
)
# @group_substitution.command(name='forfeit-dh', description='Have the pitcher bat in the DH spot')
# @commands.has_any_role(PD_PLAYERS_ROLE_NAME)
# async def sub_forfeitdh_command(self, interaction: discord.Interaction):
# this_game, owner_team, this_play = await self.checks_log_interaction(interaction)
# if False in (this_game, owner_team, this_play):
# return
#
@commands.hybrid_command(name='gamestate', help='Post the current game state', aliases=['gs'])
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME)
async def game_state_command(self, ctx: commands.Context, include_lineups: bool = True):

View File

@ -18,12 +18,19 @@ from discord.ext.commands import Greedy
import gauntlets
import helpers
# import in_game.data_cache
# import in_game.simulations
# import in_game
# # from in_game import data_cache, simulations
from in_game.data_cache import get_pd_pitchingcard, get_pd_battingcard, get_pd_player
from in_game.simulations import get_pos_embeds, get_result
from db_calls import db_get, db_post, db_patch, get_team_by_abbrev
from helpers import PD_PLAYERS_ROLE_NAME, IMAGES, PD_SEASON, random_conf_gif, fuzzy_player_search, ALL_MLB_TEAMS, \
fuzzy_search, get_channel, display_cards, get_card_embeds, get_team_embed, cardset_search, get_blank_team_card, \
get_team_by_owner, get_rosters, get_roster_sheet, legal_channel, random_conf_word, embed_pagination, get_cal_user, \
team_summary_embed, SelectView, SelectPaperdexCardset, SelectPaperdexTeam
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
# logging.basicConfig(
# filename=f'logs/{date}.log',
@ -1589,6 +1596,53 @@ class Players(commands.Cog):
this_player = await get_one_player(player_name)
logging.debug(f'this_player: {this_player}')
@app_commands.command(name='matchup', description='Simulate a matchup between a pitcher and batter')
@app_commands.describe(
pitcher_id='The pitcher\'s player_id',
batter_id='The batter\'s player_id'
)
async def matchup_command(self, interaction: discord.Interaction, pitcher_id: int, batter_id: int):
await interaction.response.defer()
try:
pit_card = await get_pd_pitchingcard(pitcher_id)
except KeyError as e:
await interaction.edit_original_response(
content=f'I could not find a pitcher card for player_id {pitcher_id}'
)
return
try:
bat_card = await get_pd_battingcard(batter_id)
except KeyError as e:
await interaction.edit_original_response(
content=f'I could not find a batter card for player_id {batter_id}'
)
return
this_pitcher = await get_pd_player(pitcher_id)
this_batter = await get_pd_player(batter_id)
# view = helpers.ButtonOptions(
# responders=[interaction.user], timeout=60,
# labels=['Reroll', None, None, None, None]
# )
await interaction.edit_original_response(
content=None,
embeds=get_pos_embeds(this_pitcher, this_batter, pit_card, bat_card),
# view=view
)
# await view.wait()
#
# if view.value:
# await question.delete()
# if view.value == 'Tagged Up':
# advance_one_runner(this_play.id, from_base=2, num_bases=1)
# elif view.value == 'Out at 3rd':
# num_outs += 1
# patch_play(this_play.id, on_second_final=False, outs=num_outs)
# else:
# await question.delete()
async def setup(bot):
await bot.add_cog(Players(bot))

View File

@ -13,7 +13,7 @@ from dataclasses import dataclass
from helpers import SBA_SEASON, PD_SEASON, get_player_url, get_sheets
from db_calls import db_get
from in_game.data_cache import get_pd_player
from in_game.data_cache import get_pd_player, CardPosition, BattingCard
db = SqliteDatabase(
'storage/gameplay.db',
@ -149,308 +149,6 @@ class ManagerAi(BaseModel):
decide_throw = IntegerField(default=5)
class StratManagerAi(pydantic.BaseModel):
id: int
name: str
steal: int = 5
running: int = 5
hold: int = 5
catcher_throw: int = 5
uncapped_home: int = 5
uncapped_third: int = 5
uncapped_trail: int = 5
bullpen_matchup: int = 5
behind_aggression: int = 5
ahead_aggression: int = 5
decide_throw: int = 5
"""
Rating Rule of Thumb:
1: Least Aggressive
5: Average
10: Most Aggressive
"""
# def __init__(self, **data) -> None:
# super().__init__(**data)
#
# seed = random.randint(1, 100)
# if seed > 95:
# self.steal = 10
# self.running = 10
# self.uncapped_third = 10
# self.uncapped_home = 10
# self.uncapped_trail = 10
# self.behind_aggression = 10
# self.ahead_aggression = 10
# elif seed > 80:
# self.steal = 8
# self.running = 8
# self.uncapped_third = 8
# self.uncapped_home = 8
# self.uncapped_trail = 8
# self.behind_aggression = 8
# self.ahead_aggression = 5
# elif seed <= 40:
# self.steal = 3
# self.running = 3
# self.uncapped_third = 3
# self.uncapped_home = 3
# self.uncapped_trail = 3
# self.behind_aggression = 5
# self.ahead_aggression = 3
# elif seed <= 15:
# self.steal = 1
# self.running = 1
# self.uncapped_third = 1
# self.uncapped_home = 1
# self.uncapped_trail = 1
# self.behind_aggression = 3
# self.ahead_aggression = 1
def check_jump(self, to_base: int, outs: int) -> Optional[str]:
"""Returns a string to be appended to the AI note"""
steal_base = f'attempt to steal'
if to_base == 2 or to_base == 3:
if self.steal == 10:
if to_base == 2:
return f'{steal_base} second if the runner has an ***** auto-jump or the safe range is 13+'
else:
steal_range = 13
elif self.steal >= 8:
steal_range = 14
elif self.steal >= 5:
steal_range = 15
elif self.steal >= 3:
steal_range = 16
else:
steal_range = 17
if outs == 2:
steal_range += 1
elif outs == 0:
steal_range -= 1
return f'{steal_base} {"second" if to_base == 2 else "third"} if their safe range is {steal_range}+'
else:
return None
def tag_from_second(self, outs: int) -> str:
"""Returns a string to be posted ahead of tag up message"""
tag_base = f'attempt to tag up if their safe range is'
if self.running >= 8:
tag_range = 5
elif self.running >= 5:
tag_range = 10
else:
tag_range = 12
if outs == 2:
tag_range += 3
elif outs == 0:
tag_range -= 2
return f'{tag_base} {tag_range}+'
def tag_from_third(self, outs: int) -> str:
"""Returns a string to be posted with the tag up message"""
tag_base = f'attempt to tag up if their safe range is'
if self.running >= 8:
tag_range = 8
elif self.running >= 5:
tag_range = 10
else:
tag_range = 12
if outs == 2:
tag_range -= 2
elif outs == 0:
tag_range += 2
return f'{tag_base} {tag_range}+'
def uncapped_advance(self, to_base: int, outs: int) -> str:
"""Returns a string to be posted with the advancement message"""
advance_base = f'attempt to advance if their safe range is'
if to_base == 3:
if self.uncapped_third >= 8:
advance_range = 14
elif self.uncapped_third >= 5:
advance_range = 18
else:
return f'not attempt to advance'
if outs == 2:
advance_range += 2
else:
if self.uncapped_home >= 8:
advance_range = 8
elif self.uncapped_home >= 5:
advance_range = 10
else:
advance_range = 12
if outs == 2:
advance_range -= 2
elif outs == 0:
advance_range += 3
return f'{advance_base} {advance_range}+'
def trail_advance(self, to_base: int, outs: int, sent_home: bool = False) -> str:
"""Returns a string to be posted with the advancement message"""
advance_base = f'attempt to advance if their safe range is'
if sent_home:
if self.uncapped_trail >= 8:
return 'attempt to advance'
elif self.uncapped_trail >= 5:
if outs == 2:
return 'attempt to advance'
else:
advance_range = 14
else:
return 'not attempt to advance'
else:
if self.uncapped_trail >= 8:
advance_range = 14
else:
advance_range = 16
return f'{advance_base} {advance_range}+'
def throw_lead_runner(self, to_base: int, outs: int) -> str:
"""Returns a string to be posted with the throw message"""
return 'throw for the lead runner'
def throw_which_runner(self, to_base: int, outs: int) -> str:
"""Returns a string to be posted with the throw message"""
if to_base == 4:
return 'throw for the lead runner'
else:
return 'throw for the lead runner if their safe range is 14-'
def gb_decide_advance(self, starting_outs: int, run_lead: int):
"""Returns a string to be posted with the advancement message"""
advance_base = f'attempt to advance if their safe range is'
if self.running >= 8:
advance_range = 10
elif self.running >= 5:
advance_range = 13
else:
advance_range = 16
if starting_outs == 1:
advance_range += 3
if run_lead >= 4:
advance_range -= 3
elif run_lead < 0:
advance_range += 3
return f'{advance_base} {min(advance_range, 20)}+'
def gb_decide_throw(self, starting_outs: int, run_lead: int):
"""Returns a string to be posted with the advancement message"""
throw_base = f'throw for the lead runner if their safe range is'
if self.decide_throw >= 8:
throw_range = 13
elif self.decide_throw >= 5:
throw_range = 10
else:
throw_range = 8
if starting_outs == 1:
throw_range -= 3
if run_lead >= 4:
throw_range -= 3
elif run_lead < 0:
throw_range += 3
return f'{throw_base} {max(throw_range, 0)}-'
def go_to_reliever(
self, this_play, tot_allowed: int, is_starter: bool = False) -> bool:
run_lead = this_play.ai_run_diff()
obc = this_play.on_base_code
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: '
f'outs: {this_play.starting_outs}, obc: {obc}, run_lead: {run_lead}, '
f'tot_allowed: {tot_allowed}')
lead_target = run_lead if is_starter else 3
# AI up big
if tot_allowed < 5 and is_starter:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 1')
return False
elif run_lead > 5 or (run_lead > 2 and self.ahead_aggression > 5):
if tot_allowed <= lead_target or obc <= 3 or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 2')
return False
elif run_lead > 2 or (run_lead >= 0 and self.ahead_aggression > 5):
if tot_allowed < lead_target or obc <= 1 or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 3')
return False
elif run_lead >= 0 or (run_lead >= -2 and self.behind_aggression > 5):
if tot_allowed < 5 or obc <= run_lead or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 4')
return False
elif run_lead >= -3 and self.behind_aggression > 5:
if tot_allowed < 5 and obc <= 1:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 5')
return False
elif run_lead <= -5:
if is_starter and this_play.inning_num <= 3:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 6')
return False
if this_play.starting_outs != 0:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 7')
return False
return True
def convert_strat_manager(manager: ManagerAi) -> StratManagerAi:
manager_dict = model_to_dict(manager)
return StratManagerAi(**manager_dict)
def get_manager(game) -> Optional[StratManagerAi]:
if not game.ai_team:
return None
# manager_ai_id = game.home_team_id if game.ai_team == 'home' else game.away_team_id
# manager_ai_id = 1
team_id = game.home_team_id if game.ai_team == 'home' else game.away_team_id
manager_ai_id = ((datetime.datetime.now().day * team_id) % 3) + 1
if manager_ai_id > 3 or manager_ai_id < 1:
manager_ai_id = 1
logging.debug(f'manager id: {manager_ai_id} for game {game}')
try:
this_manager = ManagerAi.get_by_id(manager_ai_id)
except Exception as e:
e_message = f'Could not find manager id {manager_ai_id}'
logging.error(f'{e_message}: {type(e)}: {e}')
raise KeyError(f'Could not find this AI manager\'s playbook')
return convert_strat_manager(this_manager)
def load_ai():
all_ai = [
{'name': 'Basic'}
@ -669,6 +367,7 @@ class Lineup(BaseModel):
replacing_id = IntegerField(null=True)
active = BooleanField(default=True)
variant = IntegerField(default=0)
is_fatigued = BooleanField(null=True)
@dataclass
@ -684,6 +383,7 @@ class StratLineup:
active: bool = True
card_id: int = None
variant: int = 0
is_fatigued: bool = None
def convert_stratlineup(lineup: Lineup) -> StratLineup:
@ -781,7 +481,7 @@ def post_lineups(lineups: list):
def patch_lineup(lineup_id, active: Optional[bool] = None, position: Optional[str] = None,
replacing_id: Optional[int] = None) -> StratLineup:
replacing_id: Optional[int] = None, is_fatigued: Optional[bool] = None) -> StratLineup:
this_lineup = Lineup.get_by_id(lineup_id)
if active is not None:
this_lineup.active = active
@ -789,6 +489,8 @@ def patch_lineup(lineup_id, active: Optional[bool] = None, position: Optional[st
this_lineup.position = position
if replacing_id is not None:
this_lineup.replacing_id = replacing_id
if is_fatigued is not None:
this_lineup.is_fatigued = is_fatigued
this_lineup.save()
# return_lineup = model_to_dict(this_lineup)
@ -2443,5 +2145,312 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
# f'```'
class StratManagerAi(pydantic.BaseModel):
id: int
name: str
steal: int = 5
running: int = 5
hold: int = 5
catcher_throw: int = 5
uncapped_home: int = 5
uncapped_third: int = 5
uncapped_trail: int = 5
bullpen_matchup: int = 5
behind_aggression: int = 5
ahead_aggression: int = 5
decide_throw: int = 5
"""
Rating Rule of Thumb:
1: Least Aggressive
5: Average
10: Most Aggressive
"""
# def __init__(self, **data) -> None:
# super().__init__(**data)
#
# seed = random.randint(1, 100)
# if seed > 95:
# self.steal = 10
# self.running = 10
# self.uncapped_third = 10
# self.uncapped_home = 10
# self.uncapped_trail = 10
# self.behind_aggression = 10
# self.ahead_aggression = 10
# elif seed > 80:
# self.steal = 8
# self.running = 8
# self.uncapped_third = 8
# self.uncapped_home = 8
# self.uncapped_trail = 8
# self.behind_aggression = 8
# self.ahead_aggression = 5
# elif seed <= 40:
# self.steal = 3
# self.running = 3
# self.uncapped_third = 3
# self.uncapped_home = 3
# self.uncapped_trail = 3
# self.behind_aggression = 5
# self.ahead_aggression = 3
# elif seed <= 15:
# self.steal = 1
# self.running = 1
# self.uncapped_third = 1
# self.uncapped_home = 1
# self.uncapped_trail = 1
# self.behind_aggression = 3
# self.ahead_aggression = 1
def check_jump(self, to_base: int, outs: int) -> Optional[str]:
"""Returns a string to be appended to the AI note"""
steal_base = f'attempt to steal'
if to_base == 2 or to_base == 3:
if self.steal == 10:
if to_base == 2:
return f'{steal_base} second if the runner has an ***** auto-jump or the safe range is 13+'
else:
steal_range = 13
elif self.steal >= 8:
steal_range = 14
elif self.steal >= 5:
steal_range = 15
elif self.steal >= 3:
steal_range = 16
else:
steal_range = 17
if outs == 2:
steal_range += 1
elif outs == 0:
steal_range -= 1
return f'{steal_base} {"second" if to_base == 2 else "third"} if their safe range is {steal_range}+'
else:
return None
def tag_from_second(self, outs: int) -> str:
"""Returns a string to be posted ahead of tag up message"""
tag_base = f'attempt to tag up if their safe range is'
if self.running >= 8:
tag_range = 5
elif self.running >= 5:
tag_range = 10
else:
tag_range = 12
if outs == 2:
tag_range += 3
elif outs == 0:
tag_range -= 2
return f'{tag_base} {tag_range}+'
def tag_from_third(self, outs: int) -> str:
"""Returns a string to be posted with the tag up message"""
tag_base = f'attempt to tag up if their safe range is'
if self.running >= 8:
tag_range = 8
elif self.running >= 5:
tag_range = 10
else:
tag_range = 12
if outs == 2:
tag_range -= 2
elif outs == 0:
tag_range += 2
return f'{tag_base} {tag_range}+'
def uncapped_advance(self, to_base: int, outs: int) -> str:
"""Returns a string to be posted with the advancement message"""
advance_base = f'attempt to advance if their safe range is'
if to_base == 3:
if self.uncapped_third >= 8:
advance_range = 14
elif self.uncapped_third >= 5:
advance_range = 18
else:
return f'not attempt to advance'
if outs == 2:
advance_range += 2
else:
if self.uncapped_home >= 8:
advance_range = 8
elif self.uncapped_home >= 5:
advance_range = 10
else:
advance_range = 12
if outs == 2:
advance_range -= 2
elif outs == 0:
advance_range += 3
return f'{advance_base} {advance_range}+'
# def uncapped_advance_runner(self, this_play: StratPlay, to_base: int, runner: BattingCard, defender_pos: CardPosition, modifier: int = -1):
# total_mod = modifier + defender_pos.arm
# if to_base == 3:
def trail_advance(self, to_base: int, outs: int, sent_home: bool = False) -> str:
"""Returns a string to be posted with the advancement message"""
advance_base = f'attempt to advance if their safe range is'
if sent_home:
if self.uncapped_trail >= 8:
return 'attempt to advance'
elif self.uncapped_trail >= 5:
if outs == 2:
return 'attempt to advance'
else:
advance_range = 14
else:
return 'not attempt to advance'
else:
if self.uncapped_trail >= 8:
advance_range = 14
else:
advance_range = 16
return f'{advance_base} {advance_range}+'
def throw_lead_runner(self, to_base: int, outs: int) -> str:
"""Returns a string to be posted with the throw message"""
return 'throw for the lead runner'
def throw_which_runner(self, to_base: int, outs: int) -> str:
"""Returns a string to be posted with the throw message"""
if to_base == 4:
return 'throw for the lead runner'
else:
return 'throw for the lead runner if their safe range is 14-'
def gb_decide_advance(self, starting_outs: int, run_lead: int):
"""Returns a string to be posted with the advancement message"""
advance_base = f'attempt to advance if their safe range is'
if self.running >= 8:
advance_range = 10
elif self.running >= 5:
advance_range = 13
else:
advance_range = 16
if starting_outs == 1:
advance_range += 3
if run_lead >= 4:
advance_range -= 3
elif run_lead < 0:
advance_range += 3
return f'{advance_base} {min(advance_range, 20)}+'
def gb_decide_throw(self, starting_outs: int, run_lead: int):
"""Returns a string to be posted with the advancement message"""
throw_base = f'throw for the lead runner if their safe range is'
if self.decide_throw >= 8:
throw_range = 13
elif self.decide_throw >= 5:
throw_range = 10
else:
throw_range = 8
if starting_outs == 1:
throw_range -= 3
if run_lead >= 4:
throw_range -= 3
elif run_lead < 0:
throw_range += 3
return f'{throw_base} {max(throw_range, 0)}-'
def go_to_reliever(
self, this_play, tot_allowed: int, is_starter: bool = False) -> bool:
run_lead = this_play.ai_run_diff()
obc = this_play.on_base_code
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: '
f'outs: {this_play.starting_outs}, obc: {obc}, run_lead: {run_lead}, '
f'tot_allowed: {tot_allowed}')
lead_target = run_lead if is_starter else 3
# AI up big
if tot_allowed < 5 and is_starter:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 1')
return False
elif run_lead > 5 or (run_lead > 2 and self.ahead_aggression > 5):
if tot_allowed <= lead_target or obc <= 3 or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 2')
return False
elif run_lead > 2 or (run_lead >= 0 and self.ahead_aggression > 5):
if tot_allowed < lead_target or obc <= 1 or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 3')
return False
elif run_lead >= 0 or (run_lead >= -2 and self.behind_aggression > 5):
if tot_allowed < 5 or obc <= run_lead or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 4')
return False
elif run_lead >= -3 and self.behind_aggression > 5:
if tot_allowed < 5 and obc <= 1:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 5')
return False
elif run_lead <= -5:
if is_starter and this_play.inning_num <= 3:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 6')
return False
if this_play.starting_outs != 0:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 7')
return False
return True
def convert_strat_manager(manager: ManagerAi) -> StratManagerAi:
manager_dict = model_to_dict(manager)
return StratManagerAi(**manager_dict)
def get_manager(game) -> Optional[StratManagerAi]:
if not game.ai_team:
return None
# manager_ai_id = game.home_team_id if game.ai_team == 'home' else game.away_team_id
# manager_ai_id = 1
team_id = game.home_team_id if game.ai_team == 'home' else game.away_team_id
manager_ai_id = ((datetime.datetime.now().day * team_id) % 3) + 1
if manager_ai_id > 3 or manager_ai_id < 1:
manager_ai_id = 1
logging.debug(f'manager id: {manager_ai_id} for game {game}')
try:
this_manager = ManagerAi.get_by_id(manager_ai_id)
except Exception as e:
e_message = f'Could not find manager id {manager_ai_id}'
logging.error(f'{e_message}: {type(e)}: {e}')
raise KeyError(f'Could not find this AI manager\'s playbook')
return convert_strat_manager(this_manager)
db.close()

View File

@ -5,7 +5,7 @@ import random
# import data_cache
from db_calls_gameplay import StratPlay, StratGame, get_one_lineup, get_manager, get_team_lineups, \
get_last_inning_end_play, make_sub, get_player, StratLineup, get_pitching_stats, patch_play
get_last_inning_end_play, make_sub, get_player, StratLineup, get_pitching_stats, patch_play, patch_lineup
from db_calls import db_get, db_post
from peewee import *
from typing import Optional, Literal
@ -726,6 +726,13 @@ async def check_pitching_sub(this_play: StratPlay, ai_team: dict):
async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
# Check Lineup object for 'is_fatigued'
# If yes, return True
# Else, check for fatigue below
# If fatigued, patch Lineup object with 'is_fatigued'
if this_play.pitcher.is_fatigued:
return True
used_pitchers = await get_team_lineups(
game_id=this_play.game.id,
team_id=this_play.pitcher.team_id,
@ -753,10 +760,10 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
# Check starter fatigue
if len(used_pitchers) == 1:
if ps['pl_eruns'] >= 7:
if ps['pl_runs'] >= 7:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 7+, returning True')
return True
elif ps['pl_eruns'] >= 6:
elif ps['pl_runs'] >= 6:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 6+, checking for fatigue')
f_query = get_pitching_stats(
this_play.game.id,
@ -765,8 +772,9 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
)
if f_query[0]['pl_in_runs'] >= 6:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 6 in 2, returning True')
patch_lineup(this_play.pitcher.id, is_fatigued=True)
return True
elif ps['pl_eruns'] >= 5:
elif ps['pl_runs'] >= 5:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 5+, checking for fatigue')
f_query = get_pitching_stats(
this_play.game.id,
@ -775,6 +783,7 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
)
if f_query[0]['pl_in_runs'] >= 5:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 5 in 1, returning True')
patch_lineup(this_play.pitcher.id, is_fatigued=True)
return True
innof_work = math.ceil((ps['pl_outs'] + 1) / 3)
@ -795,9 +804,11 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
elif innof_work > pof_weakness:
patch_play(this_play.id, in_pow=True)
patch_lineup(this_play.pitcher.id, is_fatigued=True)
return True
logging.info(f'ai_manager - is_pitcher_fatigued: beyond point of weakness, fatigued, returning True')
patch_lineup(this_play.pitcher.id, is_fatigued=True)
return True