Hangman

This commit is contained in:
NikolajDanger
2020-08-08 19:13:43 +02:00
parent 1490cf81eb
commit 2daefb9585
15 changed files with 225 additions and 71 deletions

View File

@ -24,7 +24,6 @@ class GamesCog(commands.Cog):
async def give(self, ctx, *, content): async def give(self, ctx, *, content):
commands = content.split(" ") commands = content.split(" ")
if len(commands) == 2: if len(commands) == 2:
print(commands)
amount = int(commands[1]) amount = int(commands[1])
response = giveMoney("#"+str(ctx.message.author.id),commands[0],amount) response = giveMoney("#"+str(ctx.message.author.id),commands[0],amount)
await ctx.send(response) await ctx.send(response)

View File

@ -35,7 +35,7 @@ class MiscCog(commands.Cog):
logThis(content,str("Logged by "+ctx.message.author.display_name)) logThis(content,str("Logged by "+ctx.message.author.display_name))
# Restarts the bot # Restarts the bot
@commands.command(hidden = True) @commands.command(hidden = True,aliases=["stop"])
async def restart(self, ctx): async def restart(self, ctx):
if "#"+str(ctx.message.author.id) in ["#266269899859427329", "#380732645602230272"]: if "#"+str(ctx.message.author.id) in ["#266269899859427329", "#380732645602230272"]:
await ctx.send("Pulling git repo and restarting...") await ctx.send("Pulling git repo and restarting...")

View File

@ -1,6 +1,6 @@
from discord.ext import commands from discord.ext import commands
from funcs import logThis, fiarReactionTest, monopolyReactionTest, emojiToCommand, fiar, runMonopoly from funcs import logThis, fiarReactionTest, monopolyReactionTest, emojiToCommand, fiar, runMonopoly, hangmanReactionTest, runHangman
class ReactionCog(commands.Cog): class ReactionCog(commands.Cog):
def __init__(self, client): def __init__(self, client):
@ -23,5 +23,8 @@ class ReactionCog(commands.Cog):
await fiar(channel," place "+str(piece)+" "+str(place),user.id) await fiar(channel," place "+str(piece)+" "+str(place),user.id)
elif monopolyReactionTest(channel,message): elif monopolyReactionTest(channel,message):
await runMonopoly(channel,"roll","#"+str(user.id)) await runMonopoly(channel,"roll","#"+str(user.id))
elif hangmanReactionTest(channel,message):
guess = chr(ord(reaction.emoji)-127397)
await runHangman(channel,"#"+str(user.id),"guess "+guess)
def setup(client): def setup(client):
client.add_cog(ReactionCog(client)) client.add_cog(ReactionCog(client))

View File

@ -1,8 +1,8 @@
"""A collection of all Gwendolyn functions.""" """A collection of all Gwendolyn functions."""
__all__ = ["helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToCommand", "fiarReactionTest", "deleteGame", "stopServer", "checkBalance", "giveMoney", "addMoney", "triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "spellFunc", "monsterFunc", "nameGen", "tavernGen", "movieFunc", "roll_dice", "parseChar", "parseRoll", "critRoll", "parseDestiny", "addToDict", "getName", "getID", "replaceMultiple", "monopolyReactionTest","parseInvest", "blackjackLoop", "fiar", "runMonopoly", "runHex", "runHangman"] __all__ = ["helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToCommand", "fiarReactionTest", "deleteGame", "stopServer", "checkBalance", "giveMoney", "addMoney", "triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "spellFunc", "monsterFunc", "nameGen", "tavernGen", "movieFunc", "roll_dice", "parseChar", "parseRoll", "critRoll", "parseDestiny", "addToDict", "getName", "getID", "replaceMultiple", "monopolyReactionTest","parseInvest", "blackjackLoop", "fiar", "runMonopoly", "runHex", "runHangman","hangmanReactionTest"]
from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToCommand, fiarReactionTest, deleteGame, stopServer, addToDict, getName, getID, monopolyReactionTest from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToCommand, fiarReactionTest, deleteGame, stopServer, addToDict, getName, getID, monopolyReactionTest, hangmanReactionTest
from .games import checkBalance, giveMoney, addMoney, triviaCountPoints, triviaStart, triviaAnswer, blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit, parseInvest, blackjackLoop, fiar, runMonopoly, runHex, runHangman from .games import checkBalance, giveMoney, addMoney, triviaCountPoints, triviaStart, triviaAnswer, blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit, parseInvest, blackjackLoop, fiar, runMonopoly, runHex, runHangman

