From dccd30e27a594dad808a20bacef213c461ea2c48 Mon Sep 17 00:00:00 2001 From: Mayur Odedara Date: Fri, 8 Oct 2021 00:57:57 +0530 Subject: Added Anagrams command (#874) * Added Anagrams command Added 2 files anagram.py - Has the code for anagram command anagram.json - Contains all the words for anagram command * Update bot/exts/fun/anagram.py Using "with" for resource file instead of getting data directly Co-authored-by: brad90four <42116429+brad90four@users.noreply.github.com> * Update bot/exts/fun/anagram.py Updated title text for answer embed Co-authored-by: Bluenix * Update bot/exts/fun/anagram.py Comma separated text for winners list Co-authored-by: Bluenix * Updated anagram.py as per review comments -Removed redundant variables -Updated embed text to avoid 'all' -Updated stale comments * Some minor formatting fixes -Added trailing commas to embed -Updated all embeds to have consistent format * Polish anagram command for multiple channels * Updated docstrings * Allowed command to be used in multiple channels * Create a class for anagram game instances * Lay groundwork for threads Co-Authored-By: Bluenix * Updated resource file for anagram command * Anagrams are now cross referenced with list of common words which should be easy for users to guess * It should not have any slur words * Update bot/exts/fun/anagram.py Co-authored-by: brad90four <42116429+brad90four@users.noreply.github.com> * Update bot/exts/fun/anagram.py Co-authored-by: brad90four <42116429+brad90four@users.noreply.github.com> * Update bot/exts/fun/anagram.py Co-authored-by: brad90four <42116429+brad90four@users.noreply.github.com> * Update bot/exts/fun/anagram.py Co-authored-by: brad90four <42116429+brad90four@users.noreply.github.com> * Linting error fix Linting error fix * Error fix Removed the "seconds" causing issue for anagram command * Revert "Error fix" This reverts commit 8c00d70f9faf62c536eac1fa61877dfab328a83f. * Error fix for seconds Fixed the error by removing "seconds" Co-authored-by: brad90four <42116429+brad90four@users.noreply.github.com> Co-authored-by: Bluenix Co-authored-by: Xithrius <15021300+Xithrius@users.noreply.github.com> --- bot/exts/fun/anagram.py | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 bot/exts/fun/anagram.py (limited to 'bot/exts/fun/anagram.py') diff --git a/bot/exts/fun/anagram.py b/bot/exts/fun/anagram.py new file mode 100644 index 00000000..9aee5f18 --- /dev/null +++ b/bot/exts/fun/anagram.py @@ -0,0 +1,110 @@ +import asyncio +import json +import logging +import random +from pathlib import Path + +import discord +from discord.ext import commands + +from bot.bot import Bot +from bot.constants import Colours + +log = logging.getLogger(__name__) + +TIME_LIMIT = 60 + +# anagram.json file contains all the anagrams +with open(Path("bot/resources/fun/anagram.json"), "r") as f: + ANAGRAMS_ALL = json.load(f) + + +class AnagramGame: + """ + Used for creating instances of anagram games. + + Once multiple games can be run at the same time, this class' instances + can be used for keeping track of each anagram game. + """ + + def __init__(self, scrambled: str, correct: list[str]) -> None: + self.scrambled = scrambled + self.correct = set(correct) + + self.winners = set() + + async def message_creation(self, message: discord.Message) -> None: + """Check if the message is a correct answer and remove it from the list of answers.""" + if message.content.lower() in self.correct: + self.winners.add(message.author.mention) + self.correct.remove(message.content.lower()) + + +class Anagram(commands.Cog): + """Cog for the Anagram game command.""" + + def __init__(self, bot: Bot): + self.bot = bot + + self.games: dict[int, AnagramGame] = {} + + @commands.command(name="anagram", aliases=("anag", "gram", "ag")) + @commands.guild_only() + async def anagram_command(self, ctx: commands.Context) -> None: + """ + Given shuffled letters, rearrange them into anagrams. + + Show an embed with scrambled letters which if rearranged can form words. + After a specific amount of time, list the correct answers and whether someone provided a + correct answer. + """ + if self.games.get(ctx.channel.id): + await ctx.send("An anagram is already being solved in this channel!") + return + + scrambled_letters, correct = random.choice(list(ANAGRAMS_ALL.items())) + + game = AnagramGame(scrambled_letters, correct) + self.games[ctx.channel.id] = game + + anagram_embed = discord.Embed( + title=f"Find anagrams from these letters: '{scrambled_letters.upper()}'", + description=f"You have {TIME_LIMIT} seconds to find correct words.", + colour=Colours.purple, + ) + + await ctx.send(embed=anagram_embed) + await asyncio.sleep(TIME_LIMIT) + + if game.winners: + win_list = ", ".join(game.winners) + content = f"Well done {win_list} for getting it right!" + else: + content = "Nobody got it right." + + answer_embed = discord.Embed( + title=f"The words were: `{'`, `'.join(ANAGRAMS_ALL[game.scrambled])}`!", + colour=Colours.pink, + ) + + await ctx.send(content, embed=answer_embed) + + # Game is finished, let's remove it from the dict + self.games.pop(ctx.channel.id) + + @commands.Cog.listener() + async def on_message(self, message: discord.Message) -> None: + """Check a message for an anagram attempt and pass to an ongoing game.""" + if message.author.bot or not message.guild: + return + + game = self.games.get(message.channel.id) + if not game: + return + + await game.message_creation(message) + + +def setup(bot: Bot) -> None: + """Load the Anagram cog.""" + bot.add_cog(Anagram(bot)) -- cgit v1.2.3