From e4a44fffefd20ea532ff942b30c7efcc446394ea Mon Sep 17 00:00:00 2001 From: NikolajDanger Date: Sun, 4 Apr 2021 15:12:34 +0200 Subject: [PATCH] :sparkles: Converted all hangman functionality to slash commands --- cogs/GameCogs.py | 7 +- cogs/ReactionCog.py | 10 ++- funcs/games/gameLoops.py | 37 -------- funcs/games/hangman.py | 185 ++++++++++++++++++++++++--------------- utils/helperClasses.py | 9 +- 5 files changed, 133 insertions(+), 115 deletions(-) diff --git a/cogs/GameCogs.py b/cogs/GameCogs.py index 50a11ff..ae07f11 100644 --- a/cogs/GameCogs.py +++ b/cogs/GameCogs.py @@ -99,16 +99,16 @@ class HangmanCog(commands.Cog): def __init__(self,bot): """Runs game stuff.""" self.bot = bot + # Starts a game of Hangman @cog_ext.cog_subcommand(**params["hangmanStart"]) async def hangmanStart(self, ctx): - await ctx.defer() - await self.bot.games.gameLoops.runHangman(ctx.channel,"#"+str(ctx.author.id),"start", ctx) + await self.bot.games.hangman.start(ctx) # Stops a game of Hangman @cog_ext.cog_subcommand(**params["hangmanStop"]) async def hangmanStop(self, ctx): - await self.bot.games.gameLoops.runHangman(ctx.channel,"#"+str(ctx.author.id),"stop", ctx) + await self.bot.games.hangman.stop(ctx) class HexCog(commands.Cog): @@ -147,6 +147,7 @@ class HexCog(commands.Cog): async def hexPlace(self, ctx, coordinates): await self.bot.games.gameLoops.runHex(ctx, "place "+coordinates, "#"+str(ctx.author.id)) + def setup(bot): bot.add_cog(GamesCog(bot)) bot.add_cog(BlackjackCog(bot)) diff --git a/cogs/ReactionCog.py b/cogs/ReactionCog.py index 741d66a..d3f21bf 100644 --- a/cogs/ReactionCog.py +++ b/cogs/ReactionCog.py @@ -39,9 +39,13 @@ class ReactionCog(commands.Cog): else: imdbName = imdbIds[showPick-1] await self.bot.other.bedreNetflix.addShow(channel,imdbName) - elif self.bot.databaseFuncs.hangmanReactionTest(channel,message) and ord(reaction.emoji) in range(127462,127488): - guess = chr(ord(reaction.emoji)-127397) - await self.bot.games.gameLoops.runHangman(channel,"#"+str(user.id),command="guess "+guess) + elif self.bot.databaseFuncs.hangmanReactionTest(channel, message, f"#{user.id}"): + self.bot.log("They reacted to the hangman message") + if ord(reaction.emoji) in range(127462,127488): + guess = chr(ord(reaction.emoji)-127397) + await self.bot.games.hangman.guess(message, f"#{user.id}", guess) + else: + self.bot.log("Bot they didn't react with a valid guess") def setup(bot): bot.add_cog(ReactionCog(bot)) diff --git a/funcs/games/gameLoops.py b/funcs/games/gameLoops.py index f680558..da6fec8 100644 --- a/funcs/games/gameLoops.py +++ b/funcs/games/gameLoops.py @@ -90,43 +90,6 @@ class GameLoops(): self.bot.databaseFuncs.deleteGame("connect 4 games",channelId) - async def runHangman(self,channel,user,command = "start", ctx = None): - try: - response, showImage, deleteImage, remainingLetters = self.bot.games.hangman.parseHangman(str(channel.id),user,command) - except: - self.bot.log("Error parsing command (error code 1701)") - if response != "": - if ctx is None: - await channel.send(response) - else: - await ctx.send(response) - self.bot.log(response,str(channel.id)) - if showImage: - if deleteImage: - await self.deleteMessage("hangman"+str(channel.id),channel) - oldImage = await channel.send(file = discord.File("resources/games/hangmanBoards/hangmanBoard"+str(channel.id)+".png")) - - if len(remainingLetters) > 15: - otherMessage = await channel.send("_ _") - reactionMessages = {oldImage : remainingLetters[:15],otherMessage : remainingLetters[15:]} - else: - otherMessage = "" - reactionMessages = {oldImage : remainingLetters} - - oldMessages = str(oldImage.id) - if otherMessage != "": - oldMessages += "\n"+str(otherMessage.id) - with open("resources/games/oldImages/hangman"+str(channel.id), "w") as f: - f.write(oldMessages) - - try: - for message, letters in reactionMessages.items(): - for letter in letters: - emoji = chr(ord(letter)+127397) - await message.add_reaction(emoji) - except: - self.bot.log("Image deleted before adding all reactions") - # Runs Hex async def runHex(self,ctx,command,user): channelId = ctx.channel_id diff --git a/funcs/games/hangman.py b/funcs/games/hangman.py index dcd50df..294fe59 100644 --- a/funcs/games/hangman.py +++ b/funcs/games/hangman.py @@ -1,4 +1,4 @@ -import json, urllib, datetime, string +import json, urllib, datetime, string, discord from .hangmanDraw import DrawHangman @@ -9,8 +9,13 @@ class Hangman(): self.bot = bot self.draw = DrawHangman(bot) - def hangmanStart(self,channel,user): + async def start(self, ctx): + await ctx.defer() + channel = str(ctx.channel_id) + user = f"#{ctx.author.id}" game = self.bot.database["hangman games"].find_one({"_id":channel}) + userName = self.bot.databaseFuncs.getName(user) + startedGame = False if game == None: apiKey = self.bot.credentials.wordnikKey @@ -26,86 +31,128 @@ class Hangman(): remainingLetters = list(string.ascii_uppercase) - try: - self.draw.drawImage(channel) - except: - self.bot.log("Error drawing image (error code 1710)") - return f"{self.bot.databaseFuncs.getName(user)} started game of hangman.", True, False, remainingLetters - else: - return "There's already a Hangman game going on in the channel", False, False, [] + self.draw.drawImage(channel) - def hangmanStop(self,channel): + logMessage = "Game started" + sendMessage = f"{userName} started game of hangman." + startedGame = True + else: + logMessage = "There was already a game going on" + sendMessage = "There's already a Hangman game going on in the channel" + + self.bot.log(logMessage) + await ctx.send(sendMessage) + + if startedGame: + filePath = f"resources/games/hangmanBoards/hangmanBoard{channel}.png" + newImage = await ctx.channel.send(file = discord.File(filePath)) + + blankMessage = await ctx.channel.send("_ _") + reactionMessages = {newImage : remainingLetters[:15], blankMessage : remainingLetters[15:]} + + oldMessages = f"{newImage.id}\n{blankMessage.id}" + + with open(f"resources/games/oldImages/hangman{channel}", "w") as f: + f.write(oldMessages) + + for message, letters in reactionMessages.items(): + for letter in letters: + emoji = chr(ord(letter)+127397) + await message.add_reaction(emoji) + + async def stop(self, ctx): + channel = str(ctx.channel.id) self.bot.database["hangman games"].delete_one({"_id":channel}) - return "Game stopped.", False, False, [] + with open(f"resources/games/oldImages/hangman{channel}", "r") as f: + messages = f.read().splitlines() - def hangmanGuess(self,channel,user,guess): + for message in messages: + oldMessage = await ctx.channel.fetch_message(int(message)) + self.bot.log("Deleting old message") + await oldMessage.delete() + + await ctx.send("Game stopped") + + async def guess(self, message, user, guess): + channel = str(message.channel.id) game = self.bot.database["hangman games"].find_one({"_id":channel}) - if game != None: - if user == game["player"]: - if len(guess) == 1 and guess in list(string.ascii_uppercase): - if guess not in game["guessed letters"]: - correctGuess = 0 + gameExists = (game != None) + singleLetter = (len(guess) == 1 and guess.isalpha()) + newGuess = (guess not in game["guessed letters"]) + validGuess = (gameExists and singleLetter and newGuess) - for x, letter in enumerate(game["word"]): - if guess == letter: - correctGuess += 1 - self.bot.database["hangman games"].update_one({"_id":channel},{"$set":{"guessed."+str(x):True}}) + if validGuess: + self.bot.log("Guessed the letter") + correctGuess = 0 - if correctGuess == 0: - self.bot.database["hangman games"].update_one({"_id":channel},{"$inc":{"misses":1}}) + for x, letter in enumerate(game["word"]): + if guess == letter: + correctGuess += 1 + self.bot.database["hangman games"].update_one({"_id":channel},{"$set":{"guessed."+str(x):True}}) - self.bot.database["hangman games"].update_one({"_id":channel},{"$push":{"guessed letters":guess}}) + if correctGuess == 0: + self.bot.database["hangman games"].update_one({"_id":channel},{"$inc":{"misses":1}}) - remainingLetters = list(string.ascii_uppercase) + self.bot.database["hangman games"].update_one({"_id":channel},{"$push":{"guessed letters":guess}}) - game = self.bot.database["hangman games"].find_one({"_id":channel}) + remainingLetters = list(string.ascii_uppercase) - for letter in game["guessed letters"]: - remainingLetters.remove(letter) + game = self.bot.database["hangman games"].find_one({"_id":channel}) - if correctGuess == 1: - message = f"Guessed {guess}. There was 1 {guess} in the word." - else: - message = f"Guessed {guess}. There were {correctGuess} {guess}s in the word." + for letter in game["guessed letters"]: + remainingLetters.remove(letter) - try: - self.draw.drawImage(channel) - except: - self.bot.log("Error drawing image (error code 1710)") - - if game["misses"] == 6: - self.hangmanStop(channel) - return message+" You've guessed wrong six times and have lost the game.", True, True, [] - elif all(i == True for i in game["guessed"]): - self.hangmanStop(channel) - self.bot.money.addMoney(user,15) - return message+" You've guessed the word! Congratulations! Adding 15 GwendoBucks to your account", True, True, [] - else: - return message, True, True, remainingLetters - else: - return f"You've already guessed {guess}", False, False, [] - else: - return "", False, False, [] + if correctGuess == 1: + sendMessage = f"Guessed {guess}. There was 1 {guess} in the word." else: - return "", False, False, [] - else: - return "There's no Hangman game going on in this channel", False, False, [] + sendMessage = f"Guessed {guess}. There were {correctGuess} {guess}s in the word." + + self.draw.drawImage(channel) + + if game["misses"] == 6: + self.bot.database["hangman games"].delete_one({"_id":channel}) + sendMessage += " You've guessed wrong six times and have lost the game." + remainingLetters = [] + elif all(i == True for i in game["guessed"]): + self.bot.database["hangman games"].delete_one({"_id":channel}) + self.bot.money.addMoney(user,15) + sendMessage += " You've guessed the word! Congratulations! Adding 15 GwendoBucks to your account" + remainingLetters = [] + + await message.channel.send(sendMessage) + + with open(f"resources/games/oldImages/hangman{channel}", "r") as f: + oldMessageIDs = f.read().splitlines() + + for oldID in oldMessageIDs: + oldMessage = await message.channel.fetch_message(int(oldID)) + self.bot.log("Deleting old message") + await oldMessage.delete() + + filePath = f"resources/games/hangmanBoards/hangmanBoard{channel}.png" + newImage = await message.channel.send(file = discord.File(filePath)) + + if len(remainingLetters) > 0: + if len(remainingLetters) > 15: + blankMessage = await message.channel.send("_ _") + reactionMessages = {newImage : remainingLetters[:15], blankMessage : remainingLetters[15:]} + else: + blankMessage = "" + reactionMessages = {newImage : remainingLetters} + + if blankMessage != "": + oldMessages = f"{newImage.id}\n{blankMessage.id}" + else: + oldMessages = str(newImage.id) + + with open(f"resources/games/oldImages/hangman{channel}", "w") as f: + f.write(oldMessages) + + for message, letters in reactionMessages.items(): + for letter in letters: + emoji = chr(ord(letter)+127397) + await message.add_reaction(emoji) + - def parseHangman(self,channel,user,command): - if command == "start": - try: - return self.hangmanStart(channel,user) - except: - self.bot.log("Error starting game (error code 1730)") - elif command == "stop": - return self.hangmanStop(channel) - elif command.startswith("guess "): - guess = command[6:].upper() - try: - return self.hangmanGuess(channel,user,guess) - except: - self.bot.log("Error in guessing (Error Code 1720)") - else: - return "I didn't understand that", False, False, [] diff --git a/utils/helperClasses.py b/utils/helperClasses.py index 56a1aa4..3a95326 100644 --- a/utils/helperClasses.py +++ b/utils/helperClasses.py @@ -100,7 +100,7 @@ class databaseFuncs(): else: return False, 0 - def hangmanReactionTest(self, channel,message): + def hangmanReactionTest(self, channel, message, user): try: with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f: oldMessages = f.read().splitlines() @@ -111,8 +111,11 @@ class databaseFuncs(): for oldMessage in oldMessages: oldMessageID = int(oldMessage) if message.id == oldMessageID: - self.bot.log("They reacted to the hangman game") - gameMessage = True + game = self.bot.database["hangman games"].find_one({"_id":str(channel.id)}) + if user == game["player"]: + gameMessage = True + + break return gameMessage