Add support for Exhibition games

This commit is contained in:
Cal Corum 2024-07-11 15:08:06 -05:00
parent 701e89eaf2
commit 2046ebcdde
5 changed files with 345 additions and 19 deletions

View File

@ -9,6 +9,7 @@ from discord import Member
from discord.ext import commands, tasks from discord.ext import commands, tasks
from discord import app_commands from discord import app_commands
import in_game import in_game
from in_game import ai_manager
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}' # date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
@ -511,6 +512,51 @@ class Admins(commands.Cog):
await ctx.channel.send(f'Checking fatigue for Play #{play_id} / ' await ctx.channel.send(f'Checking fatigue for Play #{play_id} / '
f'Pitcher {"IS" if is_fatigued else "IS NOT"} fatigued') f'Pitcher {"IS" if is_fatigued else "IS NOT"} fatigued')
@commands.command(name='test-exhibition', help='Mod: Test the lineup gen for exhibition games')
@commands.is_owner()
async def test_exhibition_command(
self, ctx, which: Literal['sp', 'rp', 'lineup'], team_id: int, cardset_ids: str, backup_cardset_ids: str):
if which == 'sp':
await ctx.send(f'Fetching a SP for Team ID {team_id}...')
this_pitcher = await ai_manager.get_starting_pitcher(
{'id': team_id},
game_id=69,
is_home=True,
league_name='exhibition'
)
await ctx.send(f'Selected Pitcher:\n{this_pitcher}')
# elif which == 'rp':
# await ctx.send(f'Fetching an RP for Team ID {team_id}...')
@commands.command(name='test-dropdown', help='Mod: Test the custom dropdown objects')
@commands.is_owner()
async def test_dropdown_command(self, ctx):
options = [
discord.SelectOption(label='2024 Live', value='17'),
discord.SelectOption(label='2018 Live', value='13'),
discord.SelectOption(label='2016 Live', value='11'),
discord.SelectOption(label='2008 Live', value='12'),
discord.SelectOption(label='2007 Live', value='07'),
discord.SelectOption(label='2006 Live', value='06'),
discord.SelectOption(label='2005 Live', value='05'),
discord.SelectOption(label='2004 Live', value='04'),
discord.SelectOption(label='2003 Live', value='03'),
discord.SelectOption(label='2002 Live', value='02'),
]
async def my_callback(interaction: discord.Interaction, values):
await interaction.response.send_message(
f'Your selection{"s are" if len(values) > 1 else " is"}: {", ".join(values)}')
my_dropdown = Dropdown(
option_list=options,
placeholder='Select a cardset',
callback=my_callback,
max_values=8
)
view = DropdownView([my_dropdown])
await ctx.send(f'Here is your dropdown:', view=view)
async def setup(bot): async def setup(bot):
await bot.add_cog(Admins(bot)) await bot.add_cog(Admins(bot))

View File

@ -18,7 +18,8 @@ from dice import sa_fielding_roll
from helpers import SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME, random_conf_gif, SBA_SEASON, PD_SEASON, IMAGES, \ from helpers import SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME, random_conf_gif, SBA_SEASON, PD_SEASON, IMAGES, \
get_pos_abbrev, SBA_COLOR, get_roster_lineups, give_packs, send_to_channel, \ get_pos_abbrev, SBA_COLOR, get_roster_lineups, give_packs, send_to_channel, \
get_channel, team_role, get_cal_user, ButtonOptions, get_ratings_guide, \ get_channel, team_role, get_cal_user, ButtonOptions, get_ratings_guide, \
get_team_by_owner, player_desc, player_pcard, player_bcard, get_team_embed, Confirm, get_sheets get_team_by_owner, player_desc, player_pcard, player_bcard, get_team_embed, Confirm, get_sheets, Dropdown, \
SELECT_CARDSET_OPTIONS, DropdownView
from in_game.ai_manager import check_pitching_sub from in_game.ai_manager import check_pitching_sub
from in_game.game_helpers import single_onestar, single_wellhit, double_twostar, double_threestar, triple, \ from in_game.game_helpers import single_onestar, single_wellhit, double_twostar, double_threestar, triple, \
runner_on_first, runner_on_second, runner_on_third, gb_result_1, gb_result_2, gb_result_3, gb_result_4, \ runner_on_first, runner_on_second, runner_on_third, gb_result_1, gb_result_2, gb_result_3, gb_result_4, \
@ -365,6 +366,8 @@ class Gameplay(commands.Cog):
gt_string = ' - Gauntlet' gt_string = ' - Gauntlet'
elif 'flashback' in game.game_type: elif 'flashback' in game.game_type:
gt_string = ' - Flashback' gt_string = ' - Flashback'
elif 'exhibition' in game.game_type:
gt_string = ' - Exhibition'
if game_state['error']: if game_state['error']:
embed = discord.Embed( embed = discord.Embed(
@ -1718,6 +1721,237 @@ class Gameplay(commands.Cog):
) )
return return
@group_new_game.command(name='exhibition', description='Start a new custom game against an AI')
@commands.has_any_role(PD_PLAYERS_ROLE_NAME)
async def new_game_exhibition_command(
self, interaction: discord.Interaction, away_team_abbrev: str, home_team_abbrev: str, sp_card_id: int,
num_innings: Literal[9, 3] = 9,
cardsets: Literal['Minor League', 'Major League', 'Hall of Fame', 'Flashback', 'Custom'] = 'Custom'):
await interaction.response.defer()
conflict = get_one_game(channel_id=interaction.channel.id, active=True)
if conflict:
await interaction.edit_original_response(
content=f'Ope. There is already a game going on in this channel. Please wait for it to complete '
f'before starting a new one.')
return
try:
if interaction.channel.category.name != 'Public Fields':
await interaction.response.send_message(
f'Why don\'t you head down to one of the Public Fields that way other humans can help if anything '
f'pops up?'
)
return
except Exception as e:
logging.error(f'Could not check channel category: {e}')
away_team = await get_team_by_abbrev(away_team_abbrev)
home_team = await get_team_by_abbrev(home_team_abbrev)
if not away_team:
await interaction.edit_original_response(
content=f'Sorry, I don\'t know who **{away_team_abbrev.upper()}** is.'
)
return
if not home_team:
await interaction.edit_original_response(
content=f'Sorry, I don\'t know who **{home_team_abbrev.upper()}** is.'
)
return
for x in [away_team, home_team]:
if not x['is_ai']:
conflict = count_team_games(x['id'])
if conflict['count']:
await interaction.edit_original_response(
content=f'Ope. The {x["sname"]} are already playing over in '
f'{interaction.guild.get_channel(conflict["games"][0]["channel_id"]).mention}'
)
return
current = await db_get('current')
week_num = current['week']
# logging.debug(f'away: {away_team} / home: {home_team} / week: {week_num} / ranked: {is_ranked}')
logging.debug(f'away: {away_team} / home: {home_team} / week: {week_num}')
if not away_team['is_ai'] and not home_team['is_ai']:
logging.error(f'Exhibition game between {away_team["abbrev"]} and {home_team["abbrev"]} has no AI')
await interaction.edit_original_response(
content=f'I don\'t see an AI team in this Exhibition game. Run `/new-game mlb-campaign` again with '
f'an AI for a campaign game or `/new-game <ranked / unlimited>` for a human game.'
)
return
ai_team = away_team if away_team['is_ai'] else home_team
human_team = away_team if home_team['is_ai'] else home_team
if interaction.user.id not in [away_team['gmid'], home_team['gmid']]:
await interaction.edit_original_response(
content='You can only start a new game if you GM one of the teams.'
)
return
league_name = 'exhibition'
this_game = post_game({
'away_team_id': away_team['id'],
'home_team_id': home_team['id'],
'week_num': week_num,
'channel_id': interaction.channel.id,
'active': True,
'is_pd': True,
'ranked': False,
'season': current['season'],
'short_game': True if num_innings == 3 else False,
'game_type': league_name
})
logging.info(
f'Game {this_game.id} ({league_name}) between {away_team_abbrev.upper()} and '
f'{home_team_abbrev.upper()} is posted!'
)
away_role = await team_role(interaction, away_team)
home_role = await team_role(interaction, home_team)
all_lineups = [] # Get Human SP
human_sp_card = await db_get(f'cards', object_id=sp_card_id)
if human_sp_card['team']['id'] != human_team['id']:
logging.error(
f'Card_id {sp_card_id} does not belong to {human_team["abbrev"]} in Game {this_game.id}'
)
patch_game(this_game.id, active=False)
await interaction.channel.send(
f'Uh oh. Card ID {sp_card_id} is {human_sp_card["player"]["p_name"]} and belongs to '
f'{human_sp_card["team"]["sname"]}. Will you double check that before we get started?')
return
all_lineups.append({
'game_id': this_game.id,
'team_id': human_team['id'],
'player_id': human_sp_card['player']['player_id'],
'card_id': sp_card_id,
'position': 'P',
'batting_order': 10,
'after_play': 0
})
async def get_ai_sp_roster(interaction, this_game, ai_team, home_team, league_name, all_lineups):
# Get AI Starting Pitcher
try:
await interaction.edit_original_response(
content=f'Now to decide on a Starting Pitcher...'
)
if ai_team['id'] == this_game.away_team_id:
patch_game(this_game.id, away_roster_num=69, ai_team='away')
else:
patch_game(this_game.id, home_roster_num=69, ai_team='home')
starter = await ai_manager.get_starting_pitcher(
ai_team,
this_game.id,
True if home_team['is_ai'] else False,
league_name
)
all_lineups.append(starter)
ai_sp = await db_get('players', object_id=starter['player_id'])
this_card = await db_get(f'cards', object_id=starter['card_id'])
await interaction.channel.send(
content=f'The {ai_team["sname"]} are starting **{player_desc(this_card["player"])}**:\n\n'
f'{player_pcard(this_card["player"])}'
)
except Exception as e:
patch_game(this_game.id, active=False)
logging.error(f'could not start an AI game with {ai_team["sname"]}: {e}')
await interaction.edit_original_response(
content=f'Looks like the {ai_team["sname"]} rotation didn\'t come through clearly. I\'ll sort '
f'this out with {ai_team["gmname"]} and {get_cal_user(interaction).mention}. I\'ll end '
f'this game - why don\'t you play against somebody else for now?'
)
raise KeyError(f'A Starting Pitcher could not be found for the {ai_team["lname"]}.')
# Get AI Lineup
try:
await interaction.edit_original_response(
content=f'I am getting a lineup card from the {ai_team["sname"]}...'
)
logging.info(f'new-game - calling lineup for {ai_team["abbrev"]}')
batters = await ai_manager.build_lineup(
ai_team, this_game.id, league_name, sp_name=ai_sp['p_name']
)
all_lineups.extend(batters)
logging.info(f'new-game - got lineup for {ai_team["abbrev"]}')
except Exception as e:
patch_game(this_game.id, active=False)
logging.error(f'could not start an AI game with {ai_team["sname"]}: {e}')
await interaction.edit_original_response(
content=f'Looks like the {ai_team["sname"]} lineup card didn\'t come through clearly. I\'ll sort '
f'this out with {ai_team["gmname"]} and {get_cal_user(interaction).mention}. I\'ll end '
f'this game - why don\'t you play against somebody else for now?'
)
return
logging.debug(f'Setting lineup for {ai_team["sname"]} in PD game')
logging.debug(f'lineups: {all_lineups}')
post_lineups(all_lineups)
if cardsets in ['Minor League', 'Major League', 'Hall of Fame', 'Flashback']:
if cardsets == 'Minor League':
cardset_ids = '17,8'
backup_cardset_ids = '13'
elif cardsets == 'Major League':
cardset_ids = '17,18,13,11,7,8'
backup_cardset_ids = '9,3'
elif cardsets == 'Hall of Fame':
all_c = [str(x) for x in range(1, 20)]
cardset_ids = f'{",".join(all_c)}'
backup_cardset_ids = None
else:
# Flashback cardsets
cardset_ids = '11,7,6,12'
backup_cardset_ids = '13,5'
this_game = patch_game(this_game.id, cardset_ids=cardset_ids, backup_cardset_ids=backup_cardset_ids)
await get_ai_sp_roster(interaction, this_game, ai_team, home_team, league_name, all_lineups)
await interaction.channel.send(
content=f'{away_role.mention} @ {home_role.mention} is set!\n\n'
f'Go ahead and set lineups with the `/read-lineup` command!',
embed=await self.initialize_play_plus_embed(this_game, full_length=False)
)
else:
async def my_callback(interaction: discord.Interaction, values):
cardset_ids = ','.join(values)
patch_game(this_game.id, cardset_ids=cardset_ids)
# await interaction.response.send_message(
# f'Your selection{"s are" if len(values) > 1 else " is"}: {", ".join(values)}')
await get_ai_sp_roster(interaction, this_game, ai_team, home_team, league_name, all_lineups)
await interaction.channel.send(
content=f'{away_role.mention} @ {home_role.mention} is set!\n\n'
f'Go ahead and set lineups with the `/read-lineup` command!',
embed=await self.initialize_play_plus_embed(this_game, full_length=False)
)
my_dropdown = Dropdown(
option_list=SELECT_CARDSET_OPTIONS,
placeholder='Select up to 8 cardsets to include',
callback=my_callback,
max_values=len(SELECT_CARDSET_OPTIONS)
)
view = DropdownView([my_dropdown])
await interaction.edit_original_response(
content=None,
view=view
)
return
@commands.command(name='force-endgame', help='Mod: Force a game to end without stats') @commands.command(name='force-endgame', help='Mod: Force a game to end without stats')
@commands.is_owner() @commands.is_owner()
async def force_end_game_command(self, ctx: commands.Context): async def force_end_game_command(self, ctx: commands.Context):

