:Sparkles: Converted all hex functionality to slash commands

This commit is contained in:
NikolajDanger
2021-04-05 23:06:30 +02:00
parent aea2875957
commit d3936fa1a9
6 changed files with 321 additions and 307 deletions

View File

@@ -115,37 +115,36 @@ class HexCog(commands.Cog):
def __init__(self,bot): def __init__(self,bot):
"""Runs game stuff.""" """Runs game stuff."""
self.bot = bot self.bot = bot
# Start a game of Hex against another user # Start a game of Hex against another user
@cog_ext.cog_subcommand(**params["hexStartUser"]) @cog_ext.cog_subcommand(**params["hexStartUser"])
async def hexStartUser(self, ctx, user): async def hexStartUser(self, ctx, user):
await ctx.defer() await self.bot.games.hex.start(ctx, user)
await self.bot.games.gameLoops.runHex(ctx, "start "+user.display_name, "#"+str(ctx.author.id))
# Start a game of Hex against Gwendolyn # Start a game of Hex against Gwendolyn
@cog_ext.cog_subcommand(**params["hexStartGwendolyn"]) @cog_ext.cog_subcommand(**params["hexStartGwendolyn"])
async def hexStartGwendolyn(self, ctx, difficulty = 2): async def hexStartGwendolyn(self, ctx, difficulty = 2):
await ctx.defer() await self.bot.games.hex.start(ctx, difficulty)
await self.bot.games.gameLoops.runHex(ctx, "start "+str(difficulty), "#"+str(ctx.author.id))
# Undo your last hex move
@cog_ext.cog_subcommand(**params["hexUndo"])
async def hexUndo(self, ctx):
await self.bot.games.gameLoops.runHex(ctx, "undo", "#"+str(ctx.author.id))
# Perform a hex swap
@cog_ext.cog_subcommand(**params["hexSwap"])
async def hexSwap(self, ctx):
await self.bot.games.gameLoops.runHex(ctx, "swap", "#"+str(ctx.author.id))
# Surrender the hex game
@cog_ext.cog_subcommand(**params["hexSurrender"])
async def hexSurrender(self, ctx):
await self.bot.games.gameLoops.runHex(ctx, "surrender", "#"+str(ctx.author.id))
# Place a piece in the hex game # Place a piece in the hex game
@cog_ext.cog_subcommand(**params["hexPlace"]) @cog_ext.cog_subcommand(**params["hexPlace"])
async def hexPlace(self, ctx, coordinates): async def hexPlace(self, ctx, coordinates):
await self.bot.games.gameLoops.runHex(ctx, "place "+coordinates, "#"+str(ctx.author.id)) await self.bot.games.hex.placeHex(ctx, coordinates, f"#{ctx.author.id}")
# Undo your last hex move
@cog_ext.cog_subcommand(**params["hexUndo"])
async def hexUndo(self, ctx):
await self.bot.games.hex.undo(ctx)
# Perform a hex swap
@cog_ext.cog_subcommand(**params["hexSwap"])
async def hexSwap(self, ctx):
await self.bot.games.hex.swap(ctx)
# Surrender the hex game
@cog_ext.cog_subcommand(**params["hexSurrender"])
async def hexSurrender(self, ctx):
await self.bot.games.hex.surrender(ctx)
def setup(bot): def setup(bot):

View File

@@ -1,66 +0,0 @@
import asyncio
import discord
class GameLoops():
def __init__(self,bot):
self.bot = bot
# Deletes a message
async def deleteMessage(self, imageLocation,channel):
try:
with open("resources/games/oldImages/"+imageLocation, "r") as f:
messages = f.read().splitlines()
for message in messages:
oldMessage = await channel.fetch_message(int(message))
self.bot.log("Deleting old message")
await oldMessage.delete()
except:
oldMessage = ""
return oldMessage
# Runs Hex
async def runHex(self,ctx,command,user):
channelId = ctx.channel_id
try:
response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.games.hex.parseHex(command,str(channelId),user)
except:
self.bot.log("Error parsing command (error code 1510)")
await ctx.send(response)
self.bot.log(response,str(channelId))
if showImage:
if deleteImage:
try:
oldImage = await self.deleteMessage("hex"+str(channelId),ctx.channel)
except:
self.bot.log("Error deleting old image (error code 1501)")
oldImage = await ctx.channel.send(file = discord.File("resources/games/hexBoards/board"+str(channelId)+".png"))
if gwendoTurn and not gameDone:
try:
response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.games.hex.hexAI(str(channelId))
except:
response, showImage, deleteImage, gameDone, gwendoTurn = "An AI error ocurred",False,False,False,False
self.bot.log("AI error (error code 1520)")
await ctx.channel.send(response)
self.bot.log(response,str(channelId))
if showImage:
if deleteImage:
await oldImage.delete()
oldImage = await ctx.channel.send(file = discord.File("resources/games/hexBoards/board"+str(channelId)+".png"))
if not gameDone:
with open("resources/games/oldImages/hex"+str(channelId), "w") as f:
f.write(str(oldImage.id))
if gameDone:
game = self.bot.database["hex games"].find_one({"_id":str(channelId)})
winner = game["winner"]
if winner != 0 and game["players"][0] != game["players"][1]: # player1 != player2
winnings = game["difficulty"]*10
self.bot.money.addMoney(game["players"][winner-1].lower(),winnings)
self.bot.databaseFuncs.deleteGame("hex games",str(channelId))

View File

@@ -2,7 +2,6 @@ from .invest import Invest
from .trivia import Trivia from .trivia import Trivia
from .blackjack import Blackjack from .blackjack import Blackjack
from .connectFour import ConnectFour from .connectFour import ConnectFour
from .gameLoops import GameLoops
from .hangman import Hangman from .hangman import Hangman
from .hex import HexGame from .hex import HexGame
@@ -14,6 +13,5 @@ class Games():
self.trivia = Trivia(bot) self.trivia = Trivia(bot)
self.blackjack = Blackjack(bot) self.blackjack = Blackjack(bot)
self.connectFour = ConnectFour(bot) self.connectFour = ConnectFour(bot)
self.gameLoops = GameLoops(bot)
self.hangman = Hangman(bot) self.hangman = Hangman(bot)
self.hex = HexGame(bot) self.hex = HexGame(bot)

View File

@@ -1,6 +1,7 @@
import random import random
import copy import copy
import math import math
import discord
from .hexDraw import DrawHex from .hexDraw import DrawHex
@@ -17,95 +18,139 @@ class HexGame():
self.bot = bot self.bot = bot
self.draw = DrawHex(bot) self.draw = DrawHex(bot)
# Parses command async def surrender(self, ctx):
def parseHex(self, command, channel, user): channel = str(ctx.channel_id)
commands = command.lower().split()
game = self.bot.database["hex games"].find_one({"_id":channel}) game = self.bot.database["hex games"].find_one({"_id":channel})
if command == "" or command == " ": user = f"#{ctx.author.id}"
return "I didn't get that. Use \"/hex start [opponent]\" to start a game.", False, False, False, False
elif commands[0] == "start":
# Starting a game
if len(commands) == 1: # if the commands is "/hex start", the opponent is Gwendolyn at difficulty 2
commands.append("2")
self.bot.log("Starting a hex game with hexStart(). "+str(user)+" challenged "+commands[1])
return self.hexStart(channel,user,commands[1]) # commands[1] is the opponent
# If using a command with no game, return error
elif game == None:
return "There's no game in this channel", False, False, False, False
# Stopping the game
elif commands[0] == "stop":
if user in game["players"]:
return "Ending game.", False, False, True, False
else:
return "You can't end a game where you're not a player.", False, False, False, False
# Placing a piece
elif commands[0] == "place":
try:
return self.placeHex(channel,commands[1], user)
except:
return "I didn't get that. To place a piece use \"/hex place [position]\". A valid position is e.g. \"E2\".", False, False, False, False
# Undo
elif commands[0] == "undo":
return self.undoHex(channel, user)
# Surrender
elif commands[0] == "surrender":
players = game["players"] players = game["players"]
if user in players:
opponent = (players.index(user) + 1) % 2 if user not in players:
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":opponent + 1}}) await ctx.send("You can't surrender when you're not a player.")
return "{} surrendered. That means {} won! Adding 30 Gwendobucks to their account.".format(self.bot.databaseFuncs.getName(user),self.bot.databaseFuncs.getName(players[opponent])), False, False, True, False
else: else:
return "You can't surrender when you're not a player.", False, False, False, False opponent = (players.index(user) + 1) % 2
opponentName = self.bot.databaseFuncs.getName(players[opponent])
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":opponent + 1}})
await ctx.send(f"{ctx.author.display_name} surrendered. That means {opponentName} won! Adding 30 Gwendobucks to their account")
with open(f"resources/games/oldImages/hex{channel}", "r") as f:
oldImage = await ctx.channel.fetch_message(int(f.read()))
if oldImage is not None:
await oldImage.delete()
else:
self.bot.log("The old image was already deleted")
self.bot.log("Sending the image")
filePath = f"resources/games/hexBoards/board{channel}.png"
oldImage = await ctx.channel.send(file = discord.File(filePath))
with open(f"resources/games/oldImages/hex{channel}", "w") as f:
f.write(str(oldImage.id))
# Swap # Swap
elif commands[0] == "swap": async def swap(self, ctx):
if len(game["gameHistory"]) == 1: # Only after the first move channel = str(ctx.channel_id)
game = self.bot.database["hex games"].find_one({"_id":channel})
user = f"#{ctx.author.id}"
if game is None:
await ctx.send("You can't swap nothing")
elif user not in game["players"]:
await ctx.send("You're not in the game")
elif len(game["gameHistory"]) != 1: # Only after the first move
await ctx.send("You can only swap as the second player after the very first move.")
elif user != game["players"][game["turn"]-1]:
await ctx.send("You can only swap after your opponent has placed their piece")
else:
self.bot.database["hex games"].update_one({"_id":channel}, self.bot.database["hex games"].update_one({"_id":channel},
{"$set":{"players":game["players"][::-1]}}) # Swaps their player-number {"$set":{"players":game["players"][::-1]}}) # Swaps their player-number
# Swaps the color of the hexes on the board drawing: # Swaps the color of the hexes on the board drawing:
self.draw.drawSwap(channel) self.draw.drawSwap(channel)
player2 = game["players"][1]
gwendoTurn = (player2 == "Gwendolyn")
return "The color of both players were swapped. It is now {}'s turn".format(player2), True, True, False, gwendoTurn
else:
return "You can only swap as the second player after the very first move.", False, False, False, False
opponent = game["players"][::-1][game["turn"]-1]
gwendoTurn = (opponent == f"#{self.bot.user.id}")
opponentName = self.bot.databaseFuncs.getName(opponent)
await ctx.send(f"The color of the players were swapped. It is now {opponentName}'s turn")
with open(f"resources/games/oldImages/hex{channel}", "r") as f:
oldImage = await ctx.channel.fetch_message(int(f.read()))
if oldImage is not None:
await oldImage.delete()
else: else:
return "I didn't get that. Use \"/hex start [opponent]\" to start a game, \"/hex place [position]\" to place a piece, \"/hex undo\" to undo your last move or \"/hex stop\" to stop a current game.", False, False, False, False self.bot.log("The old image was already deleted")
self.bot.log("Sending the image")
filePath = f"resources/games/hexBoards/board{channel}.png"
oldImage = await ctx.channel.send(file = discord.File(filePath))
with open(f"resources/games/oldImages/hex{channel}", "w") as f:
f.write(str(oldImage.id))
if gwendoTurn:
await self.hexAI(ctx)
# Starts the game # Starts the game
def hexStart(self, channel, user, opponent): async def start(self, ctx, opponent):
try:
await ctx.defer()
except:
self.bot.log("Defer failed")
user = f"#{ctx.author.id}"
channel = str(ctx.channel_id)
game = self.bot.database["hex games"].find_one({"_id":channel}) game = self.bot.database["hex games"].find_one({"_id":channel})
if game == None: startedGame = False
if opponent in ["1","2","3","4","5"]: canStart = True
difficulty = int(opponent)
diffText = " with difficulty "+opponent if game != None:
opponent = "Gwendolyn" sendMessage = "There's already a hex game going on in this channel"
elif opponent.lower() == "gwendolyn": logMessage = "There was already a game going on"
difficulty = 2 canStart = False
diffText = " with difficulty 2"
opponent = "Gwendolyn"
else: else:
try: if type(opponent) == int:
int(opponent) # Opponent is Gwendolyn
return "That difficulty doesn't exist", False, False, False, False if opponent in range(1, 6):
except: opponentName = "Gwendolyn"
opponent = self.bot.databaseFuncs.getID(opponent) difficulty = int(opponent)
if opponent == None: diffText = f" with difficulty {difficulty}"
return "I can't find that user", False, False, False, False opponent = f"#{self.bot.user.id}"
else:
sendMessage = "Difficulty doesn't exist"
logMessage = "They tried to play against a difficulty that doesn't exist"
canStart = False
elif type(opponent) == discord.member.Member:
if opponent.bot:
# User has challenged a bot
if opponent == self.bot.user:
# It was Gwendolyn
opponentName = "Gwendolyn"
difficulty = 2
diffText = f" with difficulty {difficulty}"
opponent = f"#{self.bot.user.id}"
else:
sendMessage = "You can't challenge a bot!"
logMessage = "They tried to challenge a bot"
canStart = False
else: else:
# Opponent is another player # Opponent is another player
difficulty = 3 if ctx.author != opponent:
opponentName = opponent.display_name
opponent = f"#{opponent.id}"
difficulty = 5
diffText = "" diffText = ""
else:
sendMessage = "You can't play against yourself"
logMessage = "They tried to play against themself"
canStart = False
else:
canStart = False
logMessage = f"Opponent was neither int or member. It was {type(opponent)}"
sendMessage = "Something went wrong"
if canStart:
# board is 11x11 # board is 11x11
board = [[0 for i in range(BOARDWIDTH)] for j in range(BOARDWIDTH)] board = [[0 for i in range(BOARDWIDTH)] for j in range(BOARDWIDTH)]
players = [user, opponent] players = [user, opponent]
@@ -120,36 +165,62 @@ class HexGame():
# draw the board # draw the board
self.draw.drawBoard(channel) self.draw.drawBoard(channel)
gwendoTurn = True if players[0] == "Gwendolyn" else False gwendoTurn = (players[0] == f"#{self.bot.user.id}")
showImage = True startedGame = True
return "Started Hex game against "+self.bot.databaseFuncs.getName(opponent)+ diffText+". It's "+self.bot.databaseFuncs.getName(players[0])+"'s turn", showImage, False, False, gwendoTurn
else: turnName = self.bot.databaseFuncs.getName(players[0])
return "There's already a hex game going on in this channel", False, False, False, False sendMessage = f"Started Hex game against {opponentName}{diffText}. It's {turnName}'s turn"
logMessage = "Game started"
await ctx.send(sendMessage)
self.bot.log(logMessage)
if startedGame:
filePath = f"resources/games/hexBoards/board{ctx.channel_id}.png"
newImage = await ctx.channel.send(file = discord.File(filePath))
with open(f"resources/games/oldImages/hex{ctx.channel_id}", "w") as f:
f.write(str(newImage.id))
if gwendoTurn:
await self.hexAI(ctx)
# Places a piece at the given location and checks things afterwards # Places a piece at the given location and checks things afterwards
def placeHex(self, channel : str,position : str, user): async def placeHex(self, ctx, position : str, user):
channel = str(ctx.channel_id)
game = self.bot.database["hex games"].find_one({"_id":channel}) game = self.bot.database["hex games"].find_one({"_id":channel})
placedPiece = False
if game != None: if game == None:
players = game["players"] sendMessage = "There's no game in this channel"
if user in players: self.bot.log("There was no game going on")
turn = game["turn"] elif not (position[0].isalpha() and position[1].isnumeric() and len(position) == 2):
if players[0] == players[1]: sendMessage = "The position must be a letter followed by a number."
player = turn self.bot.log(f"The position was not valid, {position}")
else: else:
player = players.index(user)+1 players = game["players"]
if user not in players:
if player == turn: sendMessage = f"You can't place when you're not in the game. The game's players are: {self.bot.databaseFuncs.getName(game['players'][0])} and {self.bot.databaseFuncs.getName(game['players'][1])}."
self.bot.log("They aren't in the game")
elif players[game["turn"]-1] != user:
sendMessage = "It's not your turn"
self.bot.log("It wasn't their turn")
else:
player = game["turn"]
turn = game["turn"]
board = game["board"] board = game["board"]
self.bot.log("Placing a piece on the board with placeHex()") self.bot.log("Placing a piece on the board with placeHex()")
# Places on board # Places on board
board = self.placeOnHexBoard(board,player,position) board = self.placeOnHexBoard(board,player,position)
if isinstance(board, list): if board is None:
self.bot.log("It was an invalid position")
sendMessage = ("That's an invalid position. You must place your piece on an empty field.")
else:
# If the move is valid: # If the move is valid:
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"board":board}}) self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"board":board}})
turn = 1 if turn == 2 else 2 turn = (turn % 2) + 1
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"turn":turn}}) self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"turn":turn}})
# Checking for a win # Checking for a win
@@ -158,74 +229,97 @@ class HexGame():
if winner == 0: # Continue with the game. if winner == 0: # Continue with the game.
gameWon = False gameWon = False
message = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed at "+position.upper()+". It's now "+self.bot.databaseFuncs.getName(game["players"][turn-1])+"'s turn."# The score is "+str(score) sendMessage = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed at "+position.upper()+". It's now "+self.bot.databaseFuncs.getName(game["players"][turn-1])+"'s turn."# The score is "+str(score)
else: # Congratulations! else: # Congratulations!
gameWon = True gameWon = True
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":winner}}) self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":winner}})
message = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed at "+position.upper()+" and won!" sendMessage = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed at "+position.upper()+" and won!"
if game["players"][winner-1] != "Gwendolyn": if game["players"][winner-1] != f"#{self.bot.user.id}":
winAmount = game["difficulty"]*10 winAmount = game["difficulty"]*10
message += " Adding "+str(winAmount)+" GwendoBucks to their account." sendMessage += " Adding "+str(winAmount)+" GwendoBucks to their account."
self.bot.database["hex games"].update_one({"_id":channel}, self.bot.database["hex games"].update_one({"_id":channel},
{"$push":{"gameHistory":(int(position[1])-1, ord(position[0])-97)}}) {"$push":{"gameHistory":(int(position[1])-1, ord(position[0])-97)}})
# Is it now Gwendolyn's turn? # Is it now Gwendolyn's turn?
gwendoTurn = False gwendoTurn = False
if game["players"][turn-1] == "Gwendolyn": if game["players"][turn-1] == f"#{self.bot.user.id}":
self.bot.log("It's Gwendolyn's turn") self.bot.log("It's Gwendolyn's turn")
gwendoTurn = True gwendoTurn = True
placedPiece = True
if user == f"#{self.bot.user.id}":
await ctx.channel.send(sendMessage)
else:
await ctx.send(sendMessage)
if placedPiece:
# Update the board # Update the board
self.draw.drawHexPlacement(channel,player, position) self.draw.drawHexPlacement(channel,player, position)
return message, True, True, gameWon, gwendoTurn with open(f"resources/games/oldImages/hex{channel}", "r") as f:
oldImage = await ctx.channel.fetch_message(int(f.read()))
if oldImage is not None:
await oldImage.delete()
else: else:
# Invalid move. "board" is the error message self.bot.log("The old image was already deleted")
message = board
return message, False, False, False, False self.bot.log("Sending the image")
filePath = f"resources/games/hexBoards/board{channel}.png"
oldImage = await ctx.channel.send(file = discord.File(filePath))
if gameWon:
self.bot.log("Dealing with the winning player")
game = self.bot.database["hex games"].find_one({"_id":channel})
winner = game["winner"]
if game["players"][winner-1] != f"#{self.bot.user.id}":
winnings = game["difficulty"]*10
self.bot.money.addMoney(game["players"][winner-1].lower(),winnings)
else: else:
# Move out of turn with open(f"resources/games/oldImages/hex{channel}", "w") as f:
message = "It isn't your turn, it is "+self.bot.databaseFuncs.getName(game["players"][turn-1])+"'s turn." f.write(str(oldImage.id))
return message, False, False, False, False
else: if gwendoTurn:
message = "You can't place when you're not in the game. The game's players are: "+self.bot.databaseFuncs.getName(game["players"][0])+" and "+self.bot.databaseFuncs.getName(game["players"][1])+"." await self.hexAI(ctx)
return message, False, False, False, False
else:
return "There's no game in this channel", False, False, False, False
# Returns a board where the placement has ocurred # Returns a board where the placement has ocurred
def placeOnHexBoard(self, board,player,position): def placeOnHexBoard(self, board,player,position):
# Translates the position # Translates the position
position = position.lower() position = position.lower()
# Error handling # Error handling
try:
column = ord(position[0]) - 97 # ord() translates from letter to number column = ord(position[0]) - 97 # ord() translates from letter to number
row = int(position[1:]) - 1 row = int(position[1:]) - 1
if column not in range(BOARDWIDTH) or row not in range(BOARDWIDTH): if column not in range(BOARDWIDTH) or row not in range(BOARDWIDTH):
self.bot.log("Position out of bounds (error code 1533)") self.bot.log("Position out of bounds")
return "Error. That position is out of bounds." return None
except:
self.bot.log("Invalid position (error code 1531)")
return "Error. The position should be a letter followed by a number, e.g. \"e2\"."
# Place at the position # Place at the position
if board[row][column] == 0: if board[row][column] == 0:
board[row][column] = player board[row][column] = player
return board return board
else: else:
self.bot.log("Cannot place on existing piece (error code 1532)") self.bot.log("Cannot place on existing piece (error code 1532)")
return "Error. You must place on an empty space." return None
# After your move, you have the option to undo get your turn back #TimeTravel # After your move, you have the option to undo get your turn back #TimeTravel
def undoHex(self, channel, user): async def undo(self, ctx):
channel = str(ctx.channel_id)
user = f"#{ctx.author.id}"
undid = False
game = self.bot.database["hex games"].find_one({"_id":channel}) game = self.bot.database["hex games"].find_one({"_id":channel})
if user in game["players"]: if user not in game["players"]:
if len(game["gameHistory"]): sendMessage = "You're not a player in the game"
elif len(game["gameHistory"]) == 0:
sendMessage = "You can't undo nothing"
elif user != game["players"][(game["turn"] % 2)]: # If it's not your turn
sendMessage = "It's not your turn"
else:
turn = game["turn"] turn = game["turn"]
# You can only undo after your turn, which is the opponent's turn.
if user == game["players"][(turn % 2)]: # If it's not your turn
self.bot.log("Undoing {}'s last move".format(self.bot.databaseFuncs.getName(user))) self.bot.log("Undoing {}'s last move".format(self.bot.databaseFuncs.getName(user)))
lastMove = game["gameHistory"].pop() lastMove = game["gameHistory"].pop()
@@ -237,20 +331,30 @@ class HexGame():
# Update the board # Update the board
self.draw.drawHexPlacement(channel,0,"abcdefghijk"[lastMove[1]]+str(lastMove[0]+1)) # The zero makes the hex disappear self.draw.drawHexPlacement(channel,0,"abcdefghijk"[lastMove[1]]+str(lastMove[0]+1)) # The zero makes the hex disappear
return "You undid your last move at {}".format(lastMove), True, True, False, False sendMessage = f"You undid your last move at {lastMove}"
else: undid = True
# Sassy
return "Nice try. You can't undo your opponent's move. ", False, False, False, False
else:
# Sassy
return "Really? You undo right at the start of the game?", False, False, False, False
await ctx.send(sendMessage)
if undid:
with open(f"resources/games/oldImages/hex{channel}", "r") as f:
oldImage = await ctx.channel.fetch_message(int(f.read()))
if oldImage is not None:
await oldImage.delete()
else: else:
return "You're not a player in the game", False, False, False, False self.bot.log("The old image was already deleted")
self.bot.log("Sending the image")
filePath = f"resources/games/hexBoards/board{channel}.png"
oldImage = await ctx.channel.send(file = discord.File(filePath))
with open(f"resources/games/oldImages/hex{channel}", "w") as f:
f.write(str(oldImage.id))
# Plays as the AI # Plays as the AI
def hexAI(self, channel): async def hexAI(self, ctx):
channel = str(ctx.channel_id)
self.bot.log("Figuring out best move") self.bot.log("Figuring out best move")
game = self.bot.database["hex games"].find_one({"_id":channel}) game = self.bot.database["hex games"].find_one({"_id":channel})
board = game["board"] board = game["board"]
@@ -269,32 +373,10 @@ class HexGame():
moves.remove(move) moves.remove(move)
chosenMove = random.choice(moves) chosenMove = random.choice(moves)
"""
GwenColor = data[channel]["players"].index("Gwendolyn") + 1 # either 1 or 2 - red or blue
if len(data[channel]["gameHistory"]) == 0:
return placeHex(channel,"F6", "Gwendolyn") # If starting, start in the middle
board = data[channel]["board"]
difficulty = data[channel]["difficulty"]
possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0]
judgements = [float('nan')]*len(possiblePlaces) # All possible moves are yet to be judged
current_score = evaluateBoard(board)[0]
for i in possiblePlaces:
testBoard = copy.deepcopy(board)
testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = GwenColor
if evaluateBoard(testBoard)[0] != current_score: # only think about a move if it improves the score (it's impossible to get worse)
# Testing a move and evaluating it
judgements[i] = minimaxHex(testBoard,difficulty,-math.inf,math.inf,GwenColor==2)
self.bot.log("Best score for place {} is {}".format((i // BOARDWIDTH,i % BOARDWIDTH),judgements[i]))
bestScore = max(judgements) if (GwenColor == 1) else min(judgements) # this line has an error
indices = [i for i, x in enumerate(judgements) if x == bestScore] # which moves got that score?
i = random.choice(indices)
chosenMove = (i // BOARDWIDTH , i % BOARDWIDTH)
"""
placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1) placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1)
self.bot.log("ChosenMove is {} at {}".format(chosenMove,placement)) self.bot.log(f"ChosenMove is {chosenMove} at {placement}")
return self.placeHex(channel,placement, "Gwendolyn")
await self.placeHex(ctx, placement, f"#{self.bot.user.id}")
def evaluateBoard(self, board): def evaluateBoard(self, board):

View File

@@ -122,7 +122,7 @@ class DrawHex():
def drawHexPlacement(self, channel,player,position): def drawHexPlacement(self, channel,player,position):
FILEPATH = "resources/games/hexBoards/board"+channel+".png" FILEPATH = "resources/games/hexBoards/board"+channel+".png"
self.bot.log("Drawing a newly placed hex. Filepath: "+FILEPATH) self.bot.log(f"Drawing a newly placed hex. Filename: board{channel}.png")
# Translates position # Translates position
# We don't need to error-check, because the position is already checked in placeOnHexBoard() # We don't need to error-check, because the position is already checked in placeOnHexBoard()

View File

@@ -53,10 +53,10 @@ class databaseFuncs():
def getName(self, userID): def getName(self, userID):
user = self.bot.database["users"].find_one({"_id":userID}) user = self.bot.database["users"].find_one({"_id":userID})
if user != None: if userID == f"#{self.bot.user.id}":
return user["user name"]
elif userID == f"#{self.bot.user.id}":
return "Gwendolyn" return "Gwendolyn"
elif user != None:
return user["user name"]
else: else:
self.bot.log(f"Couldn't find user {userID}") self.bot.log(f"Couldn't find user {userID}")
return userID return userID
@@ -78,6 +78,7 @@ class databaseFuncs():
self.bot.database["blackjack games"].delete_many({}) self.bot.database["blackjack games"].delete_many({})
self.bot.database["connect 4 games"].delete_many({}) self.bot.database["connect 4 games"].delete_many({})
self.bot.database["hangman games"].delete_many({}) self.bot.database["hangman games"].delete_many({})
self.bot.database["hex games"].delete_many({})
if not self.bot.options.testing: if not self.bot.options.testing:
g = git.cmd.Git("") g = git.cmd.Git("")