diff --git a/hangman/__init__.py b/hangman/__init__.py new file mode 100644 index 0000000..aee87e2 --- /dev/null +++ b/hangman/__init__.py @@ -0,0 +1,7 @@ +from .hangman import Hangman + + +def setup(bot): + n = Hangman(bot) + bot.add_cog(n) + bot.add_listener(n._on_react, "on_reaction_add") \ No newline at end of file diff --git a/hangman/hangman.py b/hangman/hangman.py index 987b3a2..2b3776e 100644 --- a/hangman/hangman.py +++ b/hangman/hangman.py @@ -1,11 +1,11 @@ import discord import os +from collections import defaultdict from discord.ext import commands from random import randint -from .utils.dataIO import dataIO -from .utils import checks +from redbot.core import Config, checks, RedContext class Hangman: @@ -13,190 +13,187 @@ class Hangman: def __init__(self, bot): self.bot = bot - self.path = "data/Fox-Cogs/hangman" - self.file_path = "data/Fox-Cogs/hangman/hangman.json" - self.answer_path = "data/hangman/hanganswers.txt" - self.the_data = dataIO.load_json(self.file_path) - self.winbool = False + self.config = Config.get_conf(self, identifier=1049711010310997110) + default_guild = { + "theface": ':thinking:', + } + + self.config.register_guild(**default_guild) + + self.the_data = defaultdict(lambda:{"running": False, "hangman": 0, "guesses": [], "trackmessage": False, "answer": ''}) + self.answer_path = "hangman/data/hanganswers.txt" + self.winbool = defaultdict(lambda: False) + self.letters = "🇦🇧🇨🇩🇪🇫🇬🇭🇮🇯🇰🇱🇲🇳🇴🇵🇶🇷🇸🇹🇺🇻🇼🇽🇾🇿" self.navigate = "🔼🔽" - self._updateHanglist() - - def _updateHanglist(self): - self.hanglist = ( - """> - \_________ - |/ - | - | - | - | - | - |\___ - """, - - """> - \_________ - |/ | - | - | - | - | - | - |\___ - H""", - - """> - \_________ - |/ | - | """+self.the_data["theface"]+""" - | - | - | - | - |\___ - HA""", - - """> - \________ - |/ | - | """+self.the_data["theface"]+""" - | | - | | - | - | - |\___ - HAN""", - - - """> - \_________ - |/ | - | """+self.the_data["theface"]+""" - | /| - | | - | - | - |\___ - HANG""", - - - """> - \_________ - |/ | - | """+self.the_data["theface"]+""" - | /|\ - | | - | - | - |\___ - HANGM""", - - - - """> - \________ - |/ | - | """+self.the_data["theface"]+""" - | /|\ - | | - | / - | - |\___ - HANGMA""", - - - """> - \________ - |/ | - | """+self.the_data["theface"]+""" - | /|\ - | | - | / \ - | - |\___ - HANGMAN""") - - def save_data(self): - """Saves the json""" - dataIO.save_json(self.file_path, self.the_data) - + + self.hanglist = {} + + async def _update_hanglist(self): + for guild in self.bot.guilds: + theface = await self.config.guild(guild).theface() + self.hanglist[guild] = ( + """> + \_________ + |/ + | + | + | + | + | + |\___ + """, + + """> + \_________ + |/ | + | + | + | + | + | + |\___ + H""", + + """> + \_________ + |/ | + | """+theface+""" + | + | + | + | + |\___ + HA""", + + """> + \________ + |/ | + | """+theface+""" + | | + | | + | + | + |\___ + HAN""", + + + """> + \_________ + |/ | + | """+theface+""" + | /| + | | + | + | + |\___ + HANG""", + + + """> + \_________ + |/ | + | """+theface+""" + | /|\ + | | + | + | + |\___ + HANGM""", + + + + """> + \________ + |/ | + | """+theface+""" + | /|\ + | | + | / + | + |\___ + HANGMA""", + + + """> + \________ + |/ | + | """+theface+""" + | /|\ + | | + | / \ + | + |\___ + HANGMAN""") + @commands.group(aliases=['sethang'], pass_context=True) @checks.mod_or_permissions(administrator=True) async def hangset(self, ctx): """Adjust hangman settings""" - if ctx.invoked_subcommand is None: - await self.bot.send_cmd_help(ctx) - + if not ctx.invoked_subcommand: + await ctx.send_help() + @hangset.command(pass_context=True) - async def face(self, ctx, theface): + async def face(self, ctx: commands.Context, theface): message = ctx.message #Borrowing FlapJack's emoji validation (https://github.com/flapjax/FlapJack-Cogs/blob/master/smartreact/smartreact.py) if theface[:2] == "<:": - theface = [r for server in self.bot.servers for r in server.emojis if r.id == theface.split(':')[2][:-1]][0] - + theface = [r for r in self.bot.emojis if r.id == theface.split(':')[2][:-1]][0] + try: # Use the face as reaction to see if it's valid (THANKS FLAPJACK <3) - await self.bot.add_reaction(message, theface) - self.the_data["theface"] = str(theface) - self.save_data() - self._updateHanglist() - await self.bot.say("Face has been updated!") - + await message.add_reaction(theface) except discord.errors.HTTPException: - await self.bot.say("That's not an emoji I recognize.") + await ctx.send("That's not an emoji I recognize.") + return + + await self.config.guild(ctx.guild).theface.set(theface) + await self._update_hanglist() + await ctx.send("Face has been updated!") @commands.command(aliases=['hang'], pass_context=True) async def hangman(self, ctx, guess: str=None): """Play a game of hangman against the bot!""" if guess is None: - if self.the_data["running"]: - await self.bot.say("Game of hangman is already running!\nEnter your guess!") - self._printgame() + if self.the_data[ctx.guild]["running"]: + await ctx.send("Game of hangman is already running!\nEnter your guess!") + self._printgame(ctx.channel) """await self.bot.send_cmd_help(ctx)""" else: - await self.bot.say("Starting a game of hangman!") - self._startgame() - await self._printgame() - elif not self.the_data["running"]: - await self.bot.say("Game of hangman is not yet running!\nStarting a game of hangman!") - self._startgame() - await self._printgame() + await ctx.send("Starting a game of hangman!") + self._startgame(ctx.guild) + await self._printgame(ctx.channel) + elif not self.the_data[ctx.guild]["running"]: + await ctx.send("Game of hangman is not yet running!\nStarting a game of hangman!") + self._startgame(ctx.guild) + await self._printgame(ctx.channel) else: - await self._guessletter(guess) + await self._guessletter(guess, ctx.channel) - - def _startgame(self): + def _startgame(self, guild): """Starts a new game of hangman""" - self.the_data["answer"] = self._getphrase().upper() - self.the_data["hangman"] = 0 - self.the_data["guesses"] = [] - self.winbool = False - self.the_data["running"] = True - self.the_data["trackmessage"] = False - self.save_data() + self.the_data[guild]["answer"] = self._getphrase().upper() + self.the_data[guild]["hangman"] = 0 + self.the_data[guild]["guesses"] = [] + self.winbool[guild] = False + self.the_data[guild]["running"] = True + self.the_data[guild]["trackmessage"] = False - def _stopgame(self): + def _stopgame(self, guild): """Stops the game in current state""" - self.the_data["running"] = False - self.save_data() - - async def _checkdone(self, channel=None): - if self.winbool: - if channel: - await self.bot.send_message(channel, "You Win!") - else: - await self.bot.say("You Win!") - self._stopgame() - - if self.the_data["hangman"] >= 7: - if channel: - await self.bot.send_message(channel, "You Lose!\nThe Answer was: **"+self.the_data["answer"]+"**") - else: - await self.bot.say("You Lose!\nThe Answer was: **"+self.the_data["answer"]+"**") + self.the_data[guild]["running"] = False + + async def _checkdone(self, channel): + if self.winbool[channel.guild]: + await channel.send("You Win!") + self._stopgame(channel.guild) + return - self._stopgame() + if self.the_data[channel.guild]["hangman"] >= 7: + await channel.send("You Lose!\nThe Answer was: **"+self.the_data[channel.guild]["answer"]+"**") + + self._stopgame(channel.guild) def _getphrase(self): """Get a new phrase for the game and returns it""" @@ -206,7 +203,6 @@ class Hangman: outphrase = "" while outphrase == "": outphrase = phrases[randint(0, len(phrases)-1)].partition(" (")[0] -# outphrase = phrases[randint(0,10)].partition(" (")[0] return outphrase def _hideanswer(self): @@ -234,27 +230,19 @@ class Hangman: return out_str - async def _guessletter(self, guess, channel=None): + async def _guessletter(self, guess, channel): """Checks the guess on a letter and prints game if acceptable guess""" - if not guess.upper() in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or not len(guess) == 1: - if channel: - await self.bot.send_message(channel, "Invalid guess. Only A-Z is accepted") - else: - await self.bot.say("Invalid guess. Only A-Z is accepted") + if guess.upper() not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or len(guess) != 1: + await channel.send("Invalid guess. Only A-Z is accepted") return - if guess.upper() in self.the_data["guesses"]: - if channel: - await self.bot.send_message(channel, "Already guessed that! Try again") - else: - await self.bot.say("Already guessed that! Try again") + if guess.upper() in self.the_data[channel.guild]["guesses"]: + await channel.send("Already guessed that! Try again") return - - if not guess.upper() in self.the_data["answer"]: + if guess.upper() not in self.the_data[channel.guild]["answer"]: self.the_data["hangman"] += 1 - self.the_data["guesses"].append(guess.upper()) - self.save_data() + self.the_data[channel.guild]["guesses"].append(guess.upper()) await self._printgame(channel) @@ -290,66 +278,46 @@ class Hangman: async def _reactmessage_menu(self, message): """React with menu options""" - await self.bot.clear_reactions(message) + await message.clear_reactions() - await self.bot.add_reaction(message, self.navigate[0]) - await self.bot.add_reaction(message, self.navigate[-1]) + await message.add_reaction(self.navigate[0]) + await message.add_reaction(self.navigate[-1]) async def _reactmessage_am(self, message): - await self.bot.clear_reactions(message) + await message.clear_reactions() for x in range(len(self.letters)): if x in [i for i,b in enumerate("ABCDEFGHIJKLM") if b not in self._guesslist()]: - await self.bot.add_reaction(message, self.letters[x]) + await message.add_reaction(self.letters[x]) - await self.bot.add_reaction(message, self.navigate[-1]) - + await message.add_reaction(self.navigate[-1]) async def _reactmessage_nz(self, message): await self.bot.clear_reactions(message) for x in range(len(self.letters)): if x in [i for i,b in enumerate("NOPQRSTUVWXYZ") if b not in self._guesslist()]: - await self.bot.add_reaction(message, self.letters[x+13]) + await message.add_reaction(self.letters[x+13]) - await self.bot.add_reaction(message, self.navigate[0]) + await message.add_reaction(self.navigate[0]) - async def _printgame(self, channel=None): + async def _printgame(self, channel): """Print the current state of game""" cSay = ("Guess this: " + str(self._hideanswer()) + "\n" + "Used Letters: " + str(self._guesslist()) + "\n" + self.hanglist[self.the_data["hangman"]] + "\n" + self.navigate[0]+" for A-M, "+self.navigate[-1]+" for N-Z") - if channel: - message = await self.bot.send_message(channel, cSay) - else: - message = await self.bot.say(cSay) - + + message = await channel.send(cSay) + self.the_data["trackmessage"] = message.id - self.save_data() + await self._reactmessage_menu(message) await self._checkdone(channel) - -def check_folders(): - if not os.path.exists("data/Fox-Cogs"): - print("Creating data/Fox-Cogs folder...") - os.makedirs("data/Fox-Cogs") - - if not os.path.exists("data/Fox-Cogs/hangman"): - print("Creating data/Fox-Cogs/hangman folder...") - os.makedirs("data/Fox-Cogs/hangman") - - -def check_files(): - if not dataIO.is_valid_json("data/Fox-Cogs/hangman/hangman.json"): - dataIO.save_json("data/Fox-Cogs/hangman/hangman.json", {"running": False, "hangman": 0, "guesses": [], "theface": "<:never:336861463446814720>", "trackmessage": False}) - def setup(bot): - check_folders() - check_files() n = Hangman(bot) bot.add_cog(n) bot.add_listener(n._on_react, "on_reaction_add")