Post stats via game/play/decision

This commit is contained in:
Cal Corum 2023-10-22 13:59:22 -05:00
parent 72d6129b17
commit b39fb13a6a
2 changed files with 622 additions and 333 deletions

View File

@ -28,7 +28,7 @@ from db_calls_gameplay import StratGame, StratPlay, StratLineup, StratManagerAi,
get_current_play, post_play, get_one_lineup, advance_runners, patch_play, complete_play, get_batting_stats, \
get_pitching_stats, undo_play, get_latest_play, advance_one_runner, count_team_games, get_final_scorebug, \
get_fielding_stats, get_pitching_decisions, get_or_create_bullpen, get_active_games, patch_lineup, \
get_last_game_ids, get_plays, get_manager, get_one_game, load_ai, ai_batting, undo_subs
get_last_game_ids, get_plays, get_manager, get_one_game, load_ai, ai_batting, undo_subs, get_dbready_plays
class Gameplay(commands.Cog):
@ -115,7 +115,37 @@ class Gameplay(commands.Cog):
await ctx.send(f'{error}\n\nRun !help <command_name> to see the command requirements')
async def slash_error(self, ctx, error):
await ctx.send(f'{error}')
await ctx.send(f'{error[:1600]}')
async def post_stratgame(self, this_game: StratGame, forfeit: bool = False):
return await db_post('games', payload={
'season': this_game.season,
'game_type': this_game.game_type,
'away_team_id': this_game.away_team_id,
'home_team_id': this_game.home_team_id,
'week': this_game.week_num,
'ranked': this_game.ranked,
'short_game': this_game.short_game,
'forfeit': forfeit
})
async def post_allplays(self, this_game: StratGame, final_game_id: int):
all_plays = get_dbready_plays(this_game.id, db_game_id=final_game_id)
await asyncio.sleep(0.5)
return await db_post(
'plays',
payload={'plays': all_plays},
timeout=15
)
async def post_decisions(self, this_game: StratGame, final_game_id: int):
all_dec = get_pitching_decisions(this_game, final_game_id)
await asyncio.sleep(0.5)
return await db_post(
'decisions',
payload={'decisions': all_dec},
timeout=5
)
def get_scorebug(self, home_team, away_team, curr_play):
occupied = ''
@ -256,11 +286,6 @@ class Gameplay(commands.Cog):
game_state = {'error': False, 'curr_play': curr_play, 'away_team': away_team, 'home_team': home_team}
away_team = await get_game_team(game, team_id=game.away_team_id)
home_team = await get_game_team(game, team_id=game.home_team_id)
game_state['away_team'] = away_team
game_state['home_team'] = home_team
scorebug = self.get_scorebug(home_team, away_team, game_state['curr_play'])
game_state['scorebug'] = scorebug
@ -304,6 +329,7 @@ class Gameplay(commands.Cog):
game_state['pitcher'] = pitcher
game_state['catcher'] = catcher
game_state['channel_id'] = game.channel_id
logging.debug(f'game_state: {game_state}')
return game_state
@ -326,6 +352,7 @@ class Gameplay(commands.Cog):
title=f'{game_state["away_team"]["sname"]} @ {game_state["home_team"]["sname"]}{gt_string}',
color=int(SBA_COLOR, 16)
)
logging.debug(f'got embed')
if game.is_pd:
footer_text = f'PD Season {PD_SEASON}'
@ -349,15 +376,20 @@ class Gameplay(commands.Cog):
return embed
logging.debug(f'no errors')
embed.add_field(name='Game State', value=game_state['scorebug'], inline=False)
logging.debug(f'check mercy')
if abs(game_state['curr_play'].home_score - game_state['curr_play'].away_score) >= 10:
embed.description = '***Mercy rule in effect***'
# embed.color = discord.Colour.red()
logging.debug(f'set pitcher string')
pitcher_string = f'{player_link(game, game_state["pitcher"])}'
batter_string = f'{game_state["curr_play"].batter.batting_order}. {player_link(game, game_state["batter"])} - ' \
f'{game_state["curr_play"].batter.position}'
logging.debug(f'pull bat stats')
all_bat_stats = get_batting_stats(game.id, lineup_id=game_state['curr_play'].batter.id)
if len(all_bat_stats):
b_s = all_bat_stats[0]
@ -370,6 +402,7 @@ class Gameplay(commands.Cog):
if num:
batter_string += f', {num if num > 1 else ""}{" " if num > 1 else ""}{stat}'
logging.debug(f'pull pitcher stats')
all_pit_stats = get_pitching_stats(game.id, lineup_id=game_state['curr_play'].pitcher.id)
if len(all_pit_stats):
p_s = all_pit_stats[0]
@ -385,11 +418,13 @@ class Gameplay(commands.Cog):
if game.short_game and p_s["pl_outs"] >= 3:
pitcher_string += f'\n***F A T I G U E D***'
logging.debug(f'set embed pitcher/batter')
# embed.add_field(name='Matchup', value=f'Pitcher: \nvs\nBatter: ', inline=False)
embed.add_field(name='Pitcher', value=f'{pitcher_string}')
embed.add_field(name='Batter', value=f'{batter_string}')
embed.set_image(url=player_bcard(game_state['batter']))
logging.debug(f'get baserunners')
baserunner_string = ''
if game_state['curr_play'].on_first:
runner = await get_player(game, game_state['curr_play'].on_first)
@ -401,6 +436,7 @@ class Gameplay(commands.Cog):
runner = await get_player(game, game_state['curr_play'].on_third)
baserunner_string += f'On Third: {player_link(game, runner)}\n'
logging.debug(f'set baserunners')
if len(baserunner_string) > 0:
embed.add_field(name=' ', value=' ', inline=False)
embed.add_field(
@ -414,6 +450,7 @@ class Gameplay(commands.Cog):
name='Baserunners', value='None', inline=False
)
logging.debug(f'do AI stuff')
# If an AI team is playing
if True in [game_state['pitcher']['team']['is_ai'], game_state['batter']['team']['is_ai']]:
ai_note = ''
@ -449,6 +486,7 @@ class Gameplay(commands.Cog):
inline=False
)
logging.debug(f'if not full length: return embed: {embed}')
if not full_length:
return embed
@ -1049,7 +1087,7 @@ class Gameplay(commands.Cog):
league_name = 'minor-league'
else:
await interaction.edit_original_response(
content=f'Bonus star for speed running the Minor Leagues. The Major League campaign will release soon!')
content=f'Gold star for speed running the Minor Leagues! The Major League campaign will release soon!')
return
# elif 'Major' in league:
# can_play = False
@ -1599,15 +1637,14 @@ class Gameplay(commands.Cog):
return
latest_play = get_latest_play(this_game.id)
"""
If the game isn't over
Not 0 outs
Top of inning <= 9 and not 10-run lead
Top 9th inning or earlier and not 10-run lead
"""
if latest_play is None:
patch_game(this_game.id, active=False)
await self.post_stratgame(this_game, forfeit=True)
await send_to_channel(
self.bot, 'pd-network-news',
f'The **{owner_team["lname"]}** made an oopsie-poopsie and had to call of their game down in '
f'{interaction.channel.mention}')
this_game = patch_game(this_game.id, active=False)
await interaction.edit_original_response(
content='Roger dodger - it is game over.'
)
@ -1625,19 +1662,27 @@ class Gameplay(commands.Cog):
elif abs(latest_play.home_score - latest_play.away_score) >= 10 and latest_play.inning_half == 'bot':
valid_end = True
valid_end = True # TODO: REMOVE THIS BEFORE GO-LIVE
if not valid_end:
view = Confirm(responders=[interaction.user])
question = await interaction.channel.send(
'It doesn\'t look like this game is over, yet. I can end it, but no rewards will be paid out.\n\n'
'It doesn\'t look like this game is over, yet. I can end it, but no rewards will be paid out and '
'you will take the L.\n\n'
'Should I end this game?',
view=view
)
await view.wait()
if view.value:
patch_game(this_game.id, active=False)
await question.edit(
content='Roger dodger - it is game over.', view=None
await question.delete()
await self.post_stratgame(this_game, forfeit=True)
await send_to_channel(
self.bot, 'pd-network-news',
f'The **{owner_team["lname"]}** had to cut out early from their game down in '
f'{interaction.channel.mention}')
this_game = patch_game(this_game.id, active=False)
await interaction.edit_original_response(
content='Roger dodger - it is game over.'
)
return
@ -1658,291 +1703,64 @@ class Gameplay(commands.Cog):
await question.edit(content='It stays.', view=None)
return
away_team = await db_get('teams', object_id=this_game.away_team_id)
home_team = await db_get('teams', object_id=this_game.home_team_id)
# New database driven stat submission
failure = False
final_game = await self.post_stratgame(this_game)
away_stats = {
# 'p_lines': get_pitching_stats(this_game.id, team_id=away_team['id']),
'p_lines': [],
'b_lines': get_batting_stats(this_game.id, team_id=away_team['id']),
'f_lines': get_fielding_stats(this_game.id, team_id=away_team['id'])
}
home_stats = {
# 'p_lines': get_pitching_stats(this_game.id, team_id=home_team['id']),
'p_lines': [],
'b_lines': get_batting_stats(this_game.id, team_id=home_team['id']),
'f_lines': get_fielding_stats(this_game.id, team_id=home_team['id']),
# 'score': away_stats['p_lines'][0]['tm_runs']
}
logging.debug(f'away_stats: {away_stats}\n\nhome_stats: {home_stats}')
away_pitchers = await get_team_lineups(
this_game.id, team_id=away_team['id'], inc_inactive=True, pitchers_only=True, as_string=False
)
for line in away_pitchers:
try:
# logging.info(f'line: {line}')
this_stats = get_pitching_stats(this_game.id, lineup_id=line.id)
# logging.info(f'away / this_stats: {this_stats}')
away_stats['p_lines'].extend(this_stats)
if 'score' not in home_stats:
# logging.info(f'score not in home_stats')
home_stats['score'] = this_stats[0]['pl_runs']
else:
# logging.info(f'score is in home_stats')
home_stats['score'] += this_stats[0]['pl_runs']
if 'hits' not in home_stats:
# logging.info(f'hits not in home_stats')
home_stats['hits'] = this_stats[0]['pl_hit']
else:
# logging.info(f'hits is in home_stats')
home_stats['hits'] += this_stats[0]['pl_hit']
except Exception as e:
bad_player = await get_player(this_game, line)
logging.error(f'Unable to process stats for card_id {line.card_id} in Game {this_game.id}: '
f'{type(e)}: {e}')
await interaction.edit_original_response(
content=f'I was not able to process stats for {bad_player["name"]} - '
f'{get_cal_user(interaction).mention} help!')
home_pitchers = await get_team_lineups(
this_game.id, team_id=home_team['id'], inc_inactive=True, pitchers_only=True, as_string=False
)
for line in home_pitchers:
try:
# logging.info(f'line: {line}')
this_stats = get_pitching_stats(this_game.id, lineup_id=line.id)
# logging.info(f'home / this_stats: {this_stats}')
home_stats['p_lines'].extend(this_stats)
if 'score' not in away_stats:
# logging.info(f'score not in away_stats')
away_stats['score'] = this_stats[0]['pl_runs']
else:
# logging.info(f'score is in away_stats')
away_stats['score'] += this_stats[0]['pl_runs']
if 'hits' not in away_stats:
# logging.info(f'hits not in away_stats')
away_stats['hits'] = this_stats[0]['pl_hit']
else:
# logging.info(f'hits is in away_stats')
away_stats['hits'] += this_stats[0]['pl_hit']
except Exception as e:
bad_player = await get_player(this_game, line)
logging.error(f'Unable to process stats for card_id {line.card_id} in Game {this_game.id}: '
f'{type(e)}: {e}')
await interaction.edit_original_response(
content=f'I was not able to process stats for {bad_player["name"]} - '
f'{get_cal_user(interaction).mention} help!'
)
logging.debug(f'finished tallying pitcher stats')
# away_stats['score'] = home_stats['p_lines'][0]['tm_runs']
# Send Plays to db
try:
decisions = get_pitching_decisions(this_game)
except AttributeError as e:
logging.error(f'Could not pull decisions for Game {this_game.id}: {e}')
await interaction.edit_original_response(
content=f'I was not able to calculate the Winning and Losing Pitcher for this game. Is the game '
f'ending early? {get_cal_user(interaction).mention} can probably help.'
resp = await self.post_allplays(this_game, final_game['id'])
if not resp:
failure = True
except Exception as e:
logging.error(f'end-game - Could not post plays: {e}')
failure = True
# Send Decisions to db
try:
resp = await self.post_decisions(this_game, final_game['id'])
if not resp:
failure = True
except Exception as e:
logging.error(f'end-game - Could not post decisions: {e}')
failure = True
if failure:
try:
await db_delete(f'decisions/game', object_id=final_game["id"])
except Exception as e:
logging.error(f'could not delete decisions')
try:
await db_delete(f'plays/game', object_id=final_game["id"])
except Exception as e:
logging.error(f'could not delete plays')
try:
await db_delete(f'games', object_id=final_game["id"])
except Exception as e:
logging.error(f'could not delete game')
await interaction.channel.send(
content=f'That did not go well and I wasn\'t able to submit this game. I recommend pinging Cal so he '
f'can fix this.'
)
return
logging.debug(f'decisions: {decisions}')
winning_team = away_team if away_stats['score'] > home_stats['score'] else home_team
losing_team = away_team if away_stats['score'] < home_stats['score'] else home_team
away_team = await db_get('teams', object_id=this_game.away_team_id)
home_team = await db_get('teams', object_id=this_game.home_team_id)
winning_team = away_team if latest_play.away_score > latest_play.home_score else home_team
losing_team = away_team if latest_play.away_score < latest_play.home_score else home_team
# Post Game Rewards
r_data = await self.post_rewards(winning_team, losing_team, this_game)
win_reward = r_data['win_string']
loss_reward = r_data['loss_string']
# Check for Gauntlet game so rewards go to main team
if gauntlet_team is not None:
if winning_team['gmid'] == gauntlet_team['gmid']:
winning_team = owner_team
else:
losing_team = owner_team
logging.debug(f'away_stats (in /endgame function)\n\n{away_stats}')
logging.debug(f'home_stats (in /endgame function)\n\n{home_stats}')
logging.debug(f'winning_team: {winning_team}\nlosing_team: {losing_team}')
logging.debug(f'Time to build statlines and submit the scorecard for this PD game!')
# Post result
success = await db_post(
'results',
payload={
'away_team_id': this_game.away_team_id,
'home_team_id': this_game.home_team_id,
'away_score': away_stats['score'],
'home_score': home_stats['score'],
'away_team_ranking': away_team['ranking'],
'home_team_ranking': home_team['ranking'],
'scorecard': f'Bot Game {this_game.id}',
'week': this_game.week_num,
'season': this_game.season,
'ranked': this_game.ranked,
'short_game': this_game.short_game,
'game_type': this_game.game_type
}
)
# Submit the stats
batter_stats = []
pitcher_stats = []
doubles = ''
triples = ''
homers = ''
s_bases = ''
caught_s = ''
for line in [*away_stats['b_lines'], *home_stats['b_lines']]:
if line['pl_double']:
if len(doubles):
doubles += ', '
card = await db_get("cards", object_id=line["card_id"])
doubles += f'{card["player"]["p_name"]}' \
f'{" " if line["pl_double"] > 1 else ""}' \
f'{line["pl_double"] if line["pl_double"] > 1 else ""}'
if line['pl_triple']:
if len(triples):
triples += ', '
card = await db_get("cards", object_id=line["card_id"])
triples += f'{card["player"]["p_name"]}' \
f'{" " if line["pl_triple"] > 1 else ""}' \
f'{line["pl_triple"] if line["pl_triple"] > 1 else ""}'
if line['pl_homerun']:
if len(homers):
homers += ', '
card = await db_get("cards", object_id=line["card_id"])
homers += f'{card["player"]["p_name"]}' \
f'{" " if line["pl_homerun"] > 1 else ""}' \
f'{line["pl_homerun"] if line["pl_homerun"] > 1 else ""}'
if line['pl_sb']:
if len(s_bases):
s_bases += ', '
card = await db_get("cards", object_id=line["card_id"])
s_bases += f'{card["player"]["p_name"]}' \
f'{" " if line["pl_sb"] > 1 else ""}' \
f'{line["pl_sb"] if line["pl_sb"] > 1 else ""}'
batter_stats.append(
{
'card_id': line['card_id'],
'team_id': line['team_id'],
'roster_num':
this_game.away_roster_num if this_game.away_team_id == line['team_id']
else this_game.home_roster_num,
'vs_team_id':
home_team['id'] if this_game.away_team_id == line['team_id']
else away_team['id'],
'pos': line['pos'],
'pa': line['pl_pa'],
'ab': line['pl_ab'],
'run': line['pl_run'],
'rbi': line['pl_rbi'],
'hit': line['pl_hit'],
'double': line['pl_double'],
'triple': line['pl_triple'],
'hr': line['pl_homerun'],
'bb': line['pl_bb'],
'so': line['pl_so'],
'hbp': line['pl_hbp'],
'sac': line['pl_sac'],
'ibb': line['pl_ibb'],
'gidp': line['pl_gidp'],
'sb': line['pl_sb'],
'cs': line['pl_cs'],
'bphr': line['pl_bphr'],
'bpfo': line['pl_bpfo'],
'bp1b': line['pl_bp1b'],
'bplo': line['pl_bplo'],
'week': this_game.week_num,
'season': this_game.season,
'game_id': this_game.id,
}
)
for line in [*away_stats['f_lines'], *home_stats['f_lines']]:
if line['pl_csc']:
if len(caught_s):
caught_s += ', '
card = await db_get("cards", object_id=line["card_id"])
caught_s += f'{card["player"]["p_name"]}' \
f'{" " if line["pl_csc"] > 1 else ""}' \
f'{line["pl_csc"] if line["pl_csc"] > 1 else ""}'
batter_stats.append(
{
'card_id': line['card_id'],
'team_id': line['team_id'],
'roster_num':
this_game.away_roster_num if this_game.away_team_id == line['team_id']
else this_game.home_roster_num,
'vs_team_id':
home_team['id'] if this_game.away_team_id == line['team_id']
else away_team['id'],
'pos': line['pos'],
'xch': line['pl_xch'],
'xhit': line['pl_xhit'],
'error': line['pl_error'],
'pb': line['pl_pb'],
'sbc': line['pl_sbc'],
'csc': line['pl_csc'],
'week': this_game.week_num,
'season': this_game.season,
'game_id': this_game.id
}
)
for line in [*away_stats['p_lines'], *home_stats['p_lines']]:
pitcher_stats.append(
{
'card_id': line['card_id'],
'team_id': line['team_id'],
'roster_num':
this_game.away_roster_num if this_game.away_team_id == line['team_id']
else this_game.home_roster_num,
'vs_team_id':
home_team['id'] if this_game.away_team_id == line['team_id']
else away_team['id'],
'ip': (math.floor(line['pl_outs'] / 3) * 1.0) + ((line['pl_outs'] % 3) / 3.0),
'hit': line['pl_hit'],
'run': line['pl_runs'],
'erun': line['pl_eruns'],
'so': line['pl_so'],
'bb': line['pl_bb'],
'hbp': line['pl_hbp'],
'wp': line['pl_wild_pitch'],
'balk': line['pl_balk'],
'hr': line['pl_homerun'],
'ir': 0,
'irs': 0,
'gs': 1 if line['card_id'] in decisions['starters'] else 0,
'win': 1 if line['card_id'] == decisions['winner'] else 0,
'loss': 1 if line['card_id'] == decisions['loser'] else 0,
'hold': 1 if line['card_id'] in decisions['holds'] else 0,
'sv': 1 if line['card_id'] == decisions['save'] else 0,
'bsv': 1 if line['card_id'] in decisions['b_save'] else 0,
'week': this_game.week_num,
'season': this_game.season,
'game_id': this_game.id
}
)
doubles += '\n' if len(doubles) else ''
triples += '\n' if len(triples) else ''
homers += '\n' if len(homers) else ''
s_bases += '\n' if len(s_bases) else ''
caught_s += '\n' if len(caught_s) else ''
await db_post('batstats', payload={'stats': batter_stats})
await db_post('pitstats', payload={'stats': pitcher_stats})
# Post a notification to PD
last_play = get_current_play(this_game.id)
inning = f'{last_play.inning_num if last_play.inning_half == "Bot" else last_play.inning_num - 1}'
inning = f'{latest_play.inning_num if latest_play.inning_half == "Bot" else latest_play.inning_num - 1}'
embed = get_team_embed(
f'{away_team["lname"]} {away_stats["score"]} @ {home_stats["score"]} {home_team["lname"]} - F/'
f'{away_team["lname"]} {latest_play.away_score} @ {latest_play.home_score} {home_team["lname"]} - F/'
f'{inning}',
winning_team
)
@ -1951,6 +1769,8 @@ class Gameplay(commands.Cog):
game_des = 'Major League'
elif this_game.game_type == 'minor-league':
game_des = 'Minor League'
elif this_game.game_type == 'hall-of-fame':
game_des = 'Hall of Fame'
elif this_game.ranked:
game_des = 'Ranked'
elif 'gauntlet' in this_game.game_type:
@ -1961,40 +1781,13 @@ class Gameplay(commands.Cog):
f'{"- 3-Inning Game" if this_game.short_game else " - 9-Inning Game"}'
embed.add_field(
name='Box Score',
value=get_final_scorebug(away_team, home_team, away_stats, home_stats),
value=f'```\nTeam | R | H | E |\n```',
inline=False
)
embed.add_field(
name='Location',
value=f'{interaction.guild.get_channel(this_game.channel_id).mention}'
)
wc_query = await db_get("cards", object_id=decisions["winner"])
lc_query = await db_get("cards", object_id=decisions["loser"])
if decisions["save"]:
sv_query = await db_get("cards", object_id=decisions["save"])
embed.add_field(
name='Pitching',
value=f'Win: {wc_query["player"]["p_name"]}\n'
f'Loss: {lc_query["player"]["p_name"]}\n'
f'{"Save: " if decisions["save"] else ""}'
f'{sv_query["player"]["p_name"] if decisions["save"] else ""}',
inline=False
)
if len(doubles) + len(triples) + len(homers) > 0:
embed.add_field(
name='Batting',
value=f'{"2B: " if len(doubles) else ""}{doubles if len(doubles) else ""}'
f'{"3B: " if len(triples) else ""}{triples if len(triples) else ""}'
f'{"HR: " if len(homers) else ""}{homers if len(homers) else ""}',
inline=False
)
if len(s_bases) + len(caught_s) > 0:
embed.add_field(
name='Baserunning',
value=f'{"SB: " if len(s_bases) else ""}{s_bases if len(s_bases) else ""}'
f'{"CSc: " if len(caught_s) else ""}{caught_s if len(caught_s) else ""}',
inline=False
)
embed.add_field(
name=f'{winning_team["abbrev"]} Rewards',
value=win_reward
@ -2022,23 +1815,410 @@ class Gameplay(commands.Cog):
this_run = await db_get('gauntletruns', object_id=int(this_game.game_type.split('-')[3]))
if this_run['losses'] == 2:
await send_to_channel(
bot=self.bot,
channel_name='pd-network-news',
content=f'The {gauntlet_team["lname"]} won {this_run["wins"]} games before failing in the '
f'{this_run["gauntlet"]["name"]} gauntlet.',
embed=None
)
await send_to_channel(
bot=self.bot,
channel_name='pd-network-news',
content=f'The {gauntlet_team["lname"]} won {this_run["wins"]} games before failing in the '
f'{this_run["gauntlet"]["name"]} gauntlet.',
embed=None
)
patch_game(this_game.id, active=False)
logging.info(f'Game {this_game.id} is complete')
if gauntlet_team is None:
await interaction.edit_original_response(
content=f'Good game! Go share the highlights in '
f'{get_channel(interaction, "pd-news-ticker").mention}!'
await interaction.channel.send(
content=f'Good game! Go share the highlights in '
f'{get_channel(interaction, "pd-news-ticker").mention}!'
)
"""
END OF THE NEW GAME END
"""
# away_team = await db_get('teams', object_id=this_game.away_team_id)
# home_team = await db_get('teams', object_id=this_game.home_team_id)
#
# away_stats = {
# # 'p_lines': get_pitching_stats(this_game.id, team_id=away_team['id']),
# 'p_lines': [],
# 'b_lines': get_batting_stats(this_game.id, team_id=away_team['id']),
# 'f_lines': get_fielding_stats(this_game.id, team_id=away_team['id'])
# }
# home_stats = {
# # 'p_lines': get_pitching_stats(this_game.id, team_id=home_team['id']),
# 'p_lines': [],
# 'b_lines': get_batting_stats(this_game.id, team_id=home_team['id']),
# 'f_lines': get_fielding_stats(this_game.id, team_id=home_team['id']),
# # 'score': away_stats['p_lines'][0]['tm_runs']
# }
#
# logging.debug(f'away_stats: {away_stats}\n\nhome_stats: {home_stats}')
#
# away_pitchers = await get_team_lineups(
# this_game.id, team_id=away_team['id'], inc_inactive=True, pitchers_only=True, as_string=False
# )
# for line in away_pitchers:
# try:
# # logging.info(f'line: {line}')
# this_stats = get_pitching_stats(this_game.id, lineup_id=line.id)
# # logging.info(f'away / this_stats: {this_stats}')
# away_stats['p_lines'].extend(this_stats)
# if 'score' not in home_stats:
# # logging.info(f'score not in home_stats')
# home_stats['score'] = this_stats[0]['pl_runs']
# else:
# # logging.info(f'score is in home_stats')
# home_stats['score'] += this_stats[0]['pl_runs']
# if 'hits' not in home_stats:
# # logging.info(f'hits not in home_stats')
# home_stats['hits'] = this_stats[0]['pl_hit']
# else:
# # logging.info(f'hits is in home_stats')
# home_stats['hits'] += this_stats[0]['pl_hit']
# except Exception as e:
# bad_player = await get_player(this_game, line)
# logging.error(f'Unable to process stats for card_id {line.card_id} in Game {this_game.id}: '
# f'{type(e)}: {e}')
# await interaction.edit_original_response(
# content=f'I was not able to process stats for {bad_player["name"]} - '
# f'{get_cal_user(interaction).mention} help!')
#
# home_pitchers = await get_team_lineups(
# this_game.id, team_id=home_team['id'], inc_inactive=True, pitchers_only=True, as_string=False
# )
# for line in home_pitchers:
# try:
# # logging.info(f'line: {line}')
# this_stats = get_pitching_stats(this_game.id, lineup_id=line.id)
# # logging.info(f'home / this_stats: {this_stats}')
# home_stats['p_lines'].extend(this_stats)
# if 'score' not in away_stats:
# # logging.info(f'score not in away_stats')
# away_stats['score'] = this_stats[0]['pl_runs']
# else:
# # logging.info(f'score is in away_stats')
# away_stats['score'] += this_stats[0]['pl_runs']
# if 'hits' not in away_stats:
# # logging.info(f'hits not in away_stats')
# away_stats['hits'] = this_stats[0]['pl_hit']
# else:
# # logging.info(f'hits is in away_stats')
# away_stats['hits'] += this_stats[0]['pl_hit']
# except Exception as e:
# bad_player = await get_player(this_game, line)
# logging.error(f'Unable to process stats for card_id {line.card_id} in Game {this_game.id}: '
# f'{type(e)}: {e}')
# await interaction.edit_original_response(
# content=f'I was not able to process stats for {bad_player["name"]} - '
# f'{get_cal_user(interaction).mention} help!'
# )
#
# logging.debug(f'finished tallying pitcher stats')
#
# # away_stats['score'] = home_stats['p_lines'][0]['tm_runs']
# try:
# decisions = get_pitching_decisions(this_game)
# except AttributeError as e:
# logging.error(f'Could not pull decisions for Game {this_game.id}: {e}')
# await interaction.edit_original_response(
# content=f'I was not able to calculate the Winning and Losing Pitcher for this game. Is the game '
# f'ending early? {get_cal_user(interaction).mention} can probably help.'
# )
# return
# logging.debug(f'decisions: {decisions}')
#
# winning_team = away_team if away_stats['score'] > home_stats['score'] else home_team
# losing_team = away_team if away_stats['score'] < home_stats['score'] else home_team
#
# # Post Game Rewards
# r_data = await self.post_rewards(winning_team, losing_team, this_game)
# win_reward = r_data['win_string']
# loss_reward = r_data['loss_string']
#
# # Check for Gauntlet game so rewards go to main team
# if gauntlet_team is not None:
# if winning_team['gmid'] == gauntlet_team['gmid']:
# winning_team = owner_team
# else:
# losing_team = owner_team
#
# logging.debug(f'away_stats (in /endgame function)\n\n{away_stats}')
# logging.debug(f'home_stats (in /endgame function)\n\n{home_stats}')
# logging.debug(f'winning_team: {winning_team}\nlosing_team: {losing_team}')
#
# logging.debug(f'Time to build statlines and submit the scorecard for this PD game!')
# # Post result
# success = await db_post(
# 'results',
# payload={
# 'away_team_id': this_game.away_team_id,
# 'home_team_id': this_game.home_team_id,
# 'away_score': away_stats['score'],
# 'home_score': home_stats['score'],
# 'away_team_ranking': away_team['ranking'],
# 'home_team_ranking': home_team['ranking'],
# 'scorecard': f'Bot Game {this_game.id}',
# 'week': this_game.week_num,
# 'season': this_game.season,
# 'ranked': this_game.ranked,
# 'short_game': this_game.short_game,
# 'game_type': this_game.game_type
# }
# )
# # Submit the stats
# batter_stats = []
# pitcher_stats = []
# doubles = ''
# triples = ''
# homers = ''
# s_bases = ''
# caught_s = ''
#
# for line in [*away_stats['b_lines'], *home_stats['b_lines']]:
# if line['pl_double']:
# if len(doubles):
# doubles += ', '
# card = await db_get("cards", object_id=line["card_id"])
# doubles += f'{card["player"]["p_name"]}' \
# f'{" " if line["pl_double"] > 1 else ""}' \
# f'{line["pl_double"] if line["pl_double"] > 1 else ""}'
# if line['pl_triple']:
# if len(triples):
# triples += ', '
# card = await db_get("cards", object_id=line["card_id"])
# triples += f'{card["player"]["p_name"]}' \
# f'{" " if line["pl_triple"] > 1 else ""}' \
# f'{line["pl_triple"] if line["pl_triple"] > 1 else ""}'
# if line['pl_homerun']:
# if len(homers):
# homers += ', '
# card = await db_get("cards", object_id=line["card_id"])
# homers += f'{card["player"]["p_name"]}' \
# f'{" " if line["pl_homerun"] > 1 else ""}' \
# f'{line["pl_homerun"] if line["pl_homerun"] > 1 else ""}'
# if line['pl_sb']:
# if len(s_bases):
# s_bases += ', '
# card = await db_get("cards", object_id=line["card_id"])
# s_bases += f'{card["player"]["p_name"]}' \
# f'{" " if line["pl_sb"] > 1 else ""}' \
# f'{line["pl_sb"] if line["pl_sb"] > 1 else ""}'
# batter_stats.append(
# {
# 'card_id': line['card_id'],
# 'team_id': line['team_id'],
# 'roster_num':
# this_game.away_roster_num if this_game.away_team_id == line['team_id']
# else this_game.home_roster_num,
# 'vs_team_id':
# home_team['id'] if this_game.away_team_id == line['team_id']
# else away_team['id'],
# 'pos': line['pos'],
# 'pa': line['pl_pa'],
# 'ab': line['pl_ab'],
# 'run': line['pl_run'],
# 'rbi': line['pl_rbi'],
# 'hit': line['pl_hit'],
# 'double': line['pl_double'],
# 'triple': line['pl_triple'],
# 'hr': line['pl_homerun'],
# 'bb': line['pl_bb'],
# 'so': line['pl_so'],
# 'hbp': line['pl_hbp'],
# 'sac': line['pl_sac'],
# 'ibb': line['pl_ibb'],
# 'gidp': line['pl_gidp'],
# 'sb': line['pl_sb'],
# 'cs': line['pl_cs'],
# 'bphr': line['pl_bphr'],
# 'bpfo': line['pl_bpfo'],
# 'bp1b': line['pl_bp1b'],
# 'bplo': line['pl_bplo'],
# 'week': this_game.week_num,
# 'season': this_game.season,
# 'game_id': this_game.id,
# }
# )
#
# for line in [*away_stats['f_lines'], *home_stats['f_lines']]:
# if line['pl_csc']:
# if len(caught_s):
# caught_s += ', '
# card = await db_get("cards", object_id=line["card_id"])
# caught_s += f'{card["player"]["p_name"]}' \
# f'{" " if line["pl_csc"] > 1 else ""}' \
# f'{line["pl_csc"] if line["pl_csc"] > 1 else ""}'
# batter_stats.append(
# {
# 'card_id': line['card_id'],
# 'team_id': line['team_id'],
# 'roster_num':
# this_game.away_roster_num if this_game.away_team_id == line['team_id']
# else this_game.home_roster_num,
# 'vs_team_id':
# home_team['id'] if this_game.away_team_id == line['team_id']
# else away_team['id'],
# 'pos': line['pos'],
# 'xch': line['pl_xch'],
# 'xhit': line['pl_xhit'],
# 'error': line['pl_error'],
# 'pb': line['pl_pb'],
# 'sbc': line['pl_sbc'],
# 'csc': line['pl_csc'],
# 'week': this_game.week_num,
# 'season': this_game.season,
# 'game_id': this_game.id
# }
# )
#
# for line in [*away_stats['p_lines'], *home_stats['p_lines']]:
# pitcher_stats.append(
# {
# 'card_id': line['card_id'],
# 'team_id': line['team_id'],
# 'roster_num':
# this_game.away_roster_num if this_game.away_team_id == line['team_id']
# else this_game.home_roster_num,
# 'vs_team_id':
# home_team['id'] if this_game.away_team_id == line['team_id']
# else away_team['id'],
# 'ip': (math.floor(line['pl_outs'] / 3) * 1.0) + ((line['pl_outs'] % 3) / 3.0),
# 'hit': line['pl_hit'],
# 'run': line['pl_runs'],
# 'erun': line['pl_eruns'],
# 'so': line['pl_so'],
# 'bb': line['pl_bb'],
# 'hbp': line['pl_hbp'],
# 'wp': line['pl_wild_pitch'],
# 'balk': line['pl_balk'],
# 'hr': line['pl_homerun'],
# 'ir': 0,
# 'irs': 0,
# 'gs': 1 if line['card_id'] in decisions['starters'] else 0,
# 'win': 1 if line['card_id'] == decisions['winner'] else 0,
# 'loss': 1 if line['card_id'] == decisions['loser'] else 0,
# 'hold': 1 if line['card_id'] in decisions['holds'] else 0,
# 'sv': 1 if line['card_id'] == decisions['save'] else 0,
# 'bsv': 1 if line['card_id'] in decisions['b_save'] else 0,
# 'week': this_game.week_num,
# 'season': this_game.season,
# 'game_id': this_game.id
# }
# )
#
# doubles += '\n' if len(doubles) else ''
# triples += '\n' if len(triples) else ''
# homers += '\n' if len(homers) else ''
# s_bases += '\n' if len(s_bases) else ''
# caught_s += '\n' if len(caught_s) else ''
#
# await db_post('batstats', payload={'stats': batter_stats})
# await db_post('pitstats', payload={'stats': pitcher_stats})
#
# # Post a notification to PD
# last_play = get_current_play(this_game.id)
# inning = f'{last_play.inning_num if last_play.inning_half == "Bot" else last_play.inning_num - 1}'
# embed = get_team_embed(
# f'{away_team["lname"]} {away_stats["score"]} @ {home_stats["score"]} {home_team["lname"]} - F/'
# f'{inning}',
# winning_team
# )
#
# if this_game.game_type == 'major-league':
# game_des = 'Major League'
# elif this_game.game_type == 'minor-league':
# game_des = 'Minor League'
# elif this_game.game_type == 'hall-of-fame':
# game_des = 'Hall of Fame'
# elif this_game.ranked:
# game_des = 'Ranked'
# elif 'gauntlet' in this_game.game_type:
# game_des = 'Gauntlet'
# else:
# game_des = 'Unlimited'
# embed.description = f'Score Report - {game_des} ' \
# f'{"- 3-Inning Game" if this_game.short_game else " - 9-Inning Game"}'
# embed.add_field(
# name='Box Score',
# value=get_final_scorebug(away_team, home_team, away_stats, home_stats),
# inline=False
# )
# embed.add_field(
# name='Location',
# value=f'{interaction.guild.get_channel(this_game.channel_id).mention}'
# )
# wc_query = await db_get("cards", object_id=decisions["winner"])
# lc_query = await db_get("cards", object_id=decisions["loser"])
# if decisions["save"]:
# sv_query = await db_get("cards", object_id=decisions["save"])
# embed.add_field(
# name='Pitching',
# value=f'Win: {wc_query["player"]["p_name"]}\n'
# f'Loss: {lc_query["player"]["p_name"]}\n'
# f'{"Save: " if decisions["save"] else ""}'
# f'{sv_query["player"]["p_name"] if decisions["save"] else ""}',
# inline=False
# )
# if len(doubles) + len(triples) + len(homers) > 0:
# embed.add_field(
# name='Batting',
# value=f'{"2B: " if len(doubles) else ""}{doubles if len(doubles) else ""}'
# f'{"3B: " if len(triples) else ""}{triples if len(triples) else ""}'
# f'{"HR: " if len(homers) else ""}{homers if len(homers) else ""}',
# inline=False
# )
# if len(s_bases) + len(caught_s) > 0:
# embed.add_field(
# name='Baserunning',
# value=f'{"SB: " if len(s_bases) else ""}{s_bases if len(s_bases) else ""}'
# f'{"CSc: " if len(caught_s) else ""}{caught_s if len(caught_s) else ""}',
# inline=False
# )
# embed.add_field(
# name=f'{winning_team["abbrev"]} Rewards',
# value=win_reward
# )
# embed.add_field(
# name=f'{losing_team["abbrev"]} Rewards',
# value=loss_reward
# )
# embed.add_field(
# name='Highlights',
# value=f'Please share the highlights in {get_channel(interaction, "pd-news-ticker").mention}!',
# inline=False
# )
# await send_to_channel(self.bot, 'pd-network-news', embed=embed)
#
# # Gauntlet results and reward
# if gauntlet_team is not None:
# await gauntlets.post_result(
# int(this_game.game_type.split('-')[3]),
# is_win=winning_team['gmid'] == gauntlet_team['gmid'],
# this_team=gauntlet_team,
# bot=self.bot,
# channel=interaction.channel
# )
#
# this_run = await db_get('gauntletruns', object_id=int(this_game.game_type.split('-')[3]))
# if this_run['losses'] == 2:
# await send_to_channel(
# bot=self.bot,
# channel_name='pd-network-news',
# content=f'The {gauntlet_team["lname"]} won {this_run["wins"]} games before failing in the '
# f'{this_run["gauntlet"]["name"]} gauntlet.',
# embed=None
# )
#
# patch_game(this_game.id, active=False)
#
# logging.info(f'Game {this_game.id} is complete')
# if gauntlet_team is None:
# await interaction.edit_original_response(
# content=f'Good game! Go share the highlights in '
# f'{get_channel(interaction, "pd-news-ticker").mention}!'
# )
@app_commands.command(
name='read-lineup',
description='Import a saved lineup directly from the team sheet for PD games'

View File

@ -109,6 +109,24 @@ def get_sba_team_by_owner(season, owner_id):
# return pd_await db_get('cards', object_id=card_id, none_okay=False)
class DecisionModel(pydantic.BaseModel):
game_id: int
season: int
week: int
pitcher_id: int
pitcher_team_id: int
win: int = 0
loss: int = 0
hold: int = 0
is_save: int = 0
is_start: bool = False
b_save: int = 0
irunners: int = 0
irunners_scored: int = 0
rest_ip: float = 0
rest_required: int = 0
class BaseModel(Model):
class Meta:
database = db
@ -810,6 +828,7 @@ class Play(BaseModel):
game = ForeignKeyField(Game)
play_num = IntegerField()
batter = ForeignKeyField(Lineup)
batter_pos = CharField(default='DH')
pitcher = ForeignKeyField(Lineup, null=True)
on_base_code = IntegerField()
inning_half = CharField()
@ -818,6 +837,7 @@ class Play(BaseModel):
starting_outs = IntegerField()
away_score = IntegerField()
home_score = IntegerField()
on_first = ForeignKeyField(Lineup, null=True)
on_first_final = IntegerField(null=True)
on_second = ForeignKeyField(Lineup, null=True)
@ -825,9 +845,11 @@ class Play(BaseModel):
on_third = ForeignKeyField(Lineup, null=True)
on_third_final = IntegerField(null=True)
batter_final = IntegerField(null=True)
pa = IntegerField(default=0)
ab = IntegerField(default=0)
# run = IntegerField(null=True)
run = IntegerField(default=0)
e_run = IntegerField(default=0)
hit = IntegerField(default=0)
rbi = IntegerField(default=0)
double = IntegerField(default=0)
@ -846,6 +868,10 @@ class Play(BaseModel):
sb = IntegerField(default=0)
cs = IntegerField(default=0)
outs = IntegerField(default=0)
wpa = FloatField(default=0.0)
re24 = FloatField(default=0.0)
catcher = ForeignKeyField(Lineup, null=True)
defender = ForeignKeyField(Lineup, null=True)
runner = ForeignKeyField(Lineup, null=True)
@ -876,6 +902,8 @@ class StratPlay:
starting_outs: int
away_score: int
home_score: int
batter_pos: str = None
on_first: StratLineup = None
on_first_final: int = None
on_second: StratLineup = None
@ -883,9 +911,11 @@ class StratPlay:
on_third: StratLineup = None
on_third_final: int = None
batter_final: int = None
pa: int = 0
ab: int = 0
# run: int = 0
run: int = 0
e_run: int = 0
hit: int = 0
rbi: int = 0
double: int = 0
@ -904,9 +934,14 @@ class StratPlay:
sb: int = 0
cs: int = 0
outs: int = 0
wpa: float = 0.0
re24: float = 0.0
catcher: StratLineup = None
defender: StratLineup = None
runner: StratLineup = None
check_pos: str = None
error: int = 0
wild_pitch: int = 0
@ -1171,6 +1206,31 @@ def get_last_inning_end_play(game_id, inning_half, inning_num):
return return_play
def get_dbready_plays(game_id: int, db_game_id: int):
all_plays = Play.select().where(Play.game_id == game_id)
prep_plays = [model_to_dict(x) for x in all_plays]
db.close()
for x in prep_plays:
x['pitcher_id'] = x['pitcher']['player_id']
x['batter_id'] = x['batter']['player_id']
x['batter_team_id'] = x['batter']['team_id']
x['pitcher_team_id'] = x['pitcher']['team_id']
if x['catcher'] is not None:
x['catcher_id'] = x['catcher']['player_id']
x['catcher_team_id'] = x['catcher']['team_id']
if x['defender'] is not None:
x['defender_id'] = x['defender']['player_id']
x['defender_team_id'] = x['defender']['team_id']
if x['runner'] is not None:
x['runner_id'] = x['runner']['player_id']
x['runner_team_id'] = x['runner']['team_id']
x['game_id'] = db_game_id
logging.debug(f'all_plays:\n\n{prep_plays}\n')
return prep_plays
class Bullpen(BaseModel):
ai_team_id = IntegerField()
closer_id = IntegerField()
@ -1993,7 +2053,7 @@ def get_pitching_stats(game_id, lineup_id: int = None, team_id: int = None):
return return_pitchers
def get_pitching_decisions(game: StratGame):
def get_pitching_decisions(game: StratGame, db_game_id: int):
# is_win, is_hold, is_loss = False, False, False
# away_lineups = get_team_lineups(game.id, game.away_team_id)
# home_lineups = get_team_lineups(game.id, game.home_team_id)
@ -2015,6 +2075,25 @@ def get_pitching_decisions(game: StratGame):
gs.extend([away_pitcher.card_id, home_pitcher.card_id])
logging.debug(f'SPs: {away_pitcher} / {home_pitcher}')
decisions = {
away_pitcher.player_id: DecisionModel(
game_id=db_game_id,
season=game.season,
week=game.week_num,
pitcher_id=away_pitcher.player_id,
pitcher_team_id=away_pitcher.team_id,
is_start=True
),
home_pitcher.player_id: DecisionModel(
game_id=db_game_id,
season=game.season,
week=game.week_num,
pitcher_id=home_pitcher.player_id,
pitcher_team_id=home_pitcher.team_id,
is_start=True
)
} # { <player_id>: DecisionModel }
for x in Play.select().where(Play.game_id == game.id):
logging.debug(f'checking play num {x.play_num}')
if x.inning_half == 'Top' and home_pitcher != x.pitcher:
@ -2108,6 +2187,36 @@ def get_pitching_decisions(game: StratGame):
b_save.append(save.card_id)
save = None
if home_pitcher.player_id not in decisions:
decisions[home_pitcher.player_id] = DecisionModel(
game_id=db_game_id,
season=game.season,
week=game.week_num,
pitcher_id=home_pitcher.player_id,
pitcher_team_id=home_pitcher.team_id
)
if away_pitcher.player_id not in decisions:
decisions[away_pitcher.player_id] = DecisionModel(
game_id=db_game_id,
season=game.season,
week=game.week_num,
pitcher_id=away_pitcher.player_id,
pitcher_team_id=away_pitcher.team_id
)
decisions[winner.player_id].win = 1
decisions[loser.player_id].loss = 1
if save is not None:
decisions[save.player_id].is_save = 1
for x in holds:
decisions[x.player_id].hold = 1
for x in b_save:
decisions[x.player_id].b_save = 1
return [x.dict() for x in decisions.values()]
logging.debug(f'\n\nWin: {winner}\nLose: {loser}\nSave: {save}\nBlown Save: {b_save}\nHolds: {holds}')
return {
'winner': winner.card_id,
@ -2153,7 +2262,7 @@ def get_pitching_decisions(game: StratGame):
# if next_p_first.away_score < next_p_first.home_score:
def get_final_scorebug(away_team, home_team, away_stats, home_stats):
def get_final_scorebug(away_team, home_team, away_score, home_score):
return f'```' \
f'Team | R | H | E |\n' \
f'{away_team["abbrev"].replace("Gauntlet-", ""): <4} | {away_stats["score"]: >2} | ' \