View File

@ -13,15 +13,17 @@ from .hangman import parseHangman
# Deletes a message # Deletes a message
async def deleteMessage(imageLocation,channel): async def deleteMessage(imageLocation,channel):
try: try:
logThis("Finding old image")
with open("resources/games/oldImages/"+imageLocation, "r") as f: with open("resources/games/oldImages/"+imageLocation, "r") as f:
oldImage = await channel.fetch_message(int(f.read())) messages = f.read().splitlines()
logThis("Deleting old image")
await oldImage.delete()
except:
oldImage = ""
return oldImage for message in messages:
oldMessage = await channel.fetch_message(int(message))
logThis("Deleting old message")
await oldMessage.delete()
except:
oldMessage = ""
return oldMessage
# Runs Hex # Runs Hex
async def runHex(channel,command,user): async def runHex(channel,command,user):
@ -245,11 +247,31 @@ async def runHangman(channel,user,command = "start"):
response, showImage, deleteImage, remainingLetters = parseHangman(str(channel.id),user,command) response, showImage, deleteImage, remainingLetters = parseHangman(str(channel.id),user,command)
except: except:
logThis("Error parsing command (error code 1701)") logThis("Error parsing command (error code 1701)")
if response != "":
await channel.send(response) await channel.send(response)
logThis(response,str(channel.id)) logThis(response,str(channel.id))
if showImage: if showImage:
if deleteImage: if deleteImage:
oldImage = await deleteMessage("hangman"+str(channel.id),channel) await deleteMessage("hangman"+str(channel.id),channel)
oldImage = await channel.send(file = discord.File("resources/games/hangmanBoards/hangmanBoard"+str(channel.id)+".png")) 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: with open("resources/games/oldImages/hangman"+str(channel.id), "w") as f:
f.write(str(oldImage.id)) 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:
logThis("Image deleted before adding all reactions")

View File

