# bot.py import os import discord import re from collections import Counter from discord.ext import commands from dotenv import load_dotenv WORDLE_CHANNEL = 1317916234863480832 load_dotenv() TOKEN = os.getenv('DISCORD_TOKEN') bot = commands.Bot() @bot.slash_command( name="stats", description="Prints out your stats in a daily game, examples include wordle", guild_ids=[261345598987436033] ) async def stats(interaction: discord.Interaction, game, user: discord.User = None): if game.lower() == 'wordle': channel = bot.get_channel(WORDLE_CHANNEL) if user is None: user = interaction.user WORDLE_PATTERN = r"^Wordle (\d{1,3}(?:,\d{3})*) (X|\d+)/(\d+)" total_guesses = 0 total_games = 0 wins = 0 async for message in channel.history(limit=1000): # Limit can be adjusted if message.author == user: for line in message.content.splitlines(): match = re.match(WORDLE_PATTERN, line.strip()) if match: total_games += 1 guesses = match.group(2) if guesses != 'X': total_guesses += int(guesses) wins += 1 break if total_games == 0: await interaction.response.send_message( "No Wordle results found.", ephemeral=True ) return average_guesses = total_guesses / wins win_rate = (wins / total_games) * 100 await interaction.response.send_message( f"Wordle stats for {user.mention}:\n" f"Total Games Played: {total_games}\n" f"Total Guesses: {total_guesses}\n" f"Average Guesses per Winning Game: {average_guesses:.2f}\n" f"Win Rate: {win_rate:.2f}%\n", ephemeral=False # Send message only to the user who called the command ) elif game.lower() == 'connections': channel = bot.get_channel(WORDLE_CHANNEL) if user is None: user = interaction.user CONNECTIONS_PATTERN = r"^Connections\nPuzzle #(\d+)\n((?:[\u2B1B\u2B1C\u2B1D\u2B1E\u2B20]{4}\n?)+)$" total_guesses = 0 total_games = 0 wins = 0 perfects = 0 async for message in channel.history(limit=1000): # Limit can be adjusted if message.author == user: message_content = message.content.strip() if message_content.startswith("Connections") and "Puzzle #" in message_content: # Extract the puzzle number puzzle_number_start = message_content.find("Puzzle #") + len("Puzzle #") puzzle_number_end = message_content.find("\n", puzzle_number_start) puzzle_number = message_content[puzzle_number_start:puzzle_number_end].strip() # Extract the grid (assume the grid starts after the first two lines) grid_start = message_content.find("\n", message_content.find("Puzzle #")) + 1 grid_content = message_content[grid_start:].strip() # Split the grid into lines color_grid = grid_content.split("\n") guesses = check_connections_win(color_grid) total_games += 1 if guesses > 0: total_guesses += guesses wins += 1 perfect_game = is_perfect_game(color_grid) if perfect_game: perfects += 1 if total_games == 0: await interaction.response.send_message( "No Connections results found.", ephemeral=True ) return average_guesses = total_guesses / wins win_rate = (wins / total_games) * 100 await interaction.response.send_message( f"Connections stats for {user.mention}:\n" f"Total Games Played: {total_games}\n" f"Average Guesses per Winning Game: {average_guesses:.2f}\n" f"Win Rate: {win_rate:.2f}%\n" f"Perfect Games: {perfects}\n", ephemeral=False # Send message only to the user who called the command ) else: await interaction.response.send_message( "Not a game.", ephemeral=True ) def check_connections_win(color_grid): """ Check if the Connections game is a win and return the number of guesses. A win is when there are exactly 4 groups of 4 colors each. """ # Flatten the color grid into a list of colors uniform_rows = [row for row in color_grid if len(set(row)) == 1] flattened_grid = ''.join(uniform_rows) # Count the occurrences of each color in the grid color_counts = Counter(flattened_grid) # Check if there are exactly 4 different colors with 4 squares each if len(color_counts) == 4 and all(count == 4 for count in color_counts.values()): # A win: return the number of guesses (lines in the grid) return len(color_grid) return 0 # Not a win def is_perfect_game(color_grid): """ Check if the Connections game is a perfect game (solved in 4 guesses, no mistakes). """ # A perfect game is one where the first 4 lines form perfect groups if len(color_grid) == 4 and all(len(set(line)) == 1 for line in color_grid): return True # It's a perfect game return False @bot.event async def on_ready(): print('Ready!') bot.run(TOKEN)