diff --git a/funcs/games/hangman.py b/funcs/games/hangman.py index 8da9592..b00c727 100644 --- a/funcs/games/hangman.py +++ b/funcs/games/hangman.py @@ -281,29 +281,50 @@ class DrawHangman(): devianceX, devianceAccuracyX = self.calcDeviance(*devianceXParams) devianceY, devianceAccuracyY = self.calcDeviance(*devianceYParams) - x = middle + (math.cos(math.radians(degree+start)) * (self.CIRCLESIZE/2)) - (self.LINEWIDTH/2) + devianceX - y = middle + (math.sin(math.radians(degree+start)) * (self.CIRCLESIZE/2)) - (self.LINEWIDTH/2) + devianceY + radians = math.radians(degree+start) + circleX = (math.cos(radians) * (self.CIRCLESIZE/2)) + circleY = (math.sin(radians) * (self.CIRCLESIZE/2)) - d.ellipse([(x,y),(x+self.LINEWIDTH,y+self.LINEWIDTH)],fill=(0,0,0,255)) + x = middle + circleX - (self.LINEWIDTH/2) + devianceX + y = middle + circleY - (self.LINEWIDTH/2) + devianceY + + circlePosition = [(x, y), (x+self.LINEWIDTH, y+self.LINEWIDTH)] + d.ellipse(circlePosition, fill=(0, 0, 0, 255)) return background - def badLine(self, length, rotated = False): + def badLine(self, length: int, rotated: bool = False): if rotated: w, h = length+self.LINEWIDTH*3, self.LINEWIDTH*3 else: - w, h = self.LINEWIDTH*3,length+self.LINEWIDTH*3 - background = Image.new("RGBA",(w,h),color=(0,0,0,0)) + w, h = self.LINEWIDTH*3, length+self.LINEWIDTH*3 + background = Image.new("RGBA", (w, h), color=(0, 0, 0, 0)) - d = ImageDraw.Draw(background,"RGBA") - devianceX = random.randint(-int(self.LINEWIDTH/3),int(self.LINEWIDTH/3)) + d = ImageDraw.Draw(background, "RGBA") + + possibleDeviance = int(self.LINEWIDTH/3) + devianceX = random.randint(-possibleDeviance, possibleDeviance) devianceY = 0 devianceAccuracyX = 0 devianceAccuracyY = 0 for pixel in range(length): - devianceX, devianceAccuracyX = self.calcDeviance(devianceX,devianceAccuracyX,self.LINEWIDTH/1000,self.LINEWIDTH,0.004) - devianceY, devianceAccuracyY = self.calcDeviance(devianceY,devianceAccuracyY,self.LINEWIDTH/1000,self.LINEWIDTH,0.004) + devianceParamsX = [ + devianceX, + devianceAccuracyX, + self.LINEWIDTH/1000, + self.LINEWIDTH, + 0.004 + ] + devianceParamsY = [ + devianceY, + devianceAccuracyY, + self.LINEWIDTH/1000, + self.LINEWIDTH, + 0.004 + ] + devianceX, devianceAccuracyX = self.calcDeviance(*devianceParamsX) + devianceY, devianceAccuracyY = self.calcDeviance(*devianceParamsY) if rotated: x = self.LINEWIDTH + pixel + devianceX @@ -312,165 +333,179 @@ class DrawHangman(): x = self.LINEWIDTH + devianceX y = self.LINEWIDTH + pixel + devianceY - d.ellipse([(x,y),(x+self.LINEWIDTH,y+self.LINEWIDTH)],fill=(0,0,0,255)) + circlePosition = [(x, y), (x+self.LINEWIDTH, y+self.LINEWIDTH)] + d.ellipse(circlePosition, fill=(0, 0, 0, 255)) return background - def drawMan(self, misses): - background = Image.new("RGBA",(self.MANX,self.MANY),color=(0,0,0,0)) + def drawMan(self, misses: int): + manSize = (self.MANX, self.MANY) + background = Image.new("RGBA", manSize, color=(0, 0, 0, 0)) if misses >= 1: head = self.badCircle() - background.paste(head,(int((self.MANX-(self.CIRCLESIZE+(self.LINEWIDTH*3)))/2),0),head) + pasteX = (self.MANX-(self.CIRCLESIZE+(self.LINEWIDTH*3)))//2 + pastePosition = (pasteX, 0) + background.paste(head, pastePosition, head) if misses >= 2: body = self.badLine(self.BODYSIZE) - background.paste(body,(int((self.MANX-(self.LINEWIDTH*3))/2),self.CIRCLESIZE),body) + pasteX = (self.MANX-(self.LINEWIDTH*3))//2 + pastePosition = (pasteX, self.CIRCLESIZE) + background.paste(body, pastePosition, body) if misses >= 3: - limbs = random.sample(["rl","ll","ra","la"],min(misses-2,4)) - else: limbs = [] + limbs = random.sample(["rl", "ll", "ra", "la"], min(misses-2, 4)) + else: + limbs = [] for limb in limbs: - if limb == "ra": - limbDrawing = self.badLine(self.LIMBSIZE,True) - rotation = random.randint(-45,45) - xPosition = int((self.MANX-(self.LINEWIDTH*3))/2) - rotationCompensation = min(-int(math.sin(math.radians(rotation))*(self.LIMBSIZE+(self.LINEWIDTH*3))),0) - yPosition = self.CIRCLESIZE+self.ARMPOSITION + rotationCompensation - limbDrawing = limbDrawing.rotate(rotation,expand=1) - background.paste(limbDrawing,(xPosition,yPosition),limbDrawing) - elif limb == "la": - limbDrawing = self.badLine(self.LIMBSIZE,True) - rotation = random.randint(-45,45) - xPosition = int((self.MANX-(self.LINEWIDTH*3))/2)-self.LIMBSIZE - rotationCompensation = min(int(math.sin(math.radians(rotation))*(self.LIMBSIZE+(self.LINEWIDTH*3))),0) - yPosition = self.CIRCLESIZE+self.ARMPOSITION + rotationCompensation - limbDrawing = limbDrawing.rotate(rotation,expand=1) - background.paste(limbDrawing,(xPosition,yPosition),limbDrawing) - elif limb == "rl": - limbDrawing = self.badLine(self.LIMBSIZE,True) - rotation = random.randint(-15,15) - xPosition = int((self.MANX-(self.LINEWIDTH*3))/2)-self.LINEWIDTH - yPosition = self.CIRCLESIZE+self.BODYSIZE-self.LINEWIDTH - limbDrawing = limbDrawing.rotate(rotation-45,expand=1) - background.paste(limbDrawing,(xPosition,yPosition),limbDrawing) - elif limb == "ll": - limbDrawing = self.badLine(self.LIMBSIZE,True) - rotation = random.randint(-15,15) - limbDrawing = limbDrawing.rotate(rotation+45,expand=1) - xPosition = int((self.MANX-(self.LINEWIDTH*3))/2)-limbDrawing.size[0]+self.LINEWIDTH*3 + limbDrawing = self.badLine(self.LIMBSIZE, True) + xPosition = (self.MANX-(self.LINEWIDTH*3))//2 + + if limb[1] == "a": + rotation = random.randint(-45, 45) + shift = math.sin(math.radians(rotation)) + compensation = int(shift*(self.LIMBSIZE+(self.LINEWIDTH*3))) + limbDrawing = limbDrawing.rotate(rotation, expand=1) + yPosition = self.CIRCLESIZE + self.ARMPOSITION + compensation + if limb == "ra": + compensation = min(-compensation, 0) + else: + xPosition -= self.LIMBSIZE + compensation = min(compensation, 0) + else: + rotation = random.randint(-15, 15) yPosition = self.CIRCLESIZE+self.BODYSIZE - background.paste(limbDrawing,(xPosition,yPosition),limbDrawing) + if limb == "rl": + xPosition -= self.LINEWIDTH + limbDrawing = limbDrawing.rotate(rotation-45, expand=1) + else: + yPosition -= self.LINEWIDTH + xPosition += -limbDrawing.size[0]+self.LINEWIDTH*3 + limbDrawing = limbDrawing.rotate(rotation+45, expand=1) + + pastePosition = (xPosition, yPosition) + background.paste(limbDrawing, pastePosition, limbDrawing) return background - def badText(self, text, big, color=(0,0,0,255)): - if big: font = self.FONT - else: font = self.SMALLFONT + def badText(self, text: str, big: bool, color: tuple = (0, 0, 0, 255)): + if big: + font = self.FONT + else: + font = self.SMALLFONT w, h = font.getsize(text) - img = Image.new("RGBA",(w,h),color=(0,0,0,0)) - d = ImageDraw.Draw(img,"RGBA") + img = Image.new("RGBA", (w, h), color=(0, 0, 0, 0)) + d = ImageDraw.Draw(img, "RGBA") - d.text((0,0),text,font=font,fill=color) + d.text((0, 0), text, font=font, fill=color) return img def drawGallows(self): - background = Image.new("RGBA",(self.GALLOWX,self.GALLOWY),color=(0,0,0,0)) + gallowSize = (self.GALLOWX, self.GALLOWY) + background = Image.new("RGBA", gallowSize, color=(0, 0, 0, 0)) - bottomLine = self.badLine(int(self.GALLOWX*0.75),True) - background.paste(bottomLine,(int(self.GALLOWX*0.125),self.GALLOWY-(self.LINEWIDTH*4)),bottomLine) + bottomLine = self.badLine(int(self.GALLOWX * 0.75), True) + bottomLineX = int(self.GALLOWX * 0.125) + bottomLineY = self.GALLOWY-(self.LINEWIDTH*4) + pastePosition = (bottomLineX, bottomLineY) + background.paste(bottomLine, pastePosition, bottomLine) lineTwo = self.badLine(self.GALLOWY-self.LINEWIDTH*6) - background.paste(lineTwo,(int(self.GALLOWX*(0.75*self.GOLDENRATIO)),self.LINEWIDTH*2),lineTwo) + lineTwoX = int(self.GALLOWX*(0.75*self.GOLDENRATIO)) + lineTwoY = self.LINEWIDTH*2 + pastePosition = (lineTwoX, lineTwoY) + background.paste(lineTwo, pastePosition, lineTwo) - topLine = self.badLine(int(self.GALLOWY*0.30),True) - background.paste(topLine,(int(self.GALLOWX*(0.75*self.GOLDENRATIO))-self.LINEWIDTH,self.LINEWIDTH*3),topLine) + topLine = self.badLine(int(self.GALLOWY*0.30), True) + pasteX = int(self.GALLOWX*(0.75*self.GOLDENRATIO))-self.LINEWIDTH + pastePosition = (pasteX, self.LINEWIDTH*3) + background.paste(topLine, pastePosition, topLine) lastLine = self.badLine(int(self.GALLOWY*0.125)) - background.paste(lastLine,((int(self.GALLOWX*(0.75*self.GOLDENRATIO))+int(self.GALLOWY*0.30)-self.LINEWIDTH),self.LINEWIDTH*3),lastLine) + pasteX += int(self.GALLOWY*0.30) + background.paste(lastLine, (pasteX, self.LINEWIDTH*3), lastLine) return background - def drawLetterLines(self, word,guessed,misses): - letterLines = Image.new("RGBA",((self.LETTERLINELENGTH+self.LETTERLINEDISTANCE)*len(word),self.LETTERLINELENGTH+self.LINEWIDTH*3),color=(0,0,0,0)) + def drawLetterLines(self, word: str, guessed: list, misses: int): + imageWidth = (self.LETTERLINELENGTH+self.LETTERLINEDISTANCE)*len(word) + imageSize = (imageWidth, self.LETTERLINELENGTH+self.LINEWIDTH*3) + letterLines = Image.new("RGBA", imageSize, color=(0, 0, 0, 0)) for x, letter in enumerate(word): - line = self.badLine(self.LETTERLINELENGTH,True) - letterLines.paste(line,(x*(self.LETTERLINELENGTH+self.LETTERLINEDISTANCE),self.LETTERLINELENGTH),line) + line = self.badLine(self.LETTERLINELENGTH, True) + pasteX = x*(self.LETTERLINELENGTH+self.LETTERLINEDISTANCE) + pastePosition = (pasteX, self.LETTERLINELENGTH) + letterLines.paste(line, pastePosition, line) if guessed[x]: - letterDrawing = self.badText(letter,True) + letterDrawing = self.badText(letter, True) letterWidth = self.FONT.getsize(letter)[0] - letterX = int(x*(self.LETTERLINELENGTH+self.LETTERLINEDISTANCE)-(letterWidth/2)+(self.LETTERLINELENGTH*0.5)+(self.LINEWIDTH*2)) - letterLines.paste(letterDrawing,(letterX,0),letterDrawing) + letterX = x*(self.LETTERLINELENGTH+self.LETTERLINEDISTANCE) + letterX -= (letterWidth//2) + letterX += (self.LETTERLINELENGTH//2)+(self.LINEWIDTH*2) + letterLines.paste(letterDrawing, (letterX, 0), letterDrawing) elif misses == 6: - letterDrawing = self.badText(letter,True,(242,66,54)) + letterDrawing = self.badText(letter, True, (242, 66, 54)) letterWidth = self.FONT.getsize(letter)[0] - letterX = int(x*(self.LETTERLINELENGTH+self.LETTERLINEDISTANCE)-(letterWidth/2)+(self.LETTERLINELENGTH*0.5)+(self.LINEWIDTH*2)) - letterLines.paste(letterDrawing,(letterX,0),letterDrawing) + letterX = x*(self.LETTERLINELENGTH+self.LETTERLINEDISTANCE) + letterX -= (letterWidth//2) + letterX += (self.LETTERLINELENGTH//2)+(self.LINEWIDTH*2) + letterLines.paste(letterDrawing, (letterX, 0), letterDrawing) return letterLines - def shortestDist(self,positions,newPosition): + def shortestDist(self, positions: list, newPosition: tuple): shortestDist = math.inf x, y = newPosition for i, j in positions: xDistance = abs(i-x) yDistance = abs(j-y) dist = math.sqrt(xDistance**2+yDistance**2) - if shortestDist > dist: shortestDist = dist + if shortestDist > dist: + shortestDist = dist return shortestDist - def drawMisses(self,guesses,word): - background = Image.new("RGBA",(600,400),color=(0,0,0,0)) + def drawMisses(self, guesses: list, word: str): + 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 = self.badText(guess,True) + while not placed: + letter = self.badText(guess, True) w, h = self.FONT.getsize(guess) - x = random.randint(0,600-w) - y = random.randint(0,400-h) - if self.shortestDist(pos,(x,y)) > 70: - pos.append((x,y)) - background.paste(letter,(x,y),letter) + x = random.randint(0, 600-w) + y = random.randint(0, 400-h) + if self.shortestDist(pos, (x, y)) > 70: + pos.append((x, y)) + background.paste(letter, (x, y), letter) placed = True return background - def drawImage(self,channel): + def drawImage(self, channel: str): self.bot.log("Drawing hangman image", channel) - game = self.bot.database["hangman games"].find_one({"_id":channel}) + game = self.bot.database["hangman games"].find_one({"_id": channel}) random.seed(game["game ID"]) background = Image.open("resources/paper.jpg") - try: - gallow = self.drawGallows() - except: - self.bot.log("Error drawing gallows (error code 1711)") - - try: - man = self.drawMan(game["misses"]) - except: - self.bot.log("Error drawing stick figure (error code 1712)") + gallow = self.drawGallows() + man = self.drawMan(game["misses"]) random.seed(game["game ID"]) - try: - letterLines = self.drawLetterLines(game["word"],game["guessed"],game["misses"]) - except: - self.bot.log("error drawing letter lines (error code 1713)") + letterLineParams = [game["word"], game["guessed"], game["misses"]] + letterLines = self.drawLetterLines(*letterLineParams) random.seed(game["game ID"]) - try: - misses = self.drawMisses(game["guessed letters"],game["word"]) - except: - self.bot.log("Error drawing misses (error code 1714)") + misses = self.drawMisses(game["guessed letters"], game["word"]) - background.paste(gallow,(100,100),gallow) - background.paste(man,(300,210),man) - background.paste(letterLines,(120,840),letterLines) - background.paste(misses,(600,150),misses) + background.paste(gallow, (100, 100), gallow) + background.paste(man, (300, 210), man) + background.paste(letterLines, (120, 840), letterLines) + background.paste(misses, (600, 150), misses) - missesText = self.badText("MISSES",False) + missesText = self.badText("MISSES", False) missesTextWidth = missesText.size[0] - background.paste(missesText,(850-int(missesTextWidth/2),50),missesText) + background.paste(missesText, (850-missesTextWidth//2, 50), missesText) - background.save("resources/games/hangmanBoards/hangmanBoard"+channel+".png") + boardPath = f"resources/games/hangmanBoards/hangmanBoard{channel}.png" + background.save(boardPath)