View File

@ -13,7 +13,7 @@ from dataclasses import dataclass
from helpers import SBA_SEASON, PD_SEASON, get_player_url, get_sheets from helpers import SBA_SEASON, PD_SEASON, get_player_url, get_sheets
from db_calls import db_get from db_calls import db_get
from in_game.data_cache import get_pd_player, CardPosition, BattingCard from in_game.data_cache import get_pd_player, CardPosition, BattingCard, get_pd_team
db = SqliteDatabase( db = SqliteDatabase(
'storage/gameplay.db', 'storage/gameplay.db',
@ -183,6 +183,8 @@ class Game(BaseModel):
first_message = IntegerField(null=True) first_message = IntegerField(null=True)
ai_team = CharField(null=True) ai_team = CharField(null=True)
game_type = CharField(default='minor-league') game_type = CharField(default='minor-league')
cardset_ids = CharField(null=True)
backup_cardset_ids = CharField(null=True)
# TODO: add get_away_team and get_home_team that deals with SBa/PD and returns Team object # TODO: add get_away_team and get_home_team that deals with SBa/PD and returns Team object
@ -205,6 +207,8 @@ class StratGame:
first_message: int = None first_message: int = None
ai_team: str = None ai_team: str = None
game_type: str = None game_type: str = None
cardset_ids: str = None
backup_cardset_ids: str = None
db.create_tables([Game]) db.create_tables([Game])
@ -244,7 +248,8 @@ def post_game(game_dict: dict):
return_game = StratGame( return_game = StratGame(
new_game.id, new_game.away_team_id, new_game.home_team_id, new_game.channel_id, new_game.season, new_game.id, new_game.away_team_id, new_game.home_team_id, new_game.channel_id, new_game.season,
new_game.active, new_game.is_pd, new_game.ranked, new_game.short_game, new_game.week_num, new_game.game_num, new_game.active, new_game.is_pd, new_game.ranked, new_game.short_game, new_game.week_num, new_game.game_num,
new_game.away_roster_num, new_game.home_roster_num, new_game.first_message, new_game.ai_team, new_game.game_type new_game.away_roster_num, new_game.home_roster_num, new_game.first_message, new_game.ai_team,
new_game.game_type, new_game.cardset_ids, new_game.backup_cardset_ids
) )
db.close() db.close()
@ -282,18 +287,21 @@ def get_one_game(game_id=None, away_team_id=None, home_team_id=None, week_num=No
return None return None
async def get_game_team(game: StratGame, gm_id: int = None, team_abbrev: str = None, team_id: int = None) -> dict: async def get_game_team(
game: StratGame, gm_id: int = None, team_abbrev: str = None, team_id: int = None,
skip_cache: bool = False) -> dict:
if not gm_id and not team_abbrev and not team_id: if not gm_id and not team_abbrev and not team_id:
raise KeyError(f'get_game_team requires either one of gm_id, team_abbrev, or team_id to not be None') raise KeyError(f'get_game_team requires either one of gm_id, team_abbrev, or team_id to not be None')
logging.debug(f'getting game team for game {game.id} / gm_id: {gm_id} / ' logging.debug(f'getting game team for game {game.id} / gm_id: {gm_id} / '
f'tm_abbrev: {team_abbrev} / team_id: {team_id} / game: {game}') f'tm_abbrev: {team_abbrev} / team_id: {team_id} / game: {game}')
if game.is_pd: if game.is_pd:
if gm_id: if team_id:
t_query = await db_get('teams', params=[('season', PD_SEASON), ('gm_id', gm_id)]) return await get_pd_team(team_id, skip_cache=skip_cache)
return t_query['teams'][0] elif gm_id:
elif team_id: return await get_pd_team(gm_id, skip_cache=skip_cache)
return await db_get('teams', object_id=team_id) # t_query = await db_get('teams', params=[('season', PD_SEASON), ('gm_id', gm_id)])
# return t_query['teams'][0]
else: else:
t_query = await db_get('teams', params=[('season', PD_SEASON), ('abbrev', team_abbrev)]) t_query = await db_get('teams', params=[('season', PD_SEASON), ('abbrev', team_abbrev)])
return t_query['teams'][0] return t_query['teams'][0]
@ -308,7 +316,8 @@ async def get_game_team(game: StratGame, gm_id: int = None, team_abbrev: str = N
def patch_game( def patch_game(
game_id, away_team_id=None, home_team_id=None, week_num=None, game_num=None, channel_id=None, active=None, game_id, away_team_id=None, home_team_id=None, week_num=None, game_num=None, channel_id=None, active=None,
first_message=None, home_roster_num=None, away_roster_num=None, ai_team=None): first_message=None, home_roster_num=None, away_roster_num=None, ai_team=None, cardset_ids=None,
backup_cardset_ids=None):
this_game = Game.get_by_id(game_id) this_game = Game.get_by_id(game_id)
if away_team_id is not None: if away_team_id is not None:
this_game.away_team_id = away_team_id this_game.away_team_id = away_team_id
@ -330,13 +339,17 @@ def patch_game(
this_game.away_roster_num = away_roster_num this_game.away_roster_num = away_roster_num
if ai_team is not None: if ai_team is not None:
this_game.ai_team = ai_team this_game.ai_team = ai_team
if cardset_ids is not None:
this_game.cardset_ids = cardset_ids
if backup_cardset_ids is not None:
this_game.backup_cardset_ids = backup_cardset_ids
this_game.save() this_game.save()
# return_game = model_to_dict(this_game) # return_game = model_to_dict(this_game)
return_game = StratGame( return_game = StratGame(
this_game.id, this_game.away_team_id, this_game.home_team_id, this_game.channel_id, this_game.season, this_game.id, this_game.away_team_id, this_game.home_team_id, this_game.channel_id, this_game.season,
this_game.active, this_game.is_pd, this_game.ranked, this_game.short_game, this_game.week_num, this_game.active, this_game.is_pd, this_game.ranked, this_game.short_game, this_game.week_num,
this_game.game_num, this_game.away_roster_num, this_game.home_roster_num, this_game.first_message, this_game.game_num, this_game.away_roster_num, this_game.home_roster_num, this_game.first_message,
this_game.ai_team this_game.ai_team, this_game.game_type, this_game.cardset_ids, this_game.backup_cardset_ids
) )
db.close() db.close()
return return_game return return_game

View File

@ -24,11 +24,13 @@ HELP_SHEET_SCRIPTS = (
) )
HELP_GAMEMODES = ( HELP_GAMEMODES = (
f'- Campaigns: Beat all 30 MLB teams to advance from the Minor League to Major League to Hall of Fame!'
f'- Ranked Play: Play against another PD manager with your ranked roster.\n' f'- Ranked Play: Play against another PD manager with your ranked roster.\n'
f'- Unlimited Play: Play an unranked game against another PD manager. Great for casual play, playtesting rosters, ' f'- Unlimited Play: Play an unranked game against another PD manager. Great for casual play, playtesting rosters, '
f'and event games.\n' f'and event games.\n'
f'- Gauntlets: Draft a team of 26 and attempt to win 10 games before losing 2. Rewards escalate based on the ' f'- Gauntlets: Draft a team of 26 and attempt to win 10 games before losing 2. Rewards escalate based on the '
f'number of wins.' f'number of wins.\n'
f'- Exhibition: Play a custom game against the AI'
) )
HELP_NEWGAME = ( HELP_NEWGAME = (

View File

@ -5,7 +5,8 @@ import random
# import data_cache # import data_cache
from db_calls_gameplay import StratPlay, StratGame, get_one_lineup, get_manager, get_team_lineups, \ 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, patch_lineup get_last_inning_end_play, make_sub, get_player, StratLineup, get_pitching_stats, patch_play, patch_lineup, \
get_one_game
from db_calls import db_get, db_post from db_calls import db_get, db_post
from peewee import * from peewee import *
from typing import Optional, Literal from typing import Optional, Literal
@ -102,6 +103,18 @@ def batter_grading(vs_hand, rg_data):
} }
def get_cardset_string(this_game: StratGame):
cardsets = ''
bcardsets = ''
for x in this_game.cardset_ids.split(','):
cardsets += f'&cardset_id={x}'
if this_game.backup_cardset_ids is not None:
for x in this_game.backup_cardset_ids.split(','):
bcardsets += f'&backup_cardset_id={x}'
return f'{cardsets}{bcardsets}'
async def get_or_create_card(player: dict, team: dict) -> int: async def get_or_create_card(player: dict, team: dict) -> int:
# get player card; create one if none found # get player card; create one if none found
z = 0 z = 0
@ -320,8 +333,10 @@ async def build_lineup(team_object: dict, game_id: int, league_name: str, sp_nam
# sorted_players = sorted(players.items(), key=lambda x: x[1]['cost'], reverse=True) # sorted_players = sorted(players.items(), key=lambda x: x[1]['cost'], reverse=True)
build_type = 'fun' build_type = 'fun'
this_game = get_one_game(game_id=game_id)
l_query = await db_get( l_query = await db_get(
f'teams/{team_object["id"]}/lineup/{league_name}?pitcher_name={sp_name}&build_type={build_type}', f'teams/{team_object["id"]}/lineup/{league_name}?pitcher_name={sp_name}&build_type={build_type}'
f'{get_cardset_string(this_game)}',
timeout=6 timeout=6
) )
sorted_players = l_query['array'] sorted_players = l_query['array']
@ -358,7 +373,8 @@ async def build_lineup(team_object: dict, game_id: int, league_name: str, sp_nam
return lineups return lineups
async def get_starting_pitcher(team_object: dict, game_id: int, is_home: bool, league_name: str = None) -> dict: async def get_starting_pitcher(
team_object: dict, game_id: int, is_home: bool, league_name: str = None) -> dict:
# set_params = [('cardset_id_exclude', 2)] # set_params = [('cardset_id_exclude', 2)]
# if league_name == 'minor-league': # if league_name == 'minor-league':
# set_params = copy.deepcopy(MINOR_CARDSET_PARAMS) # set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
@ -431,7 +447,19 @@ async def get_starting_pitcher(team_object: dict, game_id: int, is_home: bool, l
sp_rank = 4 sp_rank = 4
else: else:
sp_rank = 5 sp_rank = 5
starter = await db_get(f'teams/{team_object["id"]}/sp/{league_name}?sp_rank={sp_rank}')
# acardsets = [f'&cardset_id={x}' for x in cardset_ids] if cardset_ids is not None else ''
# cardsets = ''
# bcardsets = ''
# for x in cardset_ids:
# cardsets += f'&cardset_id={x}'
# abcardsets = [f'&cardset_id={x}' for x in backup_cardset_ids] if backup_cardset_ids is not None else ''
# for x in backup_cardset_ids:
# bcardsets += f'&backup_cardset_id={x}'
this_game = get_one_game(game_id=game_id)
starter = await db_get(
f'teams/{team_object["id"]}/sp/{league_name}?sp_rank={sp_rank}{get_cardset_string(this_game)}'
)
# get player card; create one if none found # get player card; create one if none found
card_id = await get_or_create_card(starter, team_object) card_id = await get_or_create_card(starter, team_object)
@ -475,7 +503,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
logging.debug(f'need: {need}') logging.debug(f'need: {need}')
rp_query = await db_get(f'teams/{ai_team["id"]}/rp/{league_name.split("-run")[0]}' rp_query = await db_get(f'teams/{ai_team["id"]}/rp/{league_name.split("-run")[0]}'
f'?need={need}&used_pitcher_ids={id_string}') f'?need={need}&used_pitcher_ids={id_string}{get_cardset_string(this_game)}')
card_id = await get_or_create_card(rp_query, ai_team) card_id = await get_or_create_card(rp_query, ai_team)
return { return {
'game_id': this_play.game.id, 'game_id': this_play.game.id,
@ -706,13 +734,16 @@ async def check_pitching_sub(this_play: StratPlay, ai_team: dict):
this_pc = await data_cache.get_pd_pitchingcard(this_play.pitcher.player_id, variant=this_play.pitcher.variant) this_pc = await data_cache.get_pd_pitchingcard(this_play.pitcher.player_id, variant=this_play.pitcher.variant)
pof_weakness = this_pc.card.starter_rating if len(used_pitchers) == 1 else this_pc.card.relief_rating pof_weakness = this_pc.card.starter_rating if len(used_pitchers) == 1 else this_pc.card.relief_rating
innof_work = math.ceil((ps['pl_outs'] + 1) / 3) innof_work = math.ceil((ps['pl_outs'] + 1) / 3)
is_starter = True if len(used_pitchers) == 1 else False
gtr = this_ai.go_to_reliever( gtr = this_ai.go_to_reliever(
this_play, this_play,
tot_allowed=ps['pl_hit'] + ps['pl_bb'] + ps['pl_hbp'], tot_allowed=ps['pl_hit'] + ps['pl_bb'] + ps['pl_hbp'],
is_starter=True if len(used_pitchers) == 1 else False is_starter=is_starter
) )
if (this_play.game.short_game or gtr or innof_work > pof_weakness + 3) and len(used_pitchers) < 8: if (this_play.game.short_game or gtr or
(innof_work > pof_weakness + 1 and not is_starter) or
(innof_work > pof_weakness + 3 and is_starter)) and len(used_pitchers) < 8:
rp_lineup = make_sub(await get_relief_pitcher(this_play, ai_team, this_play.game.game_type)) rp_lineup = make_sub(await get_relief_pitcher(this_play, ai_team, this_play.game.game_type))
try: try:
rp_pitcard = await data_cache.get_pd_pitchingcard(rp_lineup.player_id, rp_lineup.variant) rp_pitcard = await data_cache.get_pd_pitchingcard(rp_lineup.player_id, rp_lineup.variant)