@ -1,6 +1,6 @@
import json, urllib, random, datetime, string import json, urllib, random, datetime, string
from . import hangmanDraw from . import hangmanDraw, money
from funcs import getName, logThis from funcs import getName, logThis
def hangmanStart(channel,user): def hangmanStart(channel,user):
@ -8,9 +8,12 @@ def hangmanStart(channel,user):
data = json.load(f) data = json.load(f)
if channel not in data: if channel not in data:
with urllib.request.urlopen("https://random-word-api.herokuapp.com/word?number=10") as p: with urllib.request.urlopen("https://random-word-api.herokuapp.com/word?number=20") as p:
words = json.load(p) words = json.load(p)
word = "disestablishmentarianism"
while len(word) > 11:
word = list(random.choice(words).upper()) word = list(random.choice(words).upper())
logThis("Found the word \""+"".join(word)+"\"")
guessed = [False] * len(word) guessed = [False] * len(word)
gameID = datetime.datetime.now().strftime('%Y%m%d%H%M%S') gameID = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
data[channel] = {"player" : user,"guessed letters" : [],"word" : word,"game ID" : gameID,"misses" : 0,"guessed" : guessed} data[channel] = {"player" : user,"guessed letters" : [],"word" : word,"game ID" : gameID,"misses" : 0,"guessed" : guessed}
@ -26,12 +29,9 @@ def hangmanStart(channel,user):
logThis("Error drawing image (error code 1710)") logThis("Error drawing image (error code 1710)")
return f"{getName(user)} started game of hangman.", True, False, remainingLetters return f"{getName(user)} started game of hangman.", True, False, remainingLetters
else: else:
return "There's already a game going on in the channel", False, False, [] return "There's already a Hangman game going on in the channel", False, False, []
def parseHangman(channel,user,command): def hangmanStop(channel):
if command == "start":
return hangmanStart(channel,user)
elif command == "stop":
with open("resources/games/hangmanGames.json", "r") as f: with open("resources/games/hangmanGames.json", "r") as f:
data = json.load(f) data = json.load(f)
@ -40,5 +40,76 @@ def parseHangman(channel,user,command):
json.dump(data,f,indent=4) json.dump(data,f,indent=4)
return "Game stopped.", False, False, [] return "Game stopped.", False, False, []
def hangmanGuess(channel,user,guess):
with open("resources/games/hangmanGames.json", "r") as f:
data = json.load(f)
if channel in data:
if user == data[channel]["player"]:
if len(guess) == 1:
if guess not in data[channel]["guessed letters"]:
correctGuess = 0
for x, letter in enumerate(data[channel]["word"]):
if guess == letter:
correctGuess += 1
data[channel]["guessed"][x] = True
if correctGuess == 0:
data[channel]["misses"] += 1
data[channel]["guessed letters"].append(guess)
remainingLetters = list(string.ascii_uppercase)
for letter in data[channel]["guessed letters"]:
remainingLetters.remove(letter)
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."
with open("resources/games/hangmanGames.json", "w") as f:
json.dump(data,f)
try:
hangmanDraw.drawImage(channel)
except:
logThis("Error drawing image (error code 1710)")
if data[channel]["misses"] == 6:
hangmanStop(channel)
return message+" You've guessed wrong six times and have lost the game.", True, True, []
elif all(i == True for i in data[channel]["guessed"]):
hangmanStop(channel)
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, []
else:
return "", False, False, []
else:
return "There's no Hangman game going on in this channel", False, False, []
def parseHangman(channel,user,command):
if command == "start":
try:
return hangmanStart(channel,user)
except:
logThis("Error starting game (error code 1730)")
elif command == "stop":
return hangmanStop(channel)
elif command.startswith("guess "):
guess = command[6:].upper()
try:
return hangmanGuess(channel,user,guess)
except:
logThis("Error in guessing (Error Code 1720)")
else: else:
return "I didn't understand that", False, False, [] return "I didn't understand that", False, False, []

View File

@ -4,30 +4,27 @@ from PIL import ImageDraw, Image, ImageFont
from funcs import logThis from funcs import logThis
circleDegrees = 360 circleDegrees = 360
circleSize = 400 circleSize = 120
lineWidth = 40 lineWidth = 12
bodySize = 700 bodySize =210
limbSize = 300 limbSize = 60
armPosition = 200 armPosition = 60
manx = (limbSize*2)+lineWidth*4 manx = (limbSize*2)+lineWidth*4
many = (circleSize+bodySize+limbSize)+lineWidth*4 many = (circleSize+bodySize+limbSize)+lineWidth*4
letterSize = 250 letterSize = 75
textSize = 70 textSize = 70
letterLineLength = 300 letterLineLength = 90
letterLineDistance = 100 letterLineDistance = 30
gallowx, gallowy = 1200,2000 gallowx, gallowy = 360,600
goldenRatio = 1-(1 / ((1 + 5 ** 0.5) / 2)) goldenRatio = 1-(1 / ((1 + 5 ** 0.5) / 2))
smolGallowx, smolGallowy = int(gallowx * (3/10)),int(gallowy * (3/10)) fnt = ImageFont.truetype('resources/comic-sans-bold.ttf', letterSize)
smolManx, smolMany = int(manx * (3/10)),int(many * (3/10)) smolfnt = ImageFont.truetype('resources/comic-sans-bold.ttf', textSize)
fnt = ImageFont.truetype('resources/comic-sans.ttf', letterSize)
smolfnt = ImageFont.truetype('resources/comic-sans.ttf', textSize)
backgroundColor = (255,255,255,255) backgroundColor = (255,255,255,255)
@ -140,23 +137,23 @@ def drawMan(misses):
return background return background
def badText(text, big): def badText(text, big, color=(0,0,0,255)):
if big: font = fnt if big: font = fnt
else: font = smolfnt else: font = smolfnt
w, h = font.getsize(text) w, h = font.getsize(text)
img = Image.new("RGBA",(w,h),color=(0,0,0,0)) img = Image.new("RGBA",(w,h),color=(0,0,0,0))
d = ImageDraw.Draw(img,"RGBA") d = ImageDraw.Draw(img,"RGBA")
d.text((0,0),text,font=font,fill=(0,0,0,255)) d.text((0,0),text,font=font,fill=color)
return img return img
def drawGallows(): def drawGallows():
background = Image.new("RGBA",(gallowx,gallowy),color=(0,0,0,0)) background = Image.new("RGBA",(gallowx,gallowy),color=(0,0,0,0))
bottomLine = badLine(int(gallowx*0.75),True) bottomLine = badLine(int(gallowx*0.75),True)
background.paste(bottomLine,(int(gallowx*0.125),gallowy-(lineWidth*3)),bottomLine) background.paste(bottomLine,(int(gallowx*0.125),gallowy-(lineWidth*4)),bottomLine)
lineTwo = badLine(gallowy-lineWidth*4) lineTwo = badLine(gallowy-lineWidth*6)
background.paste(lineTwo,(int(gallowx*(0.75*goldenRatio)),lineWidth*2),lineTwo) background.paste(lineTwo,(int(gallowx*(0.75*goldenRatio)),lineWidth*2),lineTwo)
topLine = badLine(int(gallowy*0.30),True) topLine = badLine(int(gallowy*0.30),True)
@ -166,49 +163,87 @@ def drawGallows():
background.paste(lastLine,((int(gallowx*(0.75*goldenRatio))+int(gallowy*0.30)-lineWidth),lineWidth*3),lastLine) background.paste(lastLine,((int(gallowx*(0.75*goldenRatio))+int(gallowy*0.30)-lineWidth),lineWidth*3),lastLine)
return background return background
def drawLetterLines(word,guessed,misses):
letterLines = Image.new("RGBA",((letterLineLength+letterLineDistance)*len(word),letterLineLength+lineWidth*3),color=(0,0,0,0))
for x, letter in enumerate(word):
line = badLine(letterLineLength,True)
letterLines.paste(line,(x*(letterLineLength+letterLineDistance),letterLineLength),line)
if guessed[x]:
letterDrawing = badText(letter,True)
letterWidth = fnt.getsize(letter)[0]
letterx = int(x*(letterLineLength+letterLineDistance)-(letterWidth/2)+(letterLineLength*0.5)+(lineWidth*2))
letterLines.paste(letterDrawing,(letterx,0),letterDrawing)
elif misses == 6:
letterDrawing = badText(letter,True,(242,66,54))
letterWidth = fnt.getsize(letter)[0]
letterx = int(x*(letterLineLength+letterLineDistance)-(letterWidth/2)+(letterLineLength*0.5)+(lineWidth*2))
letterLines.paste(letterDrawing,(letterx,0),letterDrawing)
return letterLines
def shortestDist(positions,newPosition):
shortestDist = math.inf
x, y = newPosition
for i, j in positions:
xdist = abs(i-x)
ydist = abs(j-y)
dist = math.sqrt(xdist**2+ydist**2)
if shortestDist > dist: shortestDist = dist
return shortestDist
def drawMisses(guesses,word):
background = Image.new("RGBA",(600,400),color=(0,0,0,0))
pos = []
for guess in guesses:
if guess not in word:
placed = False
while placed == False:
letter = badText(guess,True)
w, h = fnt.getsize(guess)
x = random.randint(0,600-w)
y = random.randint(0,400-h)
if shortestDist(pos,(x,y)) > 70:
pos.append((x,y))
background.paste(letter,(x,y),letter)
placed = True
return background
def drawImage(channel): def drawImage(channel):
with open("resources/games/hangmanGames.json", "r") as f: with open("resources/games/hangmanGames.json", "r") as f:
data = json.load(f) data = json.load(f)
random.seed(data[channel]["game ID"]) random.seed(data[channel]["game ID"])
background = Image.new("RGBA",(1600,1000),color=backgroundColor) background = Image.open("resources/paper.jpg")
try: try:
gallow = drawGallows() gallow = drawGallows()
except: except:
logThis("Error drawing gallows (error code 1711)") logThis("Error drawing gallows (error code 1711)")
gallow = gallow.resize((smolGallowx,smolGallowy))
try: try:
man = drawMan(data[channel]["misses"]) man = drawMan(data[channel]["misses"])
except: except:
logThis("Error drawing stick figure (error code 1712)") logThis("Error drawing stick figure (error code 1712)")
random.seed(data[channel]["game ID"])
try: try:
man = man.resize((smolManx,smolMany)) letterLines = drawLetterLines(data[channel]["word"],data[channel]["guessed"],data[channel]["misses"])
except: except:
logThis("Error resizing") logThis("error drawing letter lines (error code 1713)")
random.seed(data[channel]["game ID"])
try:
misses = drawMisses(data[channel]["guessed letters"],data[channel]["word"])
except:
logThis("Error drawing misses (error code 1714)")
background.paste(gallow,(100,100),gallow) background.paste(gallow,(100,100),gallow)
background.paste(man,(280,210),man) background.paste(man,(300,210),man)
background.paste(letterLines,(120,840),letterLines)
background.paste(misses,(600,150),misses)
letterLines = Image.new("RGBA",((letterLineLength+letterLineDistance)*len(data[channel]["word"]),300+lineWidth*3),color=(0,0,0,0)) missesText = badText("MISSES",False)
for x, letter in enumerate(data[channel]["word"]): missesTextWidth = missesText.size[0]
line = badLine(letterLineLength,True) background.paste(missesText,(850-int(missesTextWidth/2),50),missesText)
letterLines.paste(line,(x*(letterLineLength+letterLineDistance),300),line)
if data[channel]["guessed"][x]:
letterDrawing = badText(letter,True)
letterWidth = fnt.getsize(letter)[0]
letterx = int(x*(letterLineLength+letterLineDistance)-(letterWidth/2)+(letterLineLength*0.5)+(lineWidth*2))
letterLines.paste(letterDrawing,(letterx,0),letterDrawing)
llw, llh = letterLines.size
letterLines = letterLines.resize((int(llw*(3/10)),int(llh*(3/10))))
background.paste(letterLines,(120,860),letterLines)
d = ImageDraw.Draw(background,"RGBA")
d.text((850,50),"Misses",font=smolfnt,fill=(0,0,0,255))
background.save("resources/games/hangmanBoards/hangmanBoard"+channel+".png") background.save("resources/games/hangmanBoards/hangmanBoard"+channel+".png")

View File

@ -234,6 +234,20 @@ def monopolyReactionTest(channel,message):
else: else:
return False return False
def hangmanReactionTest(channel,message):
with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f:
oldMessages = f.read().splitlines()
gameMessage = False
for oldMessage in oldMessages:
oldMessageID = int(oldMessage)
if message.id == oldMessageID:
logThis("They reacted to the hangman game")
gameMessage = True
return gameMessage
def stopServer(): def stopServer():
with open("resources/games/games.json","r") as f: with open("resources/games/games.json","r") as f:
games = json.load(f) games = json.load(f)

View File

@ -7,3 +7,6 @@ wikia==1.4.4
Pillow==7.1.1 Pillow==7.1.1
numpy==1.18.2 numpy==1.18.2
numexpr==2.7.1 numexpr==2.7.1
d20==1.0.4
finnhub-python==2.1.0
GitPython==3.1.0

Binary file not shown.

Binary file not shown.

View File

@ -132,3 +132,7 @@
1710 - Error in drawImage() 1710 - Error in drawImage()
1711 - Error in drawGallows() 1711 - Error in drawGallows()
1712 - Error in drawMan() 1712 - Error in drawMan()
1713 - Error in drawLetterLines()
1714 - Error in drawMisses()
1720 - Unspecified hangmanGuess() error
1730 - Unspecified hangmanStart() error

View File

@ -0,0 +1 @@
Brug `!hangman` til at starte et spil hangman. Brug derefter reaktionerne til at gætte bogstaver. Du har 6 gæt.

View File

@ -34,4 +34,6 @@
`!hex` - Lader dig spille et spil Hex. `!hex` - Lader dig spille et spil Hex.
`!hangman` - Lader dig spille et spil hangman.
Du kan få ekstra information om kommandoerne med "!help [kommando]". Du kan få ekstra information om kommandoerne med "!help [kommando]".

BIN
resources/paper.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB