diff --git a/cogs/gameplay.py b/cogs/gameplay.py index 21fdff3..1ff2a72 100644 --- a/cogs/gameplay.py +++ b/cogs/gameplay.py @@ -1102,7 +1102,7 @@ class Gameplay(commands.Cog): @group_new_game.command(name='mlb-campaign', description='Start a new MLB Campaign game against an AI') @app_commands.describe( sp_card_id='Light gray number to the left of the pitcher\'s name on your depth chart') - @app_commands.has_any_role(PD_PLAYERS_ROLE_NAME) + @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def new_game_campaign_command( self, interaction: discord.Interaction, league: Literal['Minor League', 'Flashback', 'Major League', 'Hall of Fame'], @@ -1544,7 +1544,7 @@ class Gameplay(commands.Cog): @group_new_game.command(name='gauntlet', description='Start a new Gauntlet game against an AI') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) async def new_game_gauntlet_command( - self, interaction: discord.Interaction, event_name: Literal['2024 Season', 'Super Ultra Championship'], + self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL, sp_card_id: int): await interaction.response.defer() @@ -2956,7 +2956,7 @@ class Gameplay(commands.Cog): @app_commands.describe( batting_order='Batting order of new player', new_player='Enter the Card ID (a number)') - @commands.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME) + @app_commands.checks.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME) async def sub_batter_command( self, interaction: discord.Interaction, new_player: int, batting_order: Literal[ 'this-spot', '1', '2', '3', '4', '5', '6', '7', '8', '9'], @@ -3011,7 +3011,7 @@ class Gameplay(commands.Cog): @app_commands.describe( new_player='Enter the Card ID (a number)', batting_order='Only enter this if you are forfeiting the DH') - @commands.has_any_role(PD_PLAYERS_ROLE_NAME) + @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def sub_pitcher_command( self, interaction: discord.Interaction, new_player: int, batting_order: Literal['this-spot', '1', '2', '3', '4', '5', '6', '7', '8', '9'] = None): @@ -3105,7 +3105,7 @@ class Gameplay(commands.Cog): ) # @group_substitution.command(name='forfeit-dh', description='Have the pitcher bat in the DH spot') - # @commands.has_any_role(PD_PLAYERS_ROLE_NAME) + # @commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) # async def sub_forfeitdh_command(self, interaction: discord.Interaction): # this_game, owner_team, this_play = await self.checks_log_interaction(interaction) # if False in (this_game, owner_team, this_play): diff --git a/cogs/owner.py b/cogs/owner.py index b6c0017..e670da3 100644 --- a/cogs/owner.py +++ b/cogs/owner.py @@ -92,7 +92,7 @@ class Owner(commands.Cog): # # await ctx.send(f'Just ran the sync. Here is the output:\n{sync}') - @commands.command() + @commands.command(name='sync', help='~ current guild, * global -> current, ! clear and sync current') @commands.is_owner() async def sync(self, ctx: Context, guilds: Greedy[Object], spec: Optional[Literal['~', "*", '!']] = None) -> None: """ diff --git a/cogs/players.py b/cogs/players.py index ef04961..1f66a4f 100644 --- a/cogs/players.py +++ b/cogs/players.py @@ -25,7 +25,7 @@ import helpers from in_game.data_cache import get_pd_pitchingcard, get_pd_battingcard, get_pd_player from in_game.simulations import get_pos_embeds, get_result from db_calls import db_get, db_post, db_patch, get_team_by_abbrev -from helpers import PD_PLAYERS_ROLE_NAME, IMAGES, PD_SEASON, random_conf_gif, fuzzy_player_search, ALL_MLB_TEAMS, \ +from helpers import ACTIVE_EVENT_LITERAL, PD_PLAYERS_ROLE_NAME, IMAGES, PD_SEASON, random_conf_gif, fuzzy_player_search, ALL_MLB_TEAMS, \ fuzzy_search, get_channel, display_cards, get_card_embeds, get_team_embed, cardset_search, get_blank_team_card, \ get_team_by_owner, get_rosters, get_roster_sheet, legal_channel, random_conf_word, embed_pagination, get_cal_user, \ team_summary_embed, SelectView, SelectPaperdexCardset, SelectPaperdexTeam @@ -903,7 +903,7 @@ class Players(commands.Cog): ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_run_command( - self, interaction: discord.Interaction, event_name: Literal['2024 Season', 'Super Ultra Championship'], + self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL, team_abbrev: str = None): await interaction.response.defer() @@ -944,7 +944,7 @@ class Players(commands.Cog): @group_gauntlet.command(name='start', description='Start a new Gauntlet run') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_start_command( - self, interaction: discord.Interaction, event_name: Literal['2024 Season', 'Super Ultra Championship']): + self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL): if 'hello' not in interaction.channel.name: await interaction.response.send_message( content='The draft will probably take you about 15 minutes. Why don\'t you head to your private ' @@ -1017,7 +1017,7 @@ class Players(commands.Cog): @group_gauntlet.command(name='reset', description='Wipe your current team so you can re-draft') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_reset_command( - self, interaction: discord.Interaction, event_name: Literal['2024 Season', 'Super Ultra Championship']): + self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL): await interaction.response.defer() main_team = await get_team_by_owner(interaction.user.id) draft_team = await get_team_by_abbrev(f'Gauntlet-{main_team["abbrev"]}') diff --git a/db_calls.py b/db_calls.py index a4ef5fa..3c4a4db 100644 --- a/db_calls.py +++ b/db_calls.py @@ -9,7 +9,7 @@ import os AUTH_TOKEN = {'Authorization': f'Bearer {os.environ.get("API_TOKEN")}'} DB_URL = 'https://pd.manticorum.com/api' master_debug = True -alt_database = False +alt_database = 'dev' PLAYER_CACHE = {} if alt_database == 'dev': diff --git a/gauntlets.py b/gauntlets.py index 1efb710..db43675 100644 --- a/gauntlets.py +++ b/gauntlets.py @@ -280,7 +280,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra if this_event['id'] == 1: embed_title = f'{main_team["lname"]} - {this_event["name"]} Draft' embed_description = f'{this_event["name"]}' - base_params = copy.deepcopy(ai_manager.MAJOR_CARDSET_PARAMS) + base_params = copy.deepcopy(ai_manager.GAUNTLET1_PARAMS) base_params.extend([('limit', 8), ('cardset_id', 8)]) elif this_event['id'] == 2: embed_title = f'{main_team["lname"]} - {this_event["name"]} Draft' @@ -301,6 +301,11 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra embed_description = f'{this_event["name"]}' base_params = [('cardset_id', 17), ('cardset_id', 18), ('cardset_id', 19), ('cardset_id', 16), ('cardset_id', 8), ('limit', 8)] + elif this_event['id'] == 6: + embed_title = f'{main_team['lname']} - {this_event['name']} Draft' + embed_description = f'{this_event["name"]}' + base_params = [('cardset_id', 20), ('cardset_id', 21), ('cardset_id', 22), ('cardset_id', 16), + ('cardset_id', 8), ('limit', 8)] else: logging.error(f'run_draft - Event ID {this_event["id"]} not recognized') raise KeyError(f'Draft data not found for Gauntlet {this_event["id"]}') @@ -355,10 +360,10 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra } if this_event['id'] in [1, 2]: max_counts['MVP'] = 2 - elif this_event['id'] == 5: + elif this_event['id'] in [5, 6]: g_query = await db_get( 'games', - params=[('season', draft_team['season']), ('team1_id', draft_team['id']), ('gauntlet_id', 5)] + params=[('season', draft_team['season']), ('team1_id', draft_team['id']), ('gauntlet_id', this_event['id'])] ) if g_query['count'] > 4: game_count = g_query['count'] @@ -587,6 +592,162 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra logging.info(f'getting last message') last_message = await interaction.channel.send(content=None, embeds=get_embeds(include_links=False)) + async def draft_loop(): + while round_num <= 26 and counter < 50: + counter += 1 + params = copy.deepcopy(base_params) + logging.info(f'gauntlets.py - run_draft - event_id 5 / round_num: {round_num} / counter: {counter} ' + f'/ counts: {counts} / max_counts: {max_counts}') + + # Set rarity based on remaining counts + if counts['Hall of Fame'] < max_counts['Hall of Fame']: + params.extend([ + ('min_rarity', RARITY['HoF']), ('max_rarity', RARITY['HoF']) + ]) + elif counts['MVP'] < max_counts['MVP']: + params.extend([ + ('min_rarity', RARITY['MVP']), ('max_rarity', RARITY['MVP']) + ]) + elif counts['All-Star'] < max_counts['All-Star']: + params.extend([ + ('min_rarity', RARITY['All-Star']), ('max_rarity', RARITY['All-Star']) + ]) + elif counts['Starter'] < max_counts['Starter']: + params.extend([ + ('min_rarity', RARITY['Starter']), ('max_rarity', RARITY['Starter']) + ]) + elif counts['Reserve'] < max_counts['Reserve']: + params.extend([ + ('min_rarity', RARITY['Reserve']), ('max_rarity', RARITY['Reserve']) + ]) + else: + params.extend([ + ('min_rarity', RARITY['Replacement']), ('max_rarity', RARITY['Replacement']) + ]) + + this_batch = [] + for x in ['SP', 'RP', 'IF', 'OF']: + # Slot 1 - SP + if x == 'SP': + if counts['SP'] > 5: + slot_params = [('pos_exc', 'SP')] + if counts['RP'] > 7: + slot_params = [('pos_exc', 'RP')] + else: + slot_params = [('pos_inc', 'SP')] + # if counts['SP'] > 5: + # slot_params = [('pos_exc', 'SP')] + # elif counts['RP'] < 6: + # slot_params = [('pos_inc', 'RP')] + # else: + # slot_params = [('pos_exc', 'SP'), ('pos_exc', 'RP')] + + # Slot 2 - RP + elif x == 'RP': + logging.info(f'counts[RP]: {counts["RP"]}') + if counts['RP'] > 7: + slot_params = [('pos_exc', 'RP')] + if counts['SP'] > 5: + slot_params = [('pos_exc', 'SP')] + else: + slot_params = [('pos_inc', 'RP')] + + # Slot 3 - IF + elif x == 'IF': + slot_params = [] + for y in ['1B', '2B', '3B', 'SS', 'C']: + if (counts[y] > 1) and 0 in [ + counts['C'], counts['1B'], counts['2B'], counts['3B'], counts['SS'] + ]: + slot_params.append(('pos_exc', y)) + elif (y == 'C' and counts['C'] < 3) or (y != 'C' and counts[y] < 4): + slot_params.append(('pos_inc', y)) + # if counts['C'] < 2: + # slot_params.append(('pos_inc', 'C')) + # if len(slot_params) == 0: + # slot_params = [('pos_exc', 'C'), ('pos_exc', '1B'), ('pos_exc', '2B'), ('pos_exc', '3B'), + # ('pos_exc', 'SS')] + + # Slot 4 - OF + else: + slot_params = [] + for y in ['LF', 'CF', 'RF']: + if counts[y] > 4: + slot_params.append(('pos_exc', y)) + elif counts[y] > 1 and 0 in [counts['LF'], counts['CF'], counts['RF']]: + slot_params.append(('pos_exc', y)) + elif counts[y] < 5: + slot_params.append(('pos_inc', y)) + # if len(slot_params) == 0: + # slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')] + + logging.info(f'this_batch: {this_batch}') + logging.info(f'slot_params: {slot_params}') + logging.info(f'params: {params}') + + # No position explicitly requested or denied + if len(slot_params) == 0: + if (counts['SP'] + counts['RP']) > ( + counts['C'] + counts['1B'] + counts['2B'] + counts['SS'] + counts['LF'] + counts['CF'] + + counts['RF']): + pos_counts = [ + ('C', counts['C']), ('1B', counts['1B']), ('2B', counts['2B']), ('3B', counts['3B']), + ('SS', counts['SS']), ('LF', counts['LF']), ('CF', counts['CF']), ('RF', counts['RF']) + ] + pos_counts.sort(key=lambda z: z[1]) + slot_params = [('pos_inc', pos_counts[0][0])] + else: + if counts['SP'] >= counts['RP']: + slot_params = [('pos_inc', 'RP')] + else: + slot_params = [('pos_inc', 'SP')] + + slot_params.extend(params) + p_query = await db_get('players/random', params=slot_params) + + if p_query['count'] > 0: + # test_player_list = '' + # for z in p_query['players']: + # test_player_list += f'{z["rarity"]["name"]} - {z["description"]} - {helpers.get_all_pos(x)}\n' + + # Collect 1 cards with no repeat player names + for i in p_query['players']: + if i['p_name'] not in p_names and i not in this_batch: + this_batch.append(i) + break + + if len(this_batch) < 4: + logging.error(f'Pulled less than 4 players in gauntlet draft') + p_query = await db_get('players/random', params=params) + for i in p_query['players']: + if i['p_name'] not in p_names and i not in this_batch: + this_batch.append(i) + if len(this_batch) >= 4: + break + + if len(this_batch) < 4: + raise KeyError(f'This is embarassing, but I couldn\'t find enough players for you to draft from.') + + # Present choices and capture selection + p_choice = await helpers.get_choice_from_cards(interaction, this_batch, delete_message=True) + + # Add player to list and update counts + p_names.append(p_choice['p_name']) + counts[p_choice['rarity']['name']] += 1 + + all_players.append(p_choice) + + if p_choice['pos_1'] in ['SP', 'RP']: + counts[p_choice['pos_1']] += 1 + else: + for x in helpers.get_all_pos(p_choice): + if x in counts: + counts[x] += 1 + + # Update roster embed + round_num += 1 + await last_message.edit(content=None, embeds=get_embeds(include_links=False)) + logging.info(f'going into draft') backyard_round = None custom_player_round = None @@ -1317,162 +1478,8 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra # Update roster embed round_num += 1 await last_message.edit(content=None, embeds=get_embeds(include_links=False)) - elif this_event['id'] == 5: - while round_num <= 26 and counter < 50: - counter += 1 - params = copy.deepcopy(base_params) - logging.info(f'gauntlets.py - run_draft - event_id 5 / round_num: {round_num} / counter: {counter} ' - f'/ counts: {counts} / max_counts: {max_counts}') - - # Set rarity based on remaining counts - if counts['Hall of Fame'] < max_counts['Hall of Fame']: - params.extend([ - ('min_rarity', RARITY['HoF']), ('max_rarity', RARITY['HoF']) - ]) - elif counts['MVP'] < max_counts['MVP']: - params.extend([ - ('min_rarity', RARITY['MVP']), ('max_rarity', RARITY['MVP']) - ]) - elif counts['All-Star'] < max_counts['All-Star']: - params.extend([ - ('min_rarity', RARITY['All-Star']), ('max_rarity', RARITY['All-Star']) - ]) - elif counts['Starter'] < max_counts['Starter']: - params.extend([ - ('min_rarity', RARITY['Starter']), ('max_rarity', RARITY['Starter']) - ]) - elif counts['Reserve'] < max_counts['Reserve']: - params.extend([ - ('min_rarity', RARITY['Reserve']), ('max_rarity', RARITY['Reserve']) - ]) - else: - params.extend([ - ('min_rarity', RARITY['Replacement']), ('max_rarity', RARITY['Replacement']) - ]) - - this_batch = [] - for x in ['SP', 'RP', 'IF', 'OF']: - # Slot 1 - SP - if x == 'SP': - if counts['SP'] > 5: - slot_params = [('pos_exc', 'SP')] - if counts['RP'] > 7: - slot_params = [('pos_exc', 'RP')] - else: - slot_params = [('pos_inc', 'SP')] - # if counts['SP'] > 5: - # slot_params = [('pos_exc', 'SP')] - # elif counts['RP'] < 6: - # slot_params = [('pos_inc', 'RP')] - # else: - # slot_params = [('pos_exc', 'SP'), ('pos_exc', 'RP')] - - # Slot 2 - RP - elif x == 'RP': - logging.info(f'counts[RP]: {counts["RP"]}') - if counts['RP'] > 7: - slot_params = [('pos_exc', 'RP')] - if counts['SP'] > 5: - slot_params = [('pos_exc', 'SP')] - else: - slot_params = [('pos_inc', 'RP')] - - # Slot 3 - IF - elif x == 'IF': - slot_params = [] - for y in ['1B', '2B', '3B', 'SS', 'C']: - if (counts[y] > 1) and 0 in [ - counts['C'], counts['1B'], counts['2B'], counts['3B'], counts['SS'] - ]: - slot_params.append(('pos_exc', y)) - elif (y == 'C' and counts['C'] < 3) or (y != 'C' and counts[y] < 4): - slot_params.append(('pos_inc', y)) - # if counts['C'] < 2: - # slot_params.append(('pos_inc', 'C')) - # if len(slot_params) == 0: - # slot_params = [('pos_exc', 'C'), ('pos_exc', '1B'), ('pos_exc', '2B'), ('pos_exc', '3B'), - # ('pos_exc', 'SS')] - - # Slot 4 - OF - else: - slot_params = [] - for y in ['LF', 'CF', 'RF']: - if counts[y] > 4: - slot_params.append(('pos_exc', y)) - elif counts[y] > 1 and 0 in [counts['LF'], counts['CF'], counts['RF']]: - slot_params.append(('pos_exc', y)) - elif counts[y] < 5: - slot_params.append(('pos_inc', y)) - # if len(slot_params) == 0: - # slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')] - - logging.info(f'this_batch: {this_batch}') - logging.info(f'slot_params: {slot_params}') - logging.info(f'params: {params}') - - # No position explicitly requested or denied - if len(slot_params) == 0: - if (counts['SP'] + counts['RP']) > ( - counts['C'] + counts['1B'] + counts['2B'] + counts['SS'] + counts['LF'] + counts['CF'] + - counts['RF']): - pos_counts = [ - ('C', counts['C']), ('1B', counts['1B']), ('2B', counts['2B']), ('3B', counts['3B']), - ('SS', counts['SS']), ('LF', counts['LF']), ('CF', counts['CF']), ('RF', counts['RF']) - ] - pos_counts.sort(key=lambda z: z[1]) - slot_params = [('pos_inc', pos_counts[0][0])] - else: - if counts['SP'] >= counts['RP']: - slot_params = [('pos_inc', 'RP')] - else: - slot_params = [('pos_inc', 'SP')] - - slot_params.extend(params) - p_query = await db_get('players/random', params=slot_params) - - if p_query['count'] > 0: - # test_player_list = '' - # for z in p_query['players']: - # test_player_list += f'{z["rarity"]["name"]} - {z["description"]} - {helpers.get_all_pos(x)}\n' - - # Collect 1 cards with no repeat player names - for i in p_query['players']: - if i['p_name'] not in p_names and i not in this_batch: - this_batch.append(i) - break - - if len(this_batch) < 4: - logging.error(f'Pulled less than 4 players in gauntlet draft') - p_query = await db_get('players/random', params=params) - for i in p_query['players']: - if i['p_name'] not in p_names and i not in this_batch: - this_batch.append(i) - if len(this_batch) >= 4: - break - - if len(this_batch) < 4: - raise KeyError(f'This is embarassing, but I couldn\'t find enough players for you to draft from.') - - # Present choices and capture selection - p_choice = await helpers.get_choice_from_cards(interaction, this_batch, delete_message=True) - - # Add player to list and update counts - p_names.append(p_choice['p_name']) - counts[p_choice['rarity']['name']] += 1 - - all_players.append(p_choice) - - if p_choice['pos_1'] in ['SP', 'RP']: - counts[p_choice['pos_1']] += 1 - else: - for x in helpers.get_all_pos(p_choice): - if x in counts: - counts[x] += 1 - - # Update roster embed - round_num += 1 - await last_message.edit(content=None, embeds=get_embeds(include_links=False)) - + elif this_event['id'] in [5, 6]: + await draft_loop() else: logging.error(f'run_draft - No draft logic for Event ID {this_event["id"]}') raise KeyError(f'Draft data not found for Gauntlet {this_event["id"]}') diff --git a/helpers.py b/helpers.py index 30049a0..de4f677 100644 --- a/helpers.py +++ b/helpers.py @@ -18,10 +18,10 @@ from dataclasses import dataclass from typing import Optional, Literal -SBA_SEASON = 9 -PD_SEASON = 7 -LIVE_CARDSET_ID = 17 -LIVE_PROMO_CARDSET_ID = 18 +SBA_SEASON = 10 +PD_SEASON = 8 +LIVE_CARDSET_ID = 20 +LIVE_PROMO_CARDSET_ID = 21 SBA_COLOR = 'a6ce39' PD_PLAYERS = 'Paper Dynasty Players' SBA_PLAYERS_ROLE_NAME = f'Season {SBA_SEASON} Players' @@ -239,6 +239,7 @@ SELECT_CARDSET_OPTIONS = [ discord.SelectOption(label='2013 Season', value='6'), discord.SelectOption(label='2012 Season', value='7') ] +ACTIVE_EVENT_LITERAL = Literal['1998 Season'] class Question: diff --git a/in_game/ai_manager.py b/in_game/ai_manager.py index 928b8be..40d7e90 100644 --- a/in_game/ai_manager.py +++ b/in_game/ai_manager.py @@ -22,20 +22,11 @@ db = SqliteDatabase( } ) -# 2024, Mario -MINOR_CARDSET_PARAMS = [('cardset_id', 17), ('cardset_id', 8)] - # 2018, 2024, Mario, -MAJOR_CARDSET_PARAMS = [ +GAUNTLET1_PARAMS = [ ('cardset_id', 13), ('cardset_id', 14), ('cardset_id', 17), ('cardset_id', 18), ('cardset_id', 8) ] -# 2008, 2012, 2013, 2016, 2019, 2021, 2022, 2023, Mario -HOF_CARDSET_PARAMS = [ - ('cardset_id', 1), ('cardset_id', 3), ('cardset_id', 4), ('cardset_id', 5), ('cardset_id', 6), ('cardset_id', 7), - ('cardset_id', 8), ('cardset_id', 9), ('cardset_id', 10), ('cardset_id', 11), ('cardset_id', 12), ('cardset_id', 13) -] - # 2008, 2012, 2013, 2016 GAUNTLET2_PARAMS = [ ('cardset_id', 8), ('cardset_id', 12), ('cardset_id', 6), ('cardset_id', 7), ('cardset_id', 11) diff --git a/requirements.txt b/requirements.txt index 2ff3058..1603290 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -discord.py==2.1.1 +discord.py pygsheets pydantic gsheets