Groundball Automation Update

This commit is contained in:
Cal Corum 2023-11-17 22:17:20 -06:00
parent d1e731b57d
commit 97c042c1f3
2 changed files with 256 additions and 6 deletions

View File

@ -158,6 +158,7 @@ class StratManagerAi(pydantic.BaseModel):
bullpen_matchup: int = 5
behind_aggression: int = 5
ahead_aggression: int = 5
decide_throw: int = 5
"""
Rating Rule of Thumb:
@ -335,6 +336,48 @@ class StratManagerAi(pydantic.BaseModel):
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 convert_strat_manager(manager: ManagerAi) -> StratManagerAi:
manager_dict = model_to_dict(manager)
@ -351,7 +394,7 @@ def get_manager(game) -> Optional[StratManagerAi]:
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.info(f'manager id: {manager_ai_id} for game {game}')
logging.debug(f'manager id: {manager_ai_id} for game {game}')
try:
this_manager = ManagerAi.get_by_id(manager_ai_id)

View File

@ -5,11 +5,12 @@ import random
import discord
import db_calls_gameplay
from db_calls_gameplay import StratGame, StratPlay, StratLineup, StratManagerAi, patch_play, advance_runners, \
complete_play, get_team_lineups, get_or_create_bullpen, get_player, get_sheets, make_sub, get_one_lineup
from db_calls import db_get, db_post, Player
from helpers import Pagination, get_team_embed, image_embed
complete_play, get_team_lineups, get_or_create_bullpen, get_player, get_sheets, make_sub, get_one_lineup, \
advance_one_runner, get_one_lineup, ai_batting, get_manager
from db_calls import db_get, db_post, Player, get_pd_player
from helpers import Pagination, get_team_embed, image_embed, Confirm
from typing import Literal, Optional
def single_onestar(this_play: StratPlay, comp_play: bool = True):
@ -166,7 +167,7 @@ def get_pitcher(this_game: StratGame, this_play: StratPlay):
p_team_id = this_game.away_team_id
if this_play.inning_half == 'top':
p_team_id = this_game.home_team_id
return db_calls_gameplay.get_one_lineup(this_game.id, team_id=p_team_id, position='P', active=True)
return get_one_lineup(this_game.id, team_id=p_team_id, position='P', active=True)
async def legal_check(card_ids: list, difficulty_name: str):
@ -252,3 +253,209 @@ async def show_outfield_cards(interaction: discord.Interaction, this_play: Strat
await msg.edit(content=None, embed=embeds[page_num], view=view)
return [lf_player, cf_player, rf_player][page_num]
def runner_on_first(this_play: StratPlay):
if this_play.on_base_code in [1, 4, 5, 7]:
return True
return False
def runner_on_second(this_play: StratPlay):
if this_play.on_base_code in [2, 4, 6, 7]:
return True
return False
def runner_on_third(this_play: StratPlay):
if this_play.on_base_code in [3, 5, 6, 7]:
return True
return False
def gb_result_1(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 1')
advance_runners(this_play.id, num_bases=0)
patch_play(this_play.id, pa=1, ab=1, outs=1)
return None
def gb_result_2(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 2')
num_outs = 2 if this_play.starting_outs <= 1 else 1
patch_play(this_play.id, pa=1, ab=1, outs=num_outs, on_first_final=False)
if runner_on_second(this_play):
advance_one_runner(this_play.id, from_base=2, num_bases=1)
if runner_on_third(this_play):
advance_one_runner(this_play.id, from_base=3, num_bases=1)
return None
def gb_result_3(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 3')
advance_runners(this_play.id, num_bases=1)
patch_play(this_play.id, pa=1, ab=1, outs=1)
return None
def gb_result_4(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 4')
patch_play(this_play.id, pa=1, ab=1, outs=1, on_first_final=False)
if runner_on_second(this_play):
advance_one_runner(this_play.id, from_base=2, num_bases=1)
if runner_on_third(this_play):
advance_one_runner(this_play.id, from_base=3, num_bases=1)
return 1
def gb_result_5(this_play: StratPlay, to_mif: bool) -> Optional[int]:
logging.info(f'GB 5')
patch_play(this_play.id, pa=1, ab=1, outs=1)
if to_mif:
gb_result_3(this_play)
else:
gb_result_1(this_play)
return None
def gb_result_6(this_play: StratPlay, to_right_side: bool) -> Optional[int]:
logging.info(f'GB 6')
patch_play(this_play.id, pa=1, ab=1, outs=1)
if to_right_side:
gb_result_3(this_play)
else:
gb_result_1(this_play)
return None
def gb_result_7(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 7')
patch_play(this_play.id, pa=1, ab=1, outs=1)
advance_runners(this_play.id, num_bases=1, only_forced=True)
return None
def gb_result_8(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 8')
return gb_result_7(this_play)
def gb_result_9(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 9')
return gb_result_7(this_play)
def gb_result_10(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 10')
patch_play(this_play.id, pa=1, ab=1, outs=2, on_third_final=False)
advance_one_runner(this_play.id, from_base=2, num_bases=1)
advance_one_runner(this_play.id, from_base=1, num_bases=1)
return None
def gb_result_11(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 11')
patch_play(this_play.id, pa=1, ab=1, outs=1, on_first_final=2, on_second_final=3, on_third_final=False)
return 1
async def gb_decide(this_play: StratPlay, interaction: discord.Interaction, runner: dict, from_base: int):
logging.info(f'GB Decide')
ai_is_batting = ai_batting(this_play.game, this_play)
ai_manager = get_manager(this_play.game)
bases = ['first', 'second', 'third']
ai_hint = ''
if this_play.inning_half == 'Top':
run_diff = this_play.away_score - this_play.home_score
else:
run_diff = this_play.home_score - this_play.away_score
if this_play.game.ai_team and ai_is_batting:
ai_hint = f'*The runner will ' \
f'{ai_manager.gb_decide_advance(this_play.starting_outs, run_lead=run_diff)}*'
view = Confirm(responders=[interaction.user], timeout=60, label_type='yes')
question = await interaction.channel.send(
f'Was {runner["p_name"]} sent from {bases[from_base - 1]} on the play?\n\n{ai_hint}', view=view
)
await view.wait()
if view.value:
await question.delete()
ai_hint = ''
if not ai_is_batting:
ai_hint = f'*The defense will ' \
f'{ai_manager.gb_decide_throw(this_play.starting_outs, run_lead=run_diff)}*'
view = Confirm(responders=[interaction.user], timeout=60, label_type='yes')
question = await interaction.channel.send(
f'Is the defense throwing for the lead runner?\n\n{ai_hint}', view=view
)
await view.wait()
if view.value:
await question.delete()
view = Confirm(responders=[interaction.user], timeout=60, label_type='yes')
question = await interaction.channel.send(
content=f'Was {runner["p_name"]} thrown out?', view=view
)
await view.wait()
if view.value:
await question.delete()
if this_play.on_base_code == 2:
patch_play(this_play.id, on_second_final=False, pa=1, ab=1, outs=1)
elif this_play.on_base_code == 3:
patch_play(this_play.id, on_third_final=False, pa=1, ab=1, outs=1)
elif this_play.on_base_code == 6:
patch_play(this_play.id, on_third_final=False, on_second_final=3, pa=1, ab=1, outs=1)
else:
await question.delete()
patch_play(this_play.id, pa=1, ab=1)
advance_runners(this_play.id, num_bases=1)
return 1
else:
await question.delete()
advance_runners(this_play.id, num_bases=1)
patch_play(this_play.id, pa=1, ab=1, outs=1)
return None
else:
await question.delete()
advance_runners(this_play.id, num_bases=0)
patch_play(this_play.id, pa=1, ab=1, outs=1)
return None
async def gb_result_12(this_play: StratPlay, defender: Literal['1b-2b', '3b', 'ss-p-c'],
interaction: discord.Interaction) -> Optional[int]:
logging.info(f'GB 12')
if defender == '1b-2b':
return gb_result_3(this_play)
elif defender == '3b':
return gb_result_1(this_play)
else:
return await gb_decide(
this_play, interaction, await get_player(this_play.game, this_play.on_second), from_base=2
)
def gb_result_13(this_play: StratPlay, defender: Literal['c-3b', 'else']) -> Optional[int]:
logging.info(f'GB 13')
if defender == 'c-3b':
patch_play(this_play.id, on_second_final=False, on_first_final=False, pa=1, ab=1, outs=2)
return 1
else:
return gb_result_2(this_play)