From ed7efe7aa4c1ce5fc4996af00257499bd916c84e Mon Sep 17 00:00:00 2001 From: NikolajDanger Date: Thu, 30 Jul 2020 16:32:18 +0200 Subject: [PATCH] :sparkles: Four in a row win --- Gwendolyn.py | 13 ++++- funcs/games/draw4InARow.py | 52 ++++++++++++++++++- funcs/games/fourInARow.py | 103 +++++++++++++++++++++++++++++++++---- 3 files changed, 154 insertions(+), 14 deletions(-) diff --git a/Gwendolyn.py b/Gwendolyn.py index 85e0dca..cd40bbb 100644 --- a/Gwendolyn.py +++ b/Gwendolyn.py @@ -576,7 +576,7 @@ async def parseCommands(message,content): # Runs a game of four in a row elif content.startswith("fourinarow"): - response, showImage, deleteImage = parseFourInARow(content.replace("fourinarow",""),str(message.channel),message.author.display_name) + response, showImage, deleteImage, gameDone = parseFourInARow(content.replace("fourinarow",""),str(message.channel),message.author.display_name) await message.channel.send(response) logThis(response,str(message.channel)) if showImage: @@ -590,6 +590,17 @@ async def parseCommands(message,content): oldImage = await message.channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(message.channel)+".png")) with open("resources/games/oldImages/fourInARow"+str(message.channel), "w") as f: f.write(str(oldImage.id)) + + if gameDone: + with open("resources/games/games.json", "r") as f: + data = json.load(f) + + del data["4 in a row games"][str(message.channel)] + + with open("resources/games/games.json","w") as f: + json.dump(data,f,indent=4) + + # Not a command else: diff --git a/funcs/games/draw4InARow.py b/funcs/games/draw4InARow.py index 69a3540..476d7e7 100644 --- a/funcs/games/draw4InARow.py +++ b/funcs/games/draw4InARow.py @@ -27,8 +27,8 @@ def drawImage(channel): pieceStarty = (border+gridBorder)+math.floor(placeGridSize[1]/2)-math.floor(placeSize/2) - background = Image.new("RGBA", (w,h),backgroundColor) - d = ImageDraw.Draw(background) + background = Image.new("RGB", (w,h),backgroundColor) + d = ImageDraw.Draw(background,"RGBA") # This whole part was the easiest way to make a rectangle with rounded corners and an outline # - Corners: @@ -62,4 +62,52 @@ def drawImage(channel): d.ellipse([(startx,starty),(startx+placeSize,starty+placeSize)],fill=pieceColor,outline=(0,0,0),width=outlineSize) + if data["4 in a row games"][channel]["winner"] != 0: + coordinates = data["4 in a row games"][channel]["win coordinates"] + startx = border + placeGridSize[0]*coordinates[1] + gridBorder + starty = border + placeGridSize[1]*coordinates[0] + gridBorder + a = (placeGridSize[0]*4-gridBorder-border)**2 + b = (placeGridSize[1]*4-gridBorder-border)**2 + diagonalLength = (math.sqrt(a+b))/placeGridSize[0] + diagonalAngle = math.degrees(math.atan(placeGridSize[1]/placeGridSize[0])) + + if data["4 in a row games"][channel]["win direction"] == "h": + winBar = Image.new("RGBA",(placeGridSize[0]*4,placeGridSize[1]),(0,0,0,0)) + winD = ImageDraw.Draw(winBar) + winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=(128,128,180,255)) + winD.ellipse([((placeGridSize[0]*3),0),(placeGridSize[0]*4,placeGridSize[1])],fill=(128,128,180,255)) + winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*3.5),placeGridSize[1])],fill=(128,128,180,255)) + + elif data["4 in a row games"][channel]["win direction"] == "v": + winBar = Image.new("RGBA",(placeGridSize[0],placeGridSize[1]*4),(0,0,0,0)) + winD = ImageDraw.Draw(winBar) + winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=(128,128,180,255)) + winD.ellipse([(0,(placeGridSize[1]*3)),(placeGridSize[0],placeGridSize[1]*4)],fill=(128,128,180,255)) + winD.rectangle([0,(int(placeGridSize[1]*0.5)),(placeGridSize[0],int(placeGridSize[1]*3.5))],fill=(128,128,180,255)) + + elif data["4 in a row games"][channel]["win direction"] == "r": + winBar = Image.new("RGBA",(int(placeGridSize[0]*diagonalLength),placeGridSize[1]),(0,0,0,0)) + winD = ImageDraw.Draw(winBar) + winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=(128,128,180,255)) + winD.ellipse([((placeGridSize[0]*(diagonalLength-1)),0),(placeGridSize[0]*diagonalLength,placeGridSize[1])],fill=(128,128,180,255)) + winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*(diagonalLength-0.5)),placeGridSize[1])],fill=(128,128,180,255)) + winBar = winBar.rotate(-diagonalAngle,expand=1) + startx -= border + starty -= gridBorder + border + + elif data["4 in a row games"][channel]["win direction"] == "l": + winBar = Image.new("RGBA",(int(placeGridSize[0]*diagonalLength),placeGridSize[1]),(0,0,0,0)) + winD = ImageDraw.Draw(winBar) + winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=(128,128,180,255)) + winD.ellipse([((placeGridSize[0]*(diagonalLength-1)),0),(placeGridSize[0]*diagonalLength,placeGridSize[1])],fill=(128,128,180,255)) + winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*(diagonalLength-0.5)),placeGridSize[1])],fill=(128,128,180,255)) + winBar = winBar.rotate(diagonalAngle,expand=1) + startx -= placeGridSize[0]*3 + border + starty -= gridBorder + border + + + mask = winBar.copy().convert("1") + winBar.putalpha(mask) + background.paste(winBar,(startx,starty),winBar) + background.save("resources/games/4InARowBoards/board"+channel+".png") diff --git a/funcs/games/fourInARow.py b/funcs/games/fourInARow.py index 78e3d36..2442412 100644 --- a/funcs/games/fourInARow.py +++ b/funcs/games/fourInARow.py @@ -1,6 +1,7 @@ import json from . import draw4InARow +from funcs import logThis # Starts the game def fourInARowStart(channel): @@ -11,16 +12,17 @@ def fourInARowStart(channel): board = [ [ 0 for i in range(7) ] for j in range(6) ] - data["4 in a row games"][channel] = {"board": board} + data["4 in a row games"][channel] = {"board": board,"winner":0,"win direction":"", + "win coordinates":[0,0],"players":["",""]} with open("resources/games/games.json", "w") as f: json.dump(data,f,indent=4) draw4InARow.drawImage(channel) - return "Started game", True, False + return "Started game", True, False, False else: - return "There's already a 4 in a row game going on in this channel", False, False + return "There's already a 4 in a row game going on in this channel", False, False, False # Places a piece at the lowest available point in a specific column def placePiece(channel : str,player : int,column : int): @@ -41,15 +43,31 @@ def placePiece(channel : str,player : int,column : int): board[placementx][placementy] = player data["4 in a row games"][channel]["board"] = board + with open("resources/games/games.json", "w") as f: + json.dump(data,f,indent=4) + + won, winDirection, winCoordinates = isWon(channel) + + if won != 0: + gameWon = True + data["4 in a row games"][channel]["winner"] = won + data["4 in a row games"][channel]["win direction"] = winDirection + data["4 in a row games"][channel]["win coordinates"] = winCoordinates + + message = data["4 in a row games"][channel]["players"][won-1]+" won" + else: + gameWon = False + message = "Placed a piece" + with open("resources/games/games.json", "w") as f: json.dump(data,f,indent=4) draw4InARow.drawImage(channel) - return "Placed the piece", True, True + return message, True, True, gameWon else: - return "There isn't any room in that column", True, True + return "There isn't any room in that column", True, True, False else: - return "There's no game in this channel", False, False + return "There's no game in this channel", False, False, False # Parses command @@ -58,9 +76,72 @@ def parseFourInARow(command, channel, user): return fourInARowStart(channel) elif command.startswith(" place"): commands = command.split(" ") - try: - return placePiece(channel,int(commands[2]),int(commands[3])-1) - except: - return "I didn't quite get that", False, False + #try: + return placePiece(channel,int(commands[2]),int(commands[3])-1) + #except: + # return "I didn't quite get that", False, False, False else: - return "I didn't get that", False, False \ No newline at end of file + return "I didn't get that", False, False, False + +def isWon(channel): + logThis("Checking for win",channel) + won = 0 + winDirection = "" + winCoordinates = [0,0] + + with open("resources/games/games.json", "r") as f: + data = json.load(f) + + game = data["4 in a row games"][channel]["board"] + + for line in range(len(game)): + for place in range(len(game[line])): + if won == 0: + piecePlayer = game[line][place] + if piecePlayer != 0: + # Checks horizontal + try: + pieces = [game[line][place+1],game[line][place+2],game[line][place+3]] + except: + pieces = [0] + + if all(x == piecePlayer for x in pieces): + won = piecePlayer + winDirection = "h" + winCoordinates = [line,place] + + # Checks vertical + try: + pieces = [game[line+1][place],game[line+2][place],game[line+3][place]] + except: + pieces = [0] + + if all(x == piecePlayer for x in pieces): + won = piecePlayer + winDirection = "v" + winCoordinates = [line,place] + + # Checks right diagonal + try: + pieces = [game[line+1][place+1],game[line+2][place+2],game[line+3][place+3]] + except: + pieces = [0] + + if all(x == piecePlayer for x in pieces): + won = piecePlayer + winDirection = "r" + winCoordinates = [line,place] + + # Checks left diagonal + try: + pieces = [game[line+1][place-1],game[line+2][place-2],game[line+3][place-3]] + except: + pieces = [0] + + if all(x == piecePlayer for x in pieces): + won = piecePlayer + winDirection = "l" + winCoordinates = [line,place] + + + return won, winDirection, winCoordinates