166 lines
6.8 KiB
Python
166 lines
6.8 KiB
Python
import json, urllib, datetime, string, discord
|
|
|
|
from .hangmanDraw import DrawHangman
|
|
|
|
apiUrl = "https://api.wordnik.com/v4/words.json/randomWords?hasDictionaryDef=true&minCorpusCount=5000&maxCorpusCount=-1&minDictionaryCount=1&maxDictionaryCount=-1&minLength=3&maxLength=11&limit=1&api_key="
|
|
|
|
class Hangman():
|
|
def __init__(self,bot):
|
|
self.bot = bot
|
|
self.draw = DrawHangman(bot)
|
|
|
|
async def start(self, ctx):
|
|
await self.bot.defer(ctx)
|
|
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
|
|
word = "-"
|
|
while "-" in word or "." in word:
|
|
with urllib.request.urlopen(apiUrl+apiKey) as p:
|
|
word = list(json.load(p)[0]["word"].upper())
|
|
self.bot.log("Found the word \""+"".join(word)+"\"")
|
|
guessed = [False] * len(word)
|
|
gameID = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
|
newGame = {"_id":channel,"player" : user,"guessed letters" : [],"word" : word,"game ID" : gameID,"misses" : 0,"guessed" : guessed}
|
|
self.bot.database["hangman games"].insert_one(newGame)
|
|
|
|
remainingLetters = list(string.ascii_uppercase)
|
|
|
|
self.draw.drawImage(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)
|
|
game = self.bot.database["hangman games"].find_one({"_id": channel})
|
|
|
|
if game is None:
|
|
await ctx.send("There's no game going on")
|
|
elif f"#{ctx.author.id}" != game["player"]:
|
|
await ctx.send("You can't end a game you're not in")
|
|
else:
|
|
self.bot.database["hangman games"].delete_one({"_id":channel})
|
|
|
|
with open(f"resources/games/oldImages/hangman{channel}", "r") as f:
|
|
messages = f.read().splitlines()
|
|
|
|
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})
|
|
|
|
gameExists = (game != None)
|
|
singleLetter = (len(guess) == 1 and guess.isalpha())
|
|
newGuess = (guess not in game["guessed letters"])
|
|
validGuess = (gameExists and singleLetter and newGuess)
|
|
|
|
if validGuess:
|
|
self.bot.log("Guessed the letter")
|
|
correctGuess = 0
|
|
|
|
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 correctGuess == 0:
|
|
self.bot.database["hangman games"].update_one({"_id":channel},{"$inc":{"misses":1}})
|
|
|
|
self.bot.database["hangman games"].update_one({"_id":channel},{"$push":{"guessed letters":guess}})
|
|
|
|
remainingLetters = list(string.ascii_uppercase)
|
|
|
|
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
|
|
|
for letter in game["guessed letters"]:
|
|
remainingLetters.remove(letter)
|
|
|
|
if correctGuess == 1:
|
|
sendMessage = f"Guessed {guess}. There was 1 {guess} in the word."
|
|
else:
|
|
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)
|
|
|
|
|