468 lines
17 KiB
Python
468 lines
17 KiB
Python
import datetime
|
|
import logging
|
|
import random
|
|
|
|
import discord
|
|
|
|
# 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, \
|
|
# advance_one_runner, get_one_lineup, ai_batting, get_manager
|
|
# from db_calls import db_get, db_post
|
|
from helpers import Pagination, get_team_embed, image_embed, Confirm
|
|
from typing import Literal, Optional
|
|
|
|
PUBLIC_FIELDS_CATEGORY_NAME = 'Public Fields'
|
|
|
|
|
|
def single_onestar(this_play: StratPlay, comp_play: bool = True):
|
|
patch_play(this_play.id, locked=True)
|
|
advance_runners(this_play.id, num_bases=1)
|
|
patch_play(this_play.id, pa=1, ab=1, hit=1)
|
|
if comp_play:
|
|
complete_play(this_play.id, batter_to_base=1)
|
|
|
|
|
|
def single_wellhit(this_play: StratPlay, comp_play: bool = True):
|
|
patch_play(this_play.id, locked=True)
|
|
advance_runners(this_play.id, num_bases=2)
|
|
patch_play(this_play.id, pa=1, ab=1, hit=1)
|
|
if comp_play:
|
|
complete_play(this_play.id, batter_to_base=1)
|
|
|
|
|
|
def double_twostar(this_play: StratPlay, comp_play: bool = True):
|
|
patch_play(this_play.id, locked=True)
|
|
advance_runners(this_play.id, num_bases=2)
|
|
patch_play(this_play.id, pa=1, ab=1, hit=1, double=1)
|
|
if comp_play:
|
|
complete_play(this_play.id, batter_to_base=2)
|
|
|
|
|
|
def double_threestar(this_play: StratPlay, comp_play: bool = True):
|
|
patch_play(this_play.id, locked=True)
|
|
advance_runners(this_play.id, num_bases=3)
|
|
patch_play(this_play.id, pa=1, ab=1, hit=1, double=1)
|
|
if comp_play:
|
|
complete_play(this_play.id, batter_to_base=2)
|
|
|
|
|
|
def triple(this_play: StratPlay, comp_play: bool = True):
|
|
patch_play(this_play.id, locked=True)
|
|
advance_runners(this_play.id, num_bases=3)
|
|
patch_play(this_play.id, pa=1, ab=1, hit=1, triple=1)
|
|
if comp_play:
|
|
complete_play(this_play.id, batter_to_base=3)
|
|
|
|
|
|
async def next_pitcher(this_play: StratPlay, ai_team, bot):
|
|
used_pitchers = await get_team_lineups(
|
|
game_id=this_play.game.id, team_id=ai_team['id'], inc_inactive=True, pitchers_only=True, as_string=False
|
|
)
|
|
logging.debug(f'\n\nused_pitchers: {used_pitchers}')
|
|
|
|
used_ids = [x.card_id for x in used_pitchers]
|
|
logging.debug(f'used_ids: {used_ids}')
|
|
bullpen = get_or_create_bullpen(ai_team, bot)
|
|
logging.debug(f'bullpen: {bullpen}')
|
|
|
|
if this_play.game.short_game:
|
|
if this_play.inning_num == 1:
|
|
relievers = [bullpen.middle_two_id, bullpen.middle_one_id, bullpen.middle_three_id]
|
|
elif this_play.inning_num == 2:
|
|
relievers = [bullpen.setup_id, bullpen.middle_one_id, bullpen.middle_two_id, bullpen.middle_three_id]
|
|
elif this_play.inning_num == 3:
|
|
relievers = [
|
|
bullpen.closer_id, bullpen.setup_id, bullpen.middle_one_id, bullpen.middle_two_id,
|
|
bullpen.middle_three_id
|
|
]
|
|
else:
|
|
relievers = [
|
|
bullpen.long_one_id, bullpen.long_two_id, bullpen.long_three_id, bullpen.long_four_id,
|
|
bullpen.middle_three_id, bullpen.middle_two_id, bullpen.middle_one_id, bullpen.setup_id,
|
|
bullpen.closer_id
|
|
]
|
|
else:
|
|
if this_play.inning_num < 6:
|
|
relievers = [bullpen.long_one_id, bullpen.long_two_id, bullpen.long_three_id, bullpen.long_four_id]
|
|
elif this_play.inning_num == 6:
|
|
relievers = [bullpen.middle_two_id, bullpen.middle_one_id, bullpen.middle_three_id]
|
|
elif this_play.inning_num == 7:
|
|
relievers = [bullpen.middle_one_id, bullpen.middle_two_id, bullpen.middle_three_id]
|
|
elif this_play.inning_num == 8:
|
|
relievers = [bullpen.setup_id, bullpen.middle_one_id, bullpen.middle_two_id, bullpen.middle_three_id]
|
|
elif this_play.inning_num == 9:
|
|
relievers = [
|
|
bullpen.closer_id, bullpen.setup_id, bullpen.middle_one_id, bullpen.middle_two_id, bullpen.middle_three_id
|
|
]
|
|
else:
|
|
relievers = [
|
|
bullpen.long_one_id, bullpen.long_two_id, bullpen.long_three_id, bullpen.long_four_id,
|
|
bullpen.middle_three_id, bullpen.middle_two_id, bullpen.middle_one_id, bullpen.setup_id, bullpen.closer_id
|
|
]
|
|
|
|
for arm in relievers:
|
|
if arm and arm not in used_ids:
|
|
return {'player': await get_player(this_play.game, {'card_id': arm}), 'card_id': arm}
|
|
|
|
relievers = [
|
|
bullpen.closer_id, bullpen.setup_id, bullpen.middle_one_id, bullpen.middle_two_id, bullpen.middle_three_id,
|
|
bullpen.long_one_id, bullpen.long_two_id, bullpen.long_three_id, bullpen.long_four_id
|
|
]
|
|
|
|
for arm in relievers:
|
|
if arm and arm not in used_ids:
|
|
return {'player': await get_player(this_play.game, {'card_id': arm}), 'card_id': arm}
|
|
|
|
return {"p_name": "Backup Infielder"}
|
|
|
|
|
|
def starting_pitcher(ai_team, bot, is_home):
|
|
sheets = get_sheets(bot)
|
|
this_sheet = sheets.open_by_key(ai_team['gsheet'])
|
|
r_sheet = this_sheet.worksheet_by_title('My Rosters')
|
|
|
|
rotation_range = f'I4:I8'
|
|
raw_cells = r_sheet.range(rotation_range)
|
|
d_100 = random.randint(1, 100)
|
|
logging.info(f'raw_cells: {raw_cells} / d_100: {d_100}')
|
|
|
|
if is_home:
|
|
if d_100 <= 30:
|
|
return raw_cells[0][0].value
|
|
elif d_100 <= 55:
|
|
return raw_cells[1][0].value
|
|
elif d_100 <= 75:
|
|
return raw_cells[2][0].value
|
|
elif d_100 <= 90:
|
|
return raw_cells[3][0].value
|
|
else:
|
|
return raw_cells[4][0].value
|
|
else:
|
|
if d_100 <= 50:
|
|
return raw_cells[0][0].value
|
|
elif d_100 <= 75:
|
|
return raw_cells[1][0].value
|
|
elif d_100 <= 85:
|
|
return raw_cells[2][0].value
|
|
elif d_100 <= 95:
|
|
return raw_cells[3][0].value
|
|
else:
|
|
return raw_cells[4][0].value
|
|
|
|
|
|
# def replace_pitcher(ai_team, this_play, pitcher_card_id):
|
|
# this_card = db_get(f'cards', object_id=int(pitcher_card_id))
|
|
# new_lineup = {
|
|
# 'game_id': this_play.game.id,
|
|
# 'team_id': ai_team['id'],
|
|
# 'player_id': this_card['player']['player_id'],
|
|
# 'card_id': pitcher_card_id,
|
|
# 'position': 'P',
|
|
# 'batting_order': 10,
|
|
# 'after_play': this_play.play_num - 1
|
|
# }
|
|
# make_sub(new_lineup)
|
|
|
|
|
|
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 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):
|
|
all_ids = [str(x) for x in card_ids]
|
|
l_string = "&card_id=".join(all_ids)
|
|
legality = await db_post(f'cards/legal-check/{difficulty_name}?card_id={l_string}')
|
|
|
|
r_val = {'legal': True, 'error_string': None}
|
|
if legality['count'] > 0:
|
|
r_val['legal'] = False
|
|
r_val['error_string'] = "\n- ".join(legality['bad_cards'])
|
|
|
|
return r_val
|
|
|
|
|
|
async def show_outfield_cards(interaction: discord.Interaction, this_play: StratPlay):
|
|
lf_player = await get_player(this_play.game, as_dict=False, lineup_member=get_one_lineup(
|
|
this_play.game.id, team_id=this_play.pitcher.team_id, position='LF', active=True
|
|
))
|
|
cf_player = await get_player(this_play.game, as_dict=False, lineup_member=get_one_lineup(
|
|
this_play.game.id, team_id=this_play.pitcher.team_id, position='CF', active=True
|
|
))
|
|
rf_player = await get_player(this_play.game, as_dict=False, lineup_member=get_one_lineup(
|
|
this_play.game.id, team_id=this_play.pitcher.team_id, position='RF', active=True
|
|
))
|
|
this_team = await db_get('teams', object_id=this_play.pitcher.team_id)
|
|
logging.debug(f'lf: {lf_player}\n\ncf: {cf_player}\n\nrf: {rf_player}\n\nteam: {this_team["lname"]}')
|
|
|
|
view = Pagination([interaction.user], timeout=6)
|
|
view.left_button.label = f'Left Fielder'
|
|
view.left_button.style = discord.ButtonStyle.secondary
|
|
lf_embed = image_embed(
|
|
lf_player.image, f'{this_team["sname"]} LF', this_team['color'], lf_player.p_name, this_team['lname'],
|
|
this_team['logo'])
|
|
|
|
view.cancel_button.label = f'Center Fielder'
|
|
view.cancel_button.style = discord.ButtonStyle.blurple
|
|
cf_embed = image_embed(
|
|
cf_player.image, f'{this_team["sname"]} CF', this_team['color'], cf_player.p_name, this_team['lname'],
|
|
this_team['logo'])
|
|
|
|
view.right_button.label = f'Right Fielder'
|
|
view.right_button.style = discord.ButtonStyle.secondary
|
|
rf_embed = image_embed(
|
|
rf_player.image, f'{this_team["sname"]} RF', this_team['color'], rf_player.p_name, this_team['lname'],
|
|
this_team['logo'])
|
|
|
|
page_num = 1
|
|
embeds = [lf_embed, cf_embed, rf_embed]
|
|
|
|
msg = await interaction.channel.send(embed=embeds[page_num], view=view)
|
|
|
|
await view.wait()
|
|
|
|
if view.value:
|
|
if view.value == 'left':
|
|
page_num = 0
|
|
if view.value == 'cancel':
|
|
page_num = 1
|
|
if view.value == 'right':
|
|
page_num = 2
|
|
else:
|
|
await msg.edit(content=None, embed=embeds[page_num], view=None)
|
|
|
|
view.value = None
|
|
|
|
if page_num == 0:
|
|
view.left_button.style = discord.ButtonStyle.blurple
|
|
view.cancel_button.style = discord.ButtonStyle.secondary
|
|
view.right_button.style = discord.ButtonStyle.secondary
|
|
if page_num == 1:
|
|
view.left_button.style = discord.ButtonStyle.secondary
|
|
view.cancel_button.style = discord.ButtonStyle.blurple
|
|
view.right_button.style = discord.ButtonStyle.secondary
|
|
if page_num == 2:
|
|
view.left_button.style = discord.ButtonStyle.secondary
|
|
view.cancel_button.style = discord.ButtonStyle.secondary
|
|
view.right_button.style = discord.ButtonStyle.blurple
|
|
|
|
view.left_button.disabled = True
|
|
view.cancel_button.disabled = True
|
|
view.right_button.disabled = True
|
|
|
|
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 num_outs + this_play.starting_outs < 3:
|
|
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')
|
|
if this_play.starting_outs < 2:
|
|
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 this_play.starting_outs < 2:
|
|
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')
|
|
num_outs = 2 if this_play.starting_outs <= 1 else 1
|
|
patch_play(this_play.id, pa=1, ab=1, outs=num_outs, 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':
|
|
num_outs = 2 if this_play.starting_outs <= 1 else 1
|
|
patch_play(this_play.id, on_second_final=False, on_first_final=False, pa=1, ab=1, outs=num_outs)
|
|
return 1
|
|
else:
|
|
return gb_result_2(this_play)
|
|
|