Day 1 Gauntlet Updates

Baserunner advancement bug fixes
Pitcher sub bug fixes
This commit is contained in:
Cal Corum 2025-02-06 10:00:56 -06:00
parent 282a7e7ac2
commit db52625899
4 changed files with 155 additions and 44 deletions

View File

@ -13,6 +13,7 @@ from typing import Literal
from api_calls import db_delete, db_get, db_post
from dice import DTwentyRoll, d_twenty_roll, frame_plate_check, sa_fielding_roll
from exceptions import *
from gauntlets import post_result
from helpers import COLORS, DEFENSE_LITERAL, SBA_COLOR, get_channel, team_role
from in_game.ai_manager import get_starting_lineup
from in_game.game_helpers import PUBLIC_FIELDS_CATEGORY_NAME, legal_check
@ -225,7 +226,7 @@ async def get_scorebug_embed(session: Session, this_game: Game, full_length: boo
else:
log_exception(PositionNotFoundException, f'No catcher rating found for {curr_play.catcher.card.player.name}')
cat_string = f'{curr_play.catcher.player.name_card_link('batter')}\nArm: {"+" if pitchingcard.hold > 0 else ""}{catcher_rating.arm}, PB: {catcher_rating.pb}, OT: {catcher_rating.overthrow}'
cat_string = f'{curr_play.catcher.player.name_card_link('batter')}\nArm: {"+" if catcher_rating.arm > 0 else ""}{catcher_rating.arm}, PB: {catcher_rating.pb}, OT: {catcher_rating.overthrow}'
embed.add_field(name='Catcher', value=cat_string)
if curr_play.ai_is_batting and curr_play.on_base_code > 0:
@ -512,6 +513,33 @@ def complete_play(session:Session, this_play: Play):
new_batter_team = this_play.game.away_team if nih == 'top' else this_play.game.home_team
new_pitcher_team = this_play.game.away_team if nih == 'bot' else this_play.game.home_team
inning = this_play.inning_num if nih == 'bot' else this_play.inning_num + 1
logger.info(f'Calculate runs scored')
for this_runner, runner_dest in [
(this_play.batter, this_play.batter_final), (this_play.on_first, this_play.on_first_final), (this_play.on_second, this_play.on_second_final), (this_play.on_third, this_play.on_third_final)
]:
if runner_dest is not None:
if runner_dest == 1:
logger.info(f'{this_runner} advances to first')
if on_first is not None:
log_exception(ValueError, f'Cannot place {this_runner.player.name} on first; {on_first.player.name} is already placed there')
if not switch_sides:
on_first = this_runner
elif runner_dest == 2:
logger.info(f'{this_runner} advances to second')
if on_second is not None:
log_exception(ValueError, f'Cannot place {this_runner.player.name} on second; {on_second.player.name} is already placed there')
if not switch_sides:
on_second = this_runner
elif runner_dest == 3:
logger.info(f'{this_runner} advances to third')
if on_third is not None:
log_exception(ValueError, f'Cannot place {this_runner.player.name} on third; {on_third.player.name} is already placed there')
if not switch_sides:
on_third = this_runner
elif runner_dest == 4:
logger.info(f'{this_runner} advances to home')
runs_scored += 1
else:
switch_sides = False
@ -519,45 +547,54 @@ def complete_play(session:Session, this_play: Play):
nih = this_play.inning_half
new_batter_team = this_play.batter.team
new_pitcher_team = this_play.pitcher.team
inning = this_play.inning_num
inning = this_play.inning_num
logger.info(f'Calculate runs scored')
for this_runner, runner_dest in [
(this_play.batter, this_play.batter_final), (this_play.on_first, this_play.on_first_final), (this_play.on_second, this_play.on_second_final), (this_play.on_third, this_play.on_third_final)
]:
if runner_dest is not None:
if runner_dest == 1:
logger.info(f'{this_runner} advances to first')
if on_first is not None:
log_exception(ValueError, f'Cannot place {this_runner.player.name} on first; {on_first.player.name} is already placed there')
on_first = this_runner
if not switch_sides:
on_first = this_runner
elif runner_dest == 2:
logger.info(f'{this_runner} advances to second')
if on_second is not None:
log_exception(ValueError, f'Cannot place {this_runner.player.name} on second; {on_second.player.name} is already placed there')
on_second = this_runner
if not switch_sides:
on_second = this_runner
elif runner_dest == 3:
logger.info(f'{this_runner} advances to third')
if on_third is not None:
log_exception(ValueError, f'Cannot place {this_runner.player.name} on third; {on_third.player.name} is already placed there')
on_third = this_runner
if not switch_sides:
on_third = this_runner
elif runner_dest == 4:
logger.info(f'{this_runner} advances to home')
runs_scored += 1
if this_play.inning_half == 'top':
away_score = this_play.away_score + runs_scored
home_score = this_play.home_score
logger.info(f'Check for go-ahead run')
if runs_scored > 0 and this_play.away_score <= this_play.home_score and away_score > home_score:
this_play.is_go_ahead = True
else:
away_score = this_play.away_score
home_score = this_play.home_score + runs_scored
logger.info(f'Check for go-ahead run')
if runs_scored > 0 and this_play.home_score <= this_play.away_score and home_score > away_score:
this_play.is_go_ahead = True
obc = get_obc(on_first, on_second, on_third)
if this_play.inning_half == 'top':
away_score = this_play.away_score + runs_scored
home_score = this_play.home_score
logger.info(f'Check for go-ahead run')
if runs_scored > 0 and this_play.away_score <= this_play.home_score and away_score > home_score:
this_play.is_go_ahead = True
else:
away_score = this_play.away_score
home_score = this_play.home_score + runs_scored
logger.info(f'Check for go-ahead run')
if runs_scored > 0 and this_play.home_score <= this_play.away_score and home_score > away_score:
this_play.is_go_ahead = True
logger.info(f'Calculating re24')
this_play.re24 = get_re24(this_play, runs_scored, new_obc=obc, new_starting_outs=nso)
@ -2001,11 +2038,11 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
logger.info(f'Throw is going to lead base')
await interaction.channel.send(content=None, embeds=this_roll.embeds)
runner_thrown_out = await out_at_home(lead_safe_range) if lead_base == 4 else await out_at_base(lead_safe_range, trail_runner, trail_base)
runner_thrown_out = await ask_confirm(
interaction=interaction,
question=f'Was **{lead_runner.player.name}** thrown out {AT_BASE[lead_base]}?',
label_type='yes',
)
# runner_thrown_out = await ask_confirm(
# interaction=interaction,
# question=f'Was **{lead_runner.player.name}** thrown out {AT_BASE[lead_base]}?',
# label_type='yes',
# )
# Lead runner is thrown out
if runner_thrown_out:
@ -3212,6 +3249,17 @@ async def complete_game(session: Session, interaction: discord.Interaction, this
losing_team=losing_team,
this_game=this_game
)
if 'gauntlet' in this_game.game_type:
logger.info(f'Posting gauntlet results')
await post_result(
run_id=int(this_game.game_type.split('-')[3]),
is_win=winning_team.gmid == interaction.user.id,
this_team=this_game.human_team,
bot=None,
channel=interaction.channel,
responders=[interaction.user]
)
except Exception as e:
await roll_back(db_game['id'], plays=True, decisions=True)
log_exception(e, msg='Error while posting game rewards')
@ -3449,7 +3497,7 @@ async def groundballs(session: Session, interaction: discord.Interaction, this_p
logger.info(f'Batter out, runners hold')
this_play = gb_result_1(session, this_play)
elif this_play.on_base_code in [4, 5, 7] and groundball_letter == 'a':
elif this_play.on_base_code in [5, 7] and groundball_letter == 'a':
logger.info(f'Groundball {groundball_letter} with runners on including third')
if this_play.game.ai_team is not None and this_play.pitcher.team.is_ai:
@ -3479,8 +3527,61 @@ async def groundballs(session: Session, interaction: discord.Interaction, this_p
logger.info(f'playing back, gb 2')
this_play = gb_result_2(session, this_play)
elif this_play.on_base_code in [5, 7] and groundball_letter == 'b':
logger.info(f'Groundball {groundball_letter} with runners on including third')
if this_play.game.ai_team is not None and this_play.pitcher.team.is_ai:
def_alignment = this_play.managerai.defense_alignment(session, this_play.game)
logger.info(f'def_alignment: {def_alignment}')
to_mif = await ask_confirm(
interaction,
question='Was that hit to 2B/SS?',
label_type='yes'
)
if def_alignment.infield_in or not to_mif and def_alignment.corners_in:
playing_in = True
else:
playing_in = await ask_confirm(
interaction,
question='Was the defender playing in?',
label_type='yes'
)
if playing_in and this_play.on_base_code == 7:
logger.info(f'playing in, gb 11')
this_play = gb_result_11(session, this_play)
elif playing_in:
logger.info(f'playing in, gb 9')
this_play = gb_result_9(session, this_play)
else:
logger.info(f'playing back, gb 4')
this_play = gb_result_4(session, this_play)
else:
this_play = await gb_letter(session, interaction, this_play, groundball_letter.upper(), 'None', False)
if this_play.on_base_code in [3, 5, 6, 7]:
def_align = this_play.managerai.defense_alignment(session, this_play.game)
if def_align.infield_in:
playing_in = True
else:
to_mif = await ask_confirm(
interaction,
question='Was that ball hit to 2B/SS?',
label_type='yes'
)
if not to_mif and def_align.corners_in:
playing_in = True
else:
playing_in = False
else:
playing_in = False
this_play = await gb_letter(session, interaction, this_play, groundball_letter.upper(), 'None', playing_in)
session.add(this_play)
session.commit()

View File

@ -1771,7 +1771,7 @@ async def get_embed(this_run=None, this_event=None, this_team=None):
return embed
async def end_run(this_run, this_event, this_team, force_end: bool = False):
async def end_run(this_run, this_event, this_team: Team, force_end: bool = False):
l_message = f'Tough loss. That brings your {this_event["name"]} record to ' \
f'**{this_run["wins"]}-{this_run["losses"]}**. '
if this_run['losses'] == 2 or force_end:
@ -1781,15 +1781,15 @@ async def end_run(this_run, this_event, this_team, force_end: bool = False):
object_id=this_run['id'],
params=[('ended', True)]
)
c_query = await db_post(f'cards/wipe-team/{this_team["id"]}')
c_query = await db_post(f'cards/wipe-team/{this_team.id}')
return l_message
async def evolve_pokemon(this_team, channel, responders):
async def evolve_pokemon(this_team: Team, channel, responders):
c_query = await db_get(
'cards',
params=[('team_id', this_team['id']), ('order_by', 'new'), ('limit', 26)]
params=[('team_id', this_team.id), ('order_by', 'new'), ('limit', 26)]
)
evolvable_mons = [x for x in c_query['cards'] if x['player']['cardset']['id'] in [23] and x['player']['fangr_id'] is not None and len(x['player']['fangr_id']) > 3]
@ -1809,10 +1809,10 @@ async def evolve_pokemon(this_team, channel, responders):
await channel.send('All of your Pokemon are fully evolved!')
async def post_result(run_id: int, is_win: bool, this_team, bot, channel, responders: list[discord.User] = None):
async def post_result(run_id: int, is_win: bool, this_team: Team, bot, channel, responders: list[discord.User] = None):
this_run = await db_get('gauntletruns', object_id=run_id)
this_event = await db_get('events', object_id=this_run['gauntlet']['id'])
t_query = await db_get('teams', params=[('abbrev', f'{this_team["abbrev"].replace("Gauntlet-","")}')])
t_query = await db_get('teams', params=[('abbrev', f'{this_team.abbrev.replace("Gauntlet-","")}')])
main_team = t_query['teams'][0]
if is_win:
@ -1889,13 +1889,13 @@ async def post_result(run_id: int, is_win: bool, this_team, bot, channel, respon
await send_to_channel(
bot,
'pd-network-news',
content=f'{choas_role.mention}\n\nThe **{this_team["lname"]}** have completed the '
content=f'{choas_role.mention}\n\nThe **{this_team.lname}** have completed the '
f'**{this_event["name"]} Gauntlet** with a record of {this_run["wins"]}-'
f'{this_run["losses"]}!'
)
final_message = f'That\'s number 10! Way to go - you have completed the **{this_event["name"]} Gauntlet** ' \
f'with a record of {this_run["wins"]}-{this_run["losses"]}! '
c_query = await db_post(f'cards/wipe-team/{this_team["id"]}')
c_query = await db_post(f'cards/wipe-team/{this_team.id}')
else:
final_message = f'Big win there! Your {this_event["name"]} record is now **{this_run["wins"]}-' \
f'{this_run["losses"]}**. '

View File

@ -691,15 +691,19 @@ class ManagerAi(ManagerAiBase, table=True):
logger.info(f'Starter is cooking with {allowed_runners} runners allowed - staying in')
return False
elif run_diff > 5 or (run_diff > 2 and self.ahead_aggression > 5) and (allowed_runners < run_diff or this_play.on_base_code <= 3):
elif this_pitcher.is_fatigued and this_play.on_base_code > 1:
logger.info(f'Starter is fatigued')
return True
elif (run_diff > 5 or (run_diff > 2 and self.ahead_aggression > 5)) and (allowed_runners < run_diff or this_play.on_base_code <= 3):
logger.info(f'AI team has big lead of {run_diff} - staying in')
return False
elif run_diff > 2 or (run_diff >= 0 and self.ahead_aggression > 5) and (allowed_runners < run_diff or this_play.on_base_code <= 1):
elif (run_diff > 2 or (run_diff >= 0 and self.ahead_aggression > 5)) and (allowed_runners < run_diff or this_play.on_base_code <= 1):
logger.info(f'AI team has lead of {run_diff} - staying in')
return False
elif run_diff >= 0 or (run_diff >= -2 and self.behind_aggression > 5) and (allowed_runners < 5 and this_play.on_base_code <= run_diff):
elif (run_diff >= 0 or (run_diff >= -2 and self.behind_aggression > 5)) and (allowed_runners < 5 and this_play.on_base_code <= run_diff):
logger.info(f'AI team in close game with run diff of {run_diff} - staying in')
return False
@ -722,16 +726,20 @@ class ManagerAi(ManagerAiBase, table=True):
if outs >= pitcher_pow * 3 + 3:
logger.info(f'Only allow POW + 1 IP - pull reliever')
return True
elif this_pitcher.is_fatigued and this_play.is_new_inning:
logger.info(f'Reliever is fatigued to start the inning - pull reliever')
return True
elif run_diff > 5 or (run_diff > 2 and self.ahead_aggression > 5) and (this_play.starting_outs == 2 or allowed_runners <= run_diff or this_play.on_base_code <= 3 or this_play.starting_outs == 2):
elif (run_diff > 5 or (run_diff > 2 and self.ahead_aggression > 5)) and (this_play.starting_outs == 2 or allowed_runners <= run_diff or this_play.on_base_code <= 3 or this_play.starting_outs == 2):
logger.info(f'AI team has big lead of {run_diff} - staying in')
return False
elif run_diff > 2 or (run_diff >= 0 and self.ahead_aggression > 5) and (allowed_runners < run_diff or this_play.on_base_code <= 1 or this_play.starting_outs == 2):
elif (run_diff > 2 or (run_diff >= 0 and self.ahead_aggression > 5)) and (allowed_runners < run_diff or this_play.on_base_code <= 1 or this_play.starting_outs == 2):
logger.info(f'AI team has lead of {run_diff} - staying in')
return False
elif run_diff >= 0 or (run_diff >= -2 and self.behind_aggression > 5) and (allowed_runners < 5 or this_play.on_base_code <= run_diff or this_play.starting_outs == 2):
elif (run_diff >= 0 or (run_diff >= -2 and self.behind_aggression > 5)) and (allowed_runners < 5 or this_play.on_base_code <= run_diff or this_play.starting_outs == 2):
logger.info(f'AI team in close game with run diff of {run_diff} - staying in')
return False

View File

@ -670,6 +670,8 @@ def get_db_ready_decisions(session: Session, this_game: Game, db_game_id: int) -
}
final_inning = session.exec(select(func.max(Play.inning_num)).where(Play.game == this_game)).one()
away_starter = session.exec(select(Lineup).where(Lineup.game == this_game, Lineup.team == this_game.away_team, Lineup.position == 'P', Lineup.after_play == 0)).one()
away_pitcher = away_starter
# Get starting pitchers and update this as a pointer for the play crawl
for play in session.exec(select(Play).where(Play.game == this_game)).all():
@ -758,11 +760,11 @@ def get_db_ready_decisions(session: Session, this_game: Game, db_game_id: int) -
count += 1
if winner is None:
logger.info(f'Game {this_game.id} | Setting winner to {winner} by default on play #{play.play_num}')
winner = home_pitcher if play.inning_half == 'bot' else away_pitcher
logger.info(f'Game {this_game.id} | Setting winner to {winner} by default on play #{play.play_num}')
if loser is None:
logger.info(f'Game {this_game.id} | Setting loser to {loser} by default on play #{play.play_num}')
logger.info(f'Game {this_game.id} | Setting loser to {play.pitcher} by default on play #{play.play_num}')
loser = play.pitcher
if play.is_tied and runs_scored == 0: