Merge pull request #64 from NikolajDanger/improve_codebase
Improve cogs and better slash command integration
This commit is contained in:
18
Gwendolyn.py
18
Gwendolyn.py
@ -4,7 +4,7 @@ from discord.ext import commands
|
|||||||
from discord_slash import SlashCommand
|
from discord_slash import SlashCommand
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
from funcs import Money, StarWars, Games, Other, LookupFuncs
|
from funcs import Money, StarWars, Games, Other, LookupFuncs
|
||||||
from utils import Options, Credentials, logThis, makeFiles, databaseFuncs
|
from utils import Options, Credentials, logThis, makeFiles, databaseFuncs, EventHandler, ErrorHandler
|
||||||
|
|
||||||
class Gwendolyn(commands.Bot):
|
class Gwendolyn(commands.Bot):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -25,6 +25,8 @@ class Gwendolyn(commands.Bot):
|
|||||||
self.games = Games(self)
|
self.games = Games(self)
|
||||||
self.money = Money(self)
|
self.money = Money(self)
|
||||||
self.databaseFuncs = databaseFuncs(self)
|
self.databaseFuncs = databaseFuncs(self)
|
||||||
|
self.eventHandler = EventHandler(self)
|
||||||
|
self.errorHandler = ErrorHandler(self)
|
||||||
|
|
||||||
intents = discord.Intents.default()
|
intents = discord.Intents.default()
|
||||||
intents.members = True
|
intents.members = True
|
||||||
@ -34,6 +36,20 @@ class Gwendolyn(commands.Bot):
|
|||||||
def log(self, messages, channel : str = "", level : int = 20):
|
def log(self, messages, channel : str = "", level : int = 20):
|
||||||
logThis(messages, channel, level)
|
logThis(messages, channel, level)
|
||||||
|
|
||||||
|
async def stop(self, ctx):
|
||||||
|
if f"#{ctx.author.id}" in self.options.admins:
|
||||||
|
await ctx.send("Pulling git repo and restarting...")
|
||||||
|
|
||||||
|
await self.change_presence(status = discord.Status.offline)
|
||||||
|
|
||||||
|
self.databaseFuncs.stopServer()
|
||||||
|
|
||||||
|
self.log("Logging out", level = 25)
|
||||||
|
await self.close()
|
||||||
|
else:
|
||||||
|
self.log(f"{ctx.author.display_name} tried to stop me! (error code 201)",str(ctx.channel_id))
|
||||||
|
await ctx.send(f"I don't think I will, {ctx.author.display_name} (error code 201)")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -1,57 +1,34 @@
|
|||||||
import discord, traceback
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
class EventCog(commands.Cog):
|
class EventCog(commands.Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.bot.on_error = self.on_error
|
||||||
|
|
||||||
# Syncs commands, sets the game, and logs when the bot logs in
|
# Syncs commands, sets the game, and logs when the bot logs in
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
await self.bot.databaseFuncs.syncCommands()
|
await self.bot.eventHandler.on_ready()
|
||||||
self.bot.log("Logged in as "+self.bot.user.name+", "+str(self.bot.user.id), level = 25)
|
|
||||||
game = discord.Game("Use /help for commands")
|
|
||||||
await self.bot.change_presence(activity=game, status = discord.Status.online)
|
|
||||||
|
|
||||||
@commands.Cog.listener()
|
|
||||||
async def on_disconnect(self):
|
|
||||||
await self.bot.change_presence(status = discord.Status.offline)
|
|
||||||
|
|
||||||
# Logs when user sends a command
|
# Logs when user sends a command
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_slash_command(self, ctx):
|
async def on_slash_command(self, ctx):
|
||||||
self.bot.log(f"{ctx.author.display_name} ran /{ctx.name}", str(ctx.channel_id), level = 25)
|
await self.bot.eventHandler.on_slash_command(ctx)
|
||||||
|
|
||||||
# Logs if a command experiences an error
|
# Logs if a command experiences an error
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_slash_command_error(self, ctx, error):
|
async def on_slash_command_error(self, ctx, error):
|
||||||
if isinstance(error, commands.CommandNotFound):
|
await self.bot.errorHandler.on_slash_command_error(ctx, error)
|
||||||
await ctx.send("That's not a command (error code 001)")
|
|
||||||
elif isinstance(error,commands.errors.MissingRequiredArgument):
|
|
||||||
self.bot.log(f"{error}",str(ctx.channel_id))
|
|
||||||
await ctx.send("Missing command parameters (error code 002). Try using `!help [command]` to find out how to use the command.")
|
|
||||||
else:
|
|
||||||
exception = traceback.format_exception(type(error), error, error.__traceback__)
|
|
||||||
stopAt = "\nThe above exception was the direct cause of the following exception:\n\n"
|
|
||||||
if stopAt in exception:
|
|
||||||
index = exception.index(stopAt)
|
|
||||||
exception = exception[:index]
|
|
||||||
|
|
||||||
exceptionString = "".join(exception)
|
# Logs if on error occurs
|
||||||
self.bot.log([f"exception in /{ctx.name}", f"{exceptionString}"],str(ctx.channel_id), 40)
|
async def on_error(self, method, *args, **kwargs):
|
||||||
await ctx.send("Something went wrong (error code 000)")
|
await self.bot.errorHandler.on_error(method)
|
||||||
|
|
||||||
# Logs if an error occurs
|
# If someone reacted to a message, checks if it's a reaction it's
|
||||||
|
# Gwendolyn has been waiting for, and then does something
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_error(self, method):
|
async def on_reaction_add(self, reaction, user):
|
||||||
exception = traceback.format_exc()
|
await self.bot.eventHandler.on_reaction_add(reaction, user)
|
||||||
stopAt = "\nThe above exception was the direct cause of the following exception:\n\n"
|
|
||||||
if stopAt in exception:
|
|
||||||
index = exception.index(stopAt)
|
|
||||||
exception = exception[:index]
|
|
||||||
|
|
||||||
exceptionString = "".join(exception)
|
|
||||||
self.bot.log([f"exception in /{method}", f"{exceptionString}"], level = 40)
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(EventCog(bot))
|
bot.add_cog(EventCog(bot))
|
||||||
|
159
cogs/GameCogs.py
159
cogs/GameCogs.py
@ -1,7 +1,5 @@
|
|||||||
import discord, asyncio, json
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord_slash import cog_ext
|
from discord_slash import cog_ext
|
||||||
from discord_slash import SlashCommandOptionType as scot
|
|
||||||
|
|
||||||
from utils import getParams
|
from utils import getParams
|
||||||
|
|
||||||
@ -15,73 +13,22 @@ class GamesCog(commands.Cog):
|
|||||||
# Checks user balance
|
# Checks user balance
|
||||||
@cog_ext.cog_slash(**params["balance"])
|
@cog_ext.cog_slash(**params["balance"])
|
||||||
async def balance(self, ctx):
|
async def balance(self, ctx):
|
||||||
await ctx.defer()
|
await self.bot.money.sendBalance(ctx)
|
||||||
response = self.bot.money.checkBalance("#"+str(ctx.author.id))
|
|
||||||
if response == 1:
|
|
||||||
new_message = ctx.author.display_name + " has " + str(response) + " GwendoBuck"
|
|
||||||
else:
|
|
||||||
new_message = ctx.author.display_name + " has " + str(response) + " GwendoBucks"
|
|
||||||
await ctx.send(new_message)
|
|
||||||
|
|
||||||
# Gives another user an amount of GwendoBucks
|
# Gives another user an amount of GwendoBucks
|
||||||
@cog_ext.cog_slash(**params["give"])
|
@cog_ext.cog_slash(**params["give"])
|
||||||
async def give(self, ctx, user, amount):
|
async def give(self, ctx, user, amount):
|
||||||
await ctx.defer()
|
await self.bot.money.giveMoney(ctx, user, amount)
|
||||||
username = user.display_name
|
|
||||||
if self.bot.databaseFuncs.getID(username) == None:
|
|
||||||
async for member in ctx.guild.fetch_members(limit=None):
|
|
||||||
if member.display_name.lower() == username.lower():
|
|
||||||
username = member.display_name
|
|
||||||
userID = "#" + str(member.id)
|
|
||||||
self.bot.database["users"].insert_one({"_id":userID,"user name":username,"money":0})
|
|
||||||
response = self.bot.money.giveMoney("#"+str(ctx.author.id),username,amount)
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
# Invest GwendoBucks in the stock market
|
# Invest GwendoBucks in the stock market
|
||||||
@cog_ext.cog_slash(**params["invest"])
|
@cog_ext.cog_slash(**params["invest"])
|
||||||
async def invest(self, ctx, parameters = "check"):
|
async def invest(self, ctx, parameters = "check"):
|
||||||
await ctx.defer()
|
await self.bot.games.invest.parseInvest(ctx, parameters)
|
||||||
response = self.bot.games.invest.parseInvest(parameters,"#"+str(ctx.author.id))
|
|
||||||
if response.startswith("**"):
|
|
||||||
responses = response.split("\n")
|
|
||||||
em = discord.Embed(title=responses[0],description="\n".join(responses[1:]),colour=0x00FF00)
|
|
||||||
await ctx.send(embed=em)
|
|
||||||
else:
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
# Runs a game of trivia
|
# Runs a game of trivia
|
||||||
@cog_ext.cog_slash(**params["trivia"])
|
@cog_ext.cog_slash(**params["trivia"])
|
||||||
async def trivia(self, ctx, answer = ""):
|
async def trivia(self, ctx, answer = ""):
|
||||||
await ctx.defer()
|
await self.bot.games.trivia.triviaParse(ctx, answer)
|
||||||
if answer == "":
|
|
||||||
question, options, correctAnswer = self.bot.games.trivia.triviaStart(str(ctx.channel_id))
|
|
||||||
if options != "":
|
|
||||||
results = "**"+question+"**\n"
|
|
||||||
for x, option in enumerate(options):
|
|
||||||
results += chr(x+97) + ") "+option+"\n"
|
|
||||||
|
|
||||||
await ctx.send(results)
|
|
||||||
|
|
||||||
await asyncio.sleep(60)
|
|
||||||
|
|
||||||
self.bot.games.trivia.triviaCountPoints(str(ctx.channel_id))
|
|
||||||
|
|
||||||
self.bot.databaseFuncs.deleteGame("trivia questions",str(ctx.channel_id))
|
|
||||||
|
|
||||||
self.bot.log("Time's up for the trivia question",str(ctx.channel_id))
|
|
||||||
await ctx.send("Time's up The answer was \""+chr(correctAnswer)+") "+options[correctAnswer-97]+"\". Anyone who answered that has gotten 1 GwendoBuck")
|
|
||||||
else:
|
|
||||||
await ctx.send(question, hidden=True)
|
|
||||||
|
|
||||||
elif answer in ["a","b","c","d"]:
|
|
||||||
response = self.bot.games.trivia.triviaAnswer("#"+str(ctx.author.id),str(ctx.channel_id),answer)
|
|
||||||
if response.startswith("Locked in "):
|
|
||||||
await ctx.send(f"{ctx.author.display_name} answered {answer}")
|
|
||||||
else:
|
|
||||||
await ctx.send(response)
|
|
||||||
else:
|
|
||||||
self.bot.log("I didn't understand that (error code 1101)",str(ctx.channel_id))
|
|
||||||
await ctx.send("I didn't understand that (error code 1101)")
|
|
||||||
|
|
||||||
|
|
||||||
class BlackjackCog(commands.Cog):
|
class BlackjackCog(commands.Cog):
|
||||||
@ -92,103 +39,113 @@ class BlackjackCog(commands.Cog):
|
|||||||
# Starts a game of blackjack
|
# Starts a game of blackjack
|
||||||
@cog_ext.cog_subcommand(**params["blackjackStart"])
|
@cog_ext.cog_subcommand(**params["blackjackStart"])
|
||||||
async def blackjackStart(self, ctx):
|
async def blackjackStart(self, ctx):
|
||||||
await ctx.defer()
|
await self.bot.games.blackjack.start(ctx)
|
||||||
await self.bot.games.blackjack.parseBlackjack("", ctx)
|
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["blackjackBet"])
|
@cog_ext.cog_subcommand(**params["blackjackBet"])
|
||||||
async def blackjackBet(self, ctx, bet):
|
async def blackjackBet(self, ctx, bet):
|
||||||
await ctx.defer()
|
await self.bot.games.blackjack.playerDrawHand(ctx, bet)
|
||||||
await self.bot.games.blackjack.parseBlackjack(f"bet {bet}", ctx)
|
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["blackjackStand"])
|
@cog_ext.cog_subcommand(**params["blackjackStand"])
|
||||||
async def blackjackStand(self, ctx, hand = ""):
|
async def blackjackStand(self, ctx, hand = ""):
|
||||||
await ctx.defer()
|
await self.bot.games.blackjack.stand(ctx, hand)
|
||||||
await self.bot.games.blackjack.parseBlackjack(f"stand {hand}", ctx)
|
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(**params["blackjackHit"])
|
@cog_ext.cog_subcommand(**params["blackjackHit"])
|
||||||
async def blackjackHit(self, ctx, hand = ""):
|
async def blackjackHit(self, ctx, hand = 0):
|
||||||
await ctx.defer()
|
await self.bot.games.blackjack.hit(ctx, hand)
|
||||||
await self.bot.games.blackjack.parseBlackjack(f"hit {hand}", ctx)
|
|
||||||
|
@cog_ext.cog_subcommand(**params["blackjackDouble"])
|
||||||
|
async def blackjackDouble(self, ctx, hand = 0):
|
||||||
|
await self.bot.games.blackjack.double(ctx, hand)
|
||||||
|
|
||||||
|
@cog_ext.cog_subcommand(**params["blackjackSplit"])
|
||||||
|
async def blackjackSplit(self, ctx, hand = 0):
|
||||||
|
await self.bot.games.blackjack.split(ctx, hand)
|
||||||
|
|
||||||
|
@cog_ext.cog_subcommand(**params["blackjackHilo"])
|
||||||
|
async def blackjackHilo(self, ctx):
|
||||||
|
await self.bot.games.blackjack.hilo(ctx)
|
||||||
|
|
||||||
|
@cog_ext.cog_subcommand(**params["blackjackShuffle"])
|
||||||
|
async def blackjackShuffle(self, ctx):
|
||||||
|
await self.bot.games.blackjack.shuffle(ctx)
|
||||||
|
|
||||||
|
@cog_ext.cog_subcommand(**params["blackjackCards"])
|
||||||
|
async def blackjackCards(self, ctx):
|
||||||
|
await self.bot.games.blackjack.cards(ctx)
|
||||||
|
|
||||||
|
|
||||||
class ConnectFourCog(commands.Cog):
|
class ConnectFourCog(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 connect four against a user
|
# Start a game of connect four against a user
|
||||||
@cog_ext.cog_subcommand(**params["connectFourStartUser"])
|
@cog_ext.cog_subcommand(**params["connectFourStartUser"])
|
||||||
async def connectFourStartUser(self, ctx, user):
|
async def connectFourStartUser(self, ctx, user):
|
||||||
await ctx.defer()
|
await self.bot.games.connectFour.start(ctx, user)
|
||||||
await self.bot.games.gameLoops.connectFour(ctx, "start "+user.display_name)
|
|
||||||
|
|
||||||
# Start a game of connect four against gwendolyn
|
# Start a game of connect four against gwendolyn
|
||||||
@cog_ext.cog_subcommand(**params["connectFourStartGwendolyn"])
|
@cog_ext.cog_subcommand(**params["connectFourStartGwendolyn"])
|
||||||
async def connectFourStartGwendolyn(self, ctx, difficulty = 3):
|
async def connectFourStartGwendolyn(self, ctx, difficulty = 3):
|
||||||
await ctx.defer()
|
await self.bot.games.connectFour.start(ctx, difficulty)
|
||||||
await self.bot.games.gameLoops.connectFour(ctx, "start "+str(difficulty))
|
|
||||||
|
|
||||||
# Stop the current game of connect four
|
# Stop the current game of connect four
|
||||||
@cog_ext.cog_subcommand(**params["connectFourStop"])
|
@cog_ext.cog_subcommand(**params["connectFourSurrender"])
|
||||||
async def connectFourStop(self, ctx):
|
async def connectFourSurrender(self, ctx):
|
||||||
await self.bot.games.gameLoops.connectFour(ctx, "stop")
|
await self.bot.games.connectFour.surrender(ctx)
|
||||||
|
|
||||||
# Place a piece in the current game of connect four
|
|
||||||
@cog_ext.cog_subcommand(**params["connectFourPlace"])
|
|
||||||
async def connectFourPlace(self, ctx, column):
|
|
||||||
await self.bot.games.gameLoops.connectFour(ctx, "place "+str(column))
|
|
||||||
|
|
||||||
|
|
||||||
class HangmanCog(commands.Cog):
|
class HangmanCog(commands.Cog):
|
||||||
def __init__(self,bot):
|
def __init__(self,bot):
|
||||||
"""Runs game stuff."""
|
"""Runs game stuff."""
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
# Starts a game of Hangman
|
# Starts a game of Hangman
|
||||||
@cog_ext.cog_subcommand(**params["hangmanStart"])
|
@cog_ext.cog_subcommand(**params["hangmanStart"])
|
||||||
async def hangmanStart(self, ctx):
|
async def hangmanStart(self, ctx):
|
||||||
await ctx.defer()
|
await self.bot.games.hangman.start(ctx)
|
||||||
await self.bot.games.gameLoops.runHangman(ctx.channel,"#"+str(ctx.author.id),"start", ctx)
|
|
||||||
|
|
||||||
# Stops a game of Hangman
|
# Stops a game of Hangman
|
||||||
@cog_ext.cog_subcommand(**params["hangmanStop"])
|
@cog_ext.cog_subcommand(**params["hangmanStop"])
|
||||||
async def hangmanStop(self, ctx):
|
async def hangmanStop(self, ctx):
|
||||||
await self.bot.games.gameLoops.runHangman(ctx.channel,"#"+str(ctx.author.id),"stop", ctx)
|
await self.bot.games.hangman.stop(ctx)
|
||||||
|
|
||||||
|
|
||||||
class HexCog(commands.Cog):
|
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):
|
||||||
bot.add_cog(GamesCog(bot))
|
bot.add_cog(GamesCog(bot))
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import discord, json
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord_slash import cog_ext
|
from discord_slash import cog_ext
|
||||||
from discord_slash import SlashCommandOptionType as scot
|
|
||||||
|
|
||||||
from utils import getParams, cap
|
from utils import getParams
|
||||||
|
|
||||||
params = getParams()
|
params = getParams()
|
||||||
|
|
||||||
@ -15,58 +13,12 @@ class LookupCog(commands.Cog):
|
|||||||
# Looks up a spell
|
# Looks up a spell
|
||||||
@cog_ext.cog_slash(**params["spell"])
|
@cog_ext.cog_slash(**params["spell"])
|
||||||
async def spell(self, ctx, query):
|
async def spell(self, ctx, query):
|
||||||
spell = self.bot.lookupFuncs.spellFunc(cap(query))
|
await self.bot.lookupFuncs.spellFunc(ctx, query)
|
||||||
if len(spell) > 2000:
|
|
||||||
await ctx.send(spell[:2000])
|
|
||||||
await ctx.send(spell[2000:])
|
|
||||||
else:
|
|
||||||
await ctx.send(spell)
|
|
||||||
|
|
||||||
# Looks up a monster
|
# Looks up a monster
|
||||||
@cog_ext.cog_slash(**params["monster"])
|
@cog_ext.cog_slash(**params["monster"])
|
||||||
async def monster(self, ctx, query):
|
async def monster(self, ctx, query):
|
||||||
title, text1, text2, text3, text4, text5 = self.bot.lookupFuncs.monsterFunc(cap(query))
|
await self.bot.lookupFuncs.monsterFunc(ctx, query)
|
||||||
em1 = discord.Embed(title = title, description = text1, colour=0xDEADBF)
|
|
||||||
|
|
||||||
# Sends the received information. Separates into separate messages if
|
|
||||||
# there is too much text
|
|
||||||
await ctx.send(embed = em1)
|
|
||||||
if text2 != "":
|
|
||||||
if len(text2) < 2048:
|
|
||||||
em2 = discord.Embed(title = "Special Abilities", description = text2, colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em2)
|
|
||||||
else:
|
|
||||||
em2 = discord.Embed(title = "Special Abilities", description = text2[:2048], colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em2)
|
|
||||||
em2_2 = discord.Embed(title = "", description = text2[2048:], colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em2_2)
|
|
||||||
if text3 != "":
|
|
||||||
if len(text3) < 2048:
|
|
||||||
em3 = discord.Embed(title = "Actions", description = text3, colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em3)
|
|
||||||
else:
|
|
||||||
em3 = discord.Embed(title = "Actions", description = text3[:2048], colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em3)
|
|
||||||
em3_2 = discord.Embed(title = "", description = text3[2048:], colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em3_2)
|
|
||||||
if text4 != "":
|
|
||||||
if len(text4) < 2048:
|
|
||||||
em4 = discord.Embed(title = "Reactions", description = text4, colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em4)
|
|
||||||
else:
|
|
||||||
em4 = discord.Embed(title = "Reactions", description = text4[:2048], colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em4)
|
|
||||||
em4_2 = discord.Embed(title = "", description = text4[2048:], colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em4_2)
|
|
||||||
if text5 != "":
|
|
||||||
if len(text5) < 2048:
|
|
||||||
em5 = discord.Embed(title = "Legendary Actions", description = text5, colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em5)
|
|
||||||
else:
|
|
||||||
em5 = discord.Embed(title = "Legendary Actions", description = text5[:2048], colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em5)
|
|
||||||
em5_2 = discord.Embed(title = "", description = text5[2048:], colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em5_2)
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(LookupCog(bot))
|
bot.add_cog(LookupCog(bot))
|
@ -2,16 +2,9 @@ import discord, codecs, string, json
|
|||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord_slash import cog_ext
|
from discord_slash import cog_ext
|
||||||
|
|
||||||
from utils import Options
|
from utils import getParams
|
||||||
|
|
||||||
with open("resources/slashParameters.json", "r") as f:
|
params = getParams()
|
||||||
params = json.load(f)
|
|
||||||
|
|
||||||
options = Options()
|
|
||||||
|
|
||||||
if options.testing:
|
|
||||||
for p in params:
|
|
||||||
params[p]["guild_ids"] = options.guildIds
|
|
||||||
|
|
||||||
class MiscCog(commands.Cog):
|
class MiscCog(commands.Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
@ -30,31 +23,12 @@ class MiscCog(commands.Cog):
|
|||||||
# Restarts the bot
|
# Restarts the bot
|
||||||
@cog_ext.cog_slash(**params["stop"])
|
@cog_ext.cog_slash(**params["stop"])
|
||||||
async def stop(self, ctx):
|
async def stop(self, ctx):
|
||||||
if "#"+str(ctx.author.id) in self.bot.options.admins:
|
await self.bot.stop(ctx)
|
||||||
await ctx.send("Pulling git repo and restarting...")
|
|
||||||
|
|
||||||
self.bot.databaseFuncs.stopServer()
|
|
||||||
|
|
||||||
self.bot.log("Logging out.")
|
|
||||||
await self.bot.logout()
|
|
||||||
else:
|
|
||||||
self.bot.log(f"{ctx.author.display_name} tried to stop me! (error code 201)",str(ctx.channel_id))
|
|
||||||
await ctx.send(f"I don't think I will, {ctx.author.display_name} (error code 201)")
|
|
||||||
|
|
||||||
# Gets help for specific command
|
# Gets help for specific command
|
||||||
@cog_ext.cog_slash(**params["help"])
|
@cog_ext.cog_slash(**params["help"])
|
||||||
async def helpCommand(self, ctx, command = ""):
|
async def helpCommand(self, ctx, command = ""):
|
||||||
if command == "":
|
await self.bot.other.helpFunc(ctx, command)
|
||||||
with codecs.open("resources/help/help.txt",encoding="utf-8") as f:
|
|
||||||
text = f.read()
|
|
||||||
em = discord.Embed(title = "Help", description = text,colour = 0x59f442)
|
|
||||||
await ctx.send(embed = em)
|
|
||||||
else:
|
|
||||||
self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id))
|
|
||||||
with codecs.open(f"resources/help/help-{command}.txt",encoding="utf-8") as f:
|
|
||||||
text = f.read()
|
|
||||||
em = discord.Embed(title = command.capitalize(), description = text,colour = 0x59f442)
|
|
||||||
await ctx.send(embed = em)
|
|
||||||
|
|
||||||
# Lets you thank the bot
|
# Lets you thank the bot
|
||||||
@cog_ext.cog_slash(**params["thank"])
|
@cog_ext.cog_slash(**params["thank"])
|
||||||
@ -64,67 +38,51 @@ class MiscCog(commands.Cog):
|
|||||||
# Sends a friendly message
|
# Sends a friendly message
|
||||||
@cog_ext.cog_slash(**params["hello"])
|
@cog_ext.cog_slash(**params["hello"])
|
||||||
async def hello(self, ctx):
|
async def hello(self, ctx):
|
||||||
await ctx.send(self.bot.other.helloFunc(ctx.author.display_name))
|
await self.bot.other.helloFunc(ctx)
|
||||||
|
|
||||||
# Rolls dice
|
# Rolls dice
|
||||||
@cog_ext.cog_slash(**params["roll"])
|
@cog_ext.cog_slash(**params["roll"])
|
||||||
async def roll(self, ctx, dice = "1d20"):
|
async def roll(self, ctx, dice = "1d20"):
|
||||||
await ctx.send(self.bot.other.rollDice(ctx.author.display_name, dice))
|
await self.bot.other.rollDice(ctx, dice)
|
||||||
|
|
||||||
# Sends a random image
|
# Sends a random image
|
||||||
@cog_ext.cog_slash(**params["image"])
|
@cog_ext.cog_slash(**params["image"])
|
||||||
async def image(self, ctx):
|
async def image(self, ctx):
|
||||||
await ctx.defer()
|
await self.bot.other.imageFunc(ctx)
|
||||||
await ctx.send(self.bot.other.imageFunc())
|
|
||||||
|
|
||||||
# Finds a random movie
|
# Finds a random movie
|
||||||
@cog_ext.cog_slash(**params["movie"])
|
@cog_ext.cog_slash(**params["movie"])
|
||||||
async def movie(self,ctx):
|
async def movie(self, ctx):
|
||||||
await self.bot.other.movieFunc(ctx)
|
await self.bot.other.movieFunc(ctx)
|
||||||
|
|
||||||
# Generates a random name
|
# Generates a random name
|
||||||
@cog_ext.cog_slash(**params["name"])
|
@cog_ext.cog_slash(**params["name"])
|
||||||
async def name(self, ctx):
|
async def name(self, ctx):
|
||||||
await ctx.send(self.generators.nameGen())
|
await self.generators.nameGen(ctx)
|
||||||
|
|
||||||
# Generates a random tavern name
|
# Generates a random tavern name
|
||||||
@cog_ext.cog_slash(**params["tavern"])
|
@cog_ext.cog_slash(**params["tavern"])
|
||||||
async def tavern(self, ctx):
|
async def tavern(self, ctx):
|
||||||
await ctx.send(self.generators.tavernGen())
|
await self.generators.tavernGen(ctx)
|
||||||
|
|
||||||
# Finds a page on the Senkulpa wiki
|
# Finds a page on the Senkulpa wiki
|
||||||
@cog_ext.cog_slash(**params["wiki"])
|
@cog_ext.cog_slash(**params["wiki"])
|
||||||
async def wiki(self, ctx, wikiPage):
|
async def wiki(self, ctx, wikiPage):
|
||||||
await ctx.defer()
|
await self.bot.other.findWikiPage(ctx, wikiPage)
|
||||||
command = string.capwords(wikiPage)
|
|
||||||
title, content, thumbnail = self.bot.otherfindWikiPage(command)
|
|
||||||
if title != "":
|
|
||||||
self.bot.log("Sending the embedded message",str(ctx.channel_id))
|
|
||||||
content += "\n[Læs mere](https://senkulpa.fandom.com/da/wiki/"+title.replace(" ","_")+")"
|
|
||||||
embed = discord.Embed(title = title, description = content, colour=0xDEADBF)
|
|
||||||
if thumbnail != "":
|
|
||||||
embed.set_thumbnail(url=thumbnail)
|
|
||||||
|
|
||||||
await ctx.send(embed = embed)
|
|
||||||
else:
|
|
||||||
await ctx.send(content)
|
|
||||||
|
|
||||||
#Searches for movie and adds it to Bedre Netflix
|
#Searches for movie and adds it to Bedre Netflix
|
||||||
@cog_ext.cog_slash(**params["addMovie"])
|
@cog_ext.cog_slash(**params["addMovie"])
|
||||||
async def addMovie(self, ctx, movie):
|
async def addMovie(self, ctx, movie):
|
||||||
await ctx.defer()
|
|
||||||
await self.bedreNetflix.requestMovie(ctx, movie)
|
await self.bedreNetflix.requestMovie(ctx, movie)
|
||||||
|
|
||||||
#Searches for show and adds it to Bedre Netflix
|
#Searches for show and adds it to Bedre Netflix
|
||||||
@cog_ext.cog_slash(**params["addShow"])
|
@cog_ext.cog_slash(**params["addShow"])
|
||||||
async def addShow(self, ctx, show):
|
async def addShow(self, ctx, show):
|
||||||
await ctx.defer()
|
|
||||||
await self.bedreNetflix.requestShow(ctx, show)
|
await self.bedreNetflix.requestShow(ctx, show)
|
||||||
|
|
||||||
#Returns currently downloading torrents
|
#Returns currently downloading torrents
|
||||||
@cog_ext.cog_slash(**params["downloading"])
|
@cog_ext.cog_slash(**params["downloading"])
|
||||||
async def downloading(self, ctx, parameters = "-d"):
|
async def downloading(self, ctx, parameters = "-d"):
|
||||||
await ctx.defer()
|
|
||||||
await self.bedreNetflix.downloading(ctx, parameters)
|
await self.bedreNetflix.downloading(ctx, parameters)
|
||||||
|
|
||||||
#Looks up on Wolfram Alpha
|
#Looks up on Wolfram Alpha
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
from utils import emojiToCommand
|
|
||||||
|
|
||||||
class ReactionCog(commands.Cog):
|
|
||||||
def __init__(self, bot):
|
|
||||||
"""Listens for reactions."""
|
|
||||||
self.bot = bot
|
|
||||||
|
|
||||||
@commands.Cog.listener()
|
|
||||||
async def on_reaction_add(self, reaction, user):
|
|
||||||
if user.bot == False:
|
|
||||||
message = reaction.message
|
|
||||||
channel = message.channel
|
|
||||||
self.bot.log(f"{user.display_name} reacted to a message",str(channel.id))
|
|
||||||
try:
|
|
||||||
connectFourTheirTurn, piece = self.bot.databaseFuncs.connectFourReactionTest(channel,message,"#"+str(user.id))
|
|
||||||
except:
|
|
||||||
connectFourTheirTurn = False
|
|
||||||
|
|
||||||
bedreNetflixMessage, addMovie, imdbIds = self.bot.databaseFuncs.bedreNetflixReactionTest(channel, message)
|
|
||||||
|
|
||||||
if connectFourTheirTurn:
|
|
||||||
place = emojiToCommand(reaction.emoji)
|
|
||||||
await self.bot.games.gameLoops.connectFour(message,"place "+str(piece)+" "+str(place),user.id, str(message.channel.id))
|
|
||||||
elif bedreNetflixMessage and addMovie:
|
|
||||||
moviePick = emojiToCommand(reaction.emoji)
|
|
||||||
await message.delete()
|
|
||||||
if moviePick == "none":
|
|
||||||
imdbID = None
|
|
||||||
else:
|
|
||||||
imdbID = imdbIds[moviePick-1]
|
|
||||||
await self.bot.other.bedreNetflix.addMovie(channel,imdbID)
|
|
||||||
elif bedreNetflixMessage and not addMovie:
|
|
||||||
showPick = emojiToCommand(reaction.emoji)
|
|
||||||
await message.delete()
|
|
||||||
if showPick == "none":
|
|
||||||
imdbName = None
|
|
||||||
else:
|
|
||||||
imdbName = imdbIds[showPick-1]
|
|
||||||
await self.bot.other.bedreNetflix.addShow(channel,imdbName)
|
|
||||||
elif self.bot.databaseFuncs.hangmanReactionTest(channel,message) and ord(reaction.emoji) in range(127462,127488):
|
|
||||||
guess = chr(ord(reaction.emoji)-127397)
|
|
||||||
await self.bot.games.gameLoops.runHangman(channel,"#"+str(user.id),command="guess "+guess)
|
|
||||||
def setup(bot):
|
|
||||||
bot.add_cog(ReactionCog(bot))
|
|
@ -2,16 +2,9 @@ import discord, string, json
|
|||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord_slash import cog_ext
|
from discord_slash import cog_ext
|
||||||
|
|
||||||
from utils import Options, cap
|
from utils import getParams
|
||||||
|
|
||||||
with open("resources/slashParameters.json", "r") as f:
|
params = getParams()
|
||||||
params = json.load(f)
|
|
||||||
|
|
||||||
options = Options()
|
|
||||||
|
|
||||||
if options.testing:
|
|
||||||
for p in params:
|
|
||||||
params[p]["guild_ids"] = options.guildIds
|
|
||||||
|
|
||||||
class starWarsCog(commands.Cog):
|
class starWarsCog(commands.Cog):
|
||||||
|
|
||||||
@ -22,46 +15,23 @@ class starWarsCog(commands.Cog):
|
|||||||
# Rolls star wars dice
|
# Rolls star wars dice
|
||||||
@cog_ext.cog_slash(**params["starWarsRoll"])
|
@cog_ext.cog_slash(**params["starWarsRoll"])
|
||||||
async def starWarsRoll(self, ctx, dice = ""):
|
async def starWarsRoll(self, ctx, dice = ""):
|
||||||
command = cap(dice)
|
await self.bot.starWars.roll.parseRoll(ctx, dice)
|
||||||
newMessage = self.bot.starWars.roll.parseRoll("#"+str(ctx.author.id),command)
|
|
||||||
messageList = newMessage.split("\n")
|
|
||||||
await ctx.send(messageList[0])
|
|
||||||
if len(messageList) > 1:
|
|
||||||
for messageItem in messageList[1:]:
|
|
||||||
await ctx.channel.send(messageItem)
|
|
||||||
|
|
||||||
# Controls destiny points
|
# Controls destiny points
|
||||||
@cog_ext.cog_slash(**params["starWarsDestiny"])
|
@cog_ext.cog_slash(**params["starWarsDestiny"])
|
||||||
async def starWarsDestiny(self, ctx, parameters = ""):
|
async def starWarsDestiny(self, ctx, parameters = ""):
|
||||||
newMessage = self.bot.starWars.destiny.parseDestiny("#"+str(ctx.author.id),parameters)
|
await self.bot.starWars.destiny.parseDestiny(ctx, parameters)
|
||||||
messageList = newMessage.split("\n")
|
|
||||||
await ctx.send(messageList[0])
|
|
||||||
if len(messageList) > 1:
|
|
||||||
for messageItem in messageList[1:]:
|
|
||||||
await ctx.channel.send(messageItem)
|
|
||||||
|
|
||||||
# Rolls for critical injuries
|
# Rolls for critical injuries
|
||||||
@cog_ext.cog_slash(**params["starWarsCrit"])
|
@cog_ext.cog_slash(**params["starWarsCrit"])
|
||||||
async def starWarsCrit(self, ctx, severity : int = 0):
|
async def starWarsCrit(self, ctx, severity : int = 0):
|
||||||
newMessage = self.bot.starWars.roll.critRoll(int(severity))
|
await self.bot.starWars.roll.critRoll(ctx, severity)
|
||||||
|
|
||||||
messageList = newMessage.split("\n")
|
|
||||||
await ctx.send(messageList[0])
|
|
||||||
if len(messageList) > 1:
|
|
||||||
for messageItem in messageList[1:]:
|
|
||||||
await ctx.channel.send(messageItem)
|
|
||||||
|
|
||||||
# Accesses and changes character sheet data with the parseChar function
|
# Accesses and changes character sheet data with the parseChar function
|
||||||
# from funcs/starWarsFuncs/starWarsCharacter.py
|
# from funcs/starWarsFuncs/starWarsCharacter.py
|
||||||
@cog_ext.cog_slash(**params["starWarsCharacter"])
|
@cog_ext.cog_slash(**params["starWarsCharacter"])
|
||||||
async def starWarsCharacter(self, ctx, parameters = ""):
|
async def starWarsCharacter(self, ctx, parameters = ""):
|
||||||
command = string.capwords(parameters.replace("+","+ ").replace("-","- ").replace(",",", "))
|
await self.bot.starWars.character.parseChar(ctx, parameters)
|
||||||
title, desc = self.bot.starWars.character.parseChar("#"+str(ctx.author.id),command)
|
|
||||||
if title != "":
|
|
||||||
em1 = discord.Embed(title = title, description = desc, colour=0xDEADBF)
|
|
||||||
await ctx.send(embed = em1)
|
|
||||||
else:
|
|
||||||
await ctx.send(desc)
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(starWarsCog(bot))
|
bot.add_cog(starWarsCog(bot))
|
@ -3,4 +3,4 @@
|
|||||||
__all__ = ["Money", "Games"]
|
__all__ = ["Money", "Games"]
|
||||||
|
|
||||||
from .money import Money
|
from .money import Money
|
||||||
from .games import Games
|
from .gamesContainer import Games
|
||||||
|
@ -18,7 +18,7 @@ class Blackjack():
|
|||||||
def blackjackShuffle(self, decks, channel):
|
def blackjackShuffle(self, decks, channel):
|
||||||
self.bot.log("Shuffling the blackjack deck")
|
self.bot.log("Shuffling the blackjack deck")
|
||||||
|
|
||||||
with open("resources/games/deckofCards.txt","r") as f:
|
with open("resources/games/deckOfCards.txt","r") as f:
|
||||||
deck = f.read()
|
deck = f.read()
|
||||||
|
|
||||||
allDecks = deck.split("\n") * decks
|
allDecks = deck.split("\n") * decks
|
||||||
@ -170,175 +170,223 @@ class Blackjack():
|
|||||||
|
|
||||||
return hand, allStanding, preAllStanding
|
return hand, allStanding, preAllStanding
|
||||||
|
|
||||||
|
|
||||||
# When players try to hit
|
# When players try to hit
|
||||||
def blackjackHit(self,channel,user,handNumber = 0):
|
async def hit(self, ctx, handNumber = 0):
|
||||||
|
try:
|
||||||
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("Defer failed")
|
||||||
|
channel = str(ctx.channel_id)
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
roundDone = False
|
||||||
|
|
||||||
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
||||||
|
|
||||||
if user in game["user hands"]:
|
if user in game["user hands"]:
|
||||||
|
|
||||||
hand, handNumber = self.getHandNumber(game["user hands"][user],handNumber)
|
userHands = game["user hands"][user]
|
||||||
|
hand, handNumber = self.getHandNumber(userHands, handNumber)
|
||||||
|
|
||||||
if hand != None:
|
if hand == None:
|
||||||
if game["round"] > 0:
|
logMessage = "They didn't specify a hand"
|
||||||
if hand["hit"] == False:
|
sendMessage = "You need to specify a hand"
|
||||||
if hand["standing"] == False:
|
elif game["round"] <= 0:
|
||||||
hand["hand"].append(self.drawCard(channel))
|
logMessage = "They tried to hit on the 0th round"
|
||||||
hand["hit"] = True
|
sendMessage = "You can't hit before you see your cards"
|
||||||
|
elif hand["hit"]:
|
||||||
handValue = self.calcHandValue(hand["hand"])
|
logMessage = "They've already hit this round"
|
||||||
|
sendMessage = "You've already hit this round"
|
||||||
if handValue > 21:
|
elif hand["standing"]:
|
||||||
hand["busted"] = True
|
logMessage = "They're already standing"
|
||||||
|
sendMessage = "You can't hit when you're standing"
|
||||||
if handNumber == 2:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".other hand":hand}})
|
|
||||||
elif handNumber == 3:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".third hand":hand}})
|
|
||||||
elif handNumber == 4:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".fourth hand":hand}})
|
|
||||||
else:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user:hand}})
|
|
||||||
|
|
||||||
response = "accept"
|
|
||||||
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
|
|
||||||
|
|
||||||
return response + str(roundDone)[0] + str(game["round"])
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" is already standing")
|
|
||||||
return "You can't hit when you're standing"
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" has already hit this round")
|
|
||||||
return "You've already hit this round"
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to hit on the 0th round")
|
|
||||||
return "You can't hit before you see your cards"
|
|
||||||
else:
|
else:
|
||||||
self.bot.log(user+" didn't specify a hand")
|
hand["hand"].append(self.drawCard(channel))
|
||||||
return "You need to specify a hand"
|
hand["hit"] = True
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to hit without being in the game")
|
|
||||||
return "You have to enter the game before you can hit"
|
|
||||||
|
|
||||||
|
handValue = self.calcHandValue(hand["hand"])
|
||||||
|
|
||||||
|
if handValue > 21:
|
||||||
|
hand["busted"] = True
|
||||||
|
|
||||||
|
if handNumber == 2:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".other hand":hand}})
|
||||||
|
elif handNumber == 3:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".third hand":hand}})
|
||||||
|
elif handNumber == 4:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".fourth hand":hand}})
|
||||||
|
else:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user:hand}})
|
||||||
|
|
||||||
|
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
|
||||||
|
|
||||||
|
sendMessage = f"{ctx.author.display_name} hit"
|
||||||
|
logMessage = "They succeeded"
|
||||||
|
else:
|
||||||
|
logMessage = "They tried to hit without being in the game"
|
||||||
|
sendMessage = "You have to enter the game before you can hit"
|
||||||
|
|
||||||
|
await ctx.send(sendMessage)
|
||||||
|
self.bot.log(logMessage)
|
||||||
|
|
||||||
|
if roundDone:
|
||||||
|
gameID = game["gameID"]
|
||||||
|
self.bot.log("Hit calling self.blackjackLoop()", channel)
|
||||||
|
await self.blackjackLoop(ctx.channel, game["round"]+1, gameID)
|
||||||
|
|
||||||
# When players try to double down
|
# When players try to double down
|
||||||
def blackjackDouble(self,channel,user,handNumber = 0):
|
async def double(self, ctx, handNumber = 0):
|
||||||
|
try:
|
||||||
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("Defer failed")
|
||||||
|
channel = str(ctx.channel_id)
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
roundDone = False
|
||||||
|
|
||||||
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
||||||
|
|
||||||
if user in game["user hands"]:
|
if user in game["user hands"]:
|
||||||
hand, handNumber = self.getHandNumber(game["user hands"][user],handNumber)
|
hand, handNumber = self.getHandNumber(game["user hands"][user],handNumber)
|
||||||
|
|
||||||
if hand != None:
|
if hand == None:
|
||||||
if game["round"] > 0:
|
logMessage = "They didn't specify a hand"
|
||||||
if hand["hit"] == False:
|
sendMessage = "You need to specify a hand"
|
||||||
if hand["standing"] == False:
|
elif game["round"] <= 0:
|
||||||
if len(hand["hand"]) == 2:
|
logMessage = "They tried to hit on the 0th round"
|
||||||
bet = hand["bet"]
|
sendMessage = "You can't hit before you see your cards"
|
||||||
if self.bot.money.checkBalance(user) >= bet:
|
elif hand["hit"]:
|
||||||
self.bot.money.addMoney(user,-1 * bet)
|
logMessage = "They've already hit this round"
|
||||||
|
sendMessage = "You've already hit this round"
|
||||||
hand["hand"].append(self.drawCard(channel))
|
elif hand["standing"]:
|
||||||
hand["hit"] = True
|
logMessage = "They're already standing"
|
||||||
hand["doubled"] = True
|
sendMessage = "You can't hit when you're standing"
|
||||||
hand["bet"] += bet
|
elif len(hand["hand"]) != 2:
|
||||||
|
logMessage = "They tried to double after round 1"
|
||||||
handValue = self.calcHandValue(hand["hand"])
|
sendMessage = "You can only double on the first round"
|
||||||
|
|
||||||
|
|
||||||
if handValue > 21:
|
|
||||||
hand["busted"] = True
|
|
||||||
|
|
||||||
if handNumber == 2:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".other hand":hand}})
|
|
||||||
elif handNumber == 3:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".third hand":hand}})
|
|
||||||
elif handNumber == 4:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".fourth hand":hand}})
|
|
||||||
else:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user:hand}})
|
|
||||||
|
|
||||||
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
|
|
||||||
|
|
||||||
return "Adding another "+str(bet)+" GwendoBucks to "+self.bot.databaseFuncs.getName(user)+"'s bet and drawing another card.",str(roundDone)[0] + str(game["round"])
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" doesn't have enough GwendoBucks")
|
|
||||||
return "You don't have enough GwendoBucks",""
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to double on round "+str(game["round"]))
|
|
||||||
return "You can only double down on the first round",""
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" is already standing")
|
|
||||||
return "You can't double when you're standing",""
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" has already hit this round")
|
|
||||||
return "You've already hit this round",""
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to double on the 0th round")
|
|
||||||
return "You can't double down before you see your cards",""
|
|
||||||
else:
|
else:
|
||||||
self.bot.log(user+" didn't specify a hand")
|
bet = hand["bet"]
|
||||||
return "You need to specify which hand"
|
if self.bot.money.checkBalance(user) < bet:
|
||||||
|
logMessage = "They tried to double without being in the game"
|
||||||
|
sendMessage = "You can't double when you're not in the game"
|
||||||
|
else:
|
||||||
|
self.bot.money.addMoney(user,-1 * bet)
|
||||||
|
|
||||||
|
hand["hand"].append(self.drawCard(channel))
|
||||||
|
hand["hit"] = True
|
||||||
|
hand["doubled"] = True
|
||||||
|
hand["bet"] += bet
|
||||||
|
|
||||||
|
handValue = self.calcHandValue(hand["hand"])
|
||||||
|
|
||||||
|
|
||||||
|
if handValue > 21:
|
||||||
|
hand["busted"] = True
|
||||||
|
|
||||||
|
if handNumber == 2:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".other hand":hand}})
|
||||||
|
elif handNumber == 3:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".third hand":hand}})
|
||||||
|
elif handNumber == 4:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".fourth hand":hand}})
|
||||||
|
else:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user:hand}})
|
||||||
|
|
||||||
|
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
|
||||||
|
|
||||||
|
sendMessage = f"Adding another {bet} GwendoBucks to {self.bot.databaseFuncs.getName(user)}'s bet and drawing another card."
|
||||||
|
logMessage = "They succeeded"
|
||||||
else:
|
else:
|
||||||
self.bot.log(user+" tried to double without being in the game")
|
logMessage = "They tried to double without being in the game"
|
||||||
return "You can't double when you're not in the game",""
|
sendMessage = "You can't double when you're not in the game"
|
||||||
|
|
||||||
|
await ctx.send(sendMessage)
|
||||||
|
self.bot.log(logMessage)
|
||||||
|
|
||||||
|
if roundDone:
|
||||||
|
gameID = game["gameID"]
|
||||||
|
self.bot.log("Double calling self.blackjackLoop()", channel)
|
||||||
|
await self.blackjackLoop(ctx.channel, game["round"]+1, gameID)
|
||||||
|
|
||||||
# When players try to stand
|
# When players try to stand
|
||||||
def blackjackStand(self,channel,user,handNumber = 0):
|
async def stand(self, ctx, handNumber = 0):
|
||||||
|
try:
|
||||||
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("Defer failed")
|
||||||
|
channel = str(ctx.channel_id)
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
roundDone = False
|
||||||
|
|
||||||
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
||||||
|
|
||||||
if user in game["user hands"]:
|
if user in game["user hands"]:
|
||||||
|
|
||||||
hand, handNumber = self.getHandNumber(game["user hands"][user],handNumber)
|
hand, handNumber = self.getHandNumber(game["user hands"][user],handNumber)
|
||||||
|
|
||||||
if hand != None:
|
if hand == None:
|
||||||
if game["round"] > 0:
|
sendMessage = "You need to specify which hand"
|
||||||
if hand["hit"] == False:
|
logMessage = "They didn't specify a hand"
|
||||||
if hand["standing"] == False:
|
elif game["round"] <= 0:
|
||||||
hand["standing"] = True
|
sendMessage = "You can't stand before you see your cards"
|
||||||
|
logMessage = "They tried to stand on round 0"
|
||||||
if handNumber == 2:
|
elif hand["hit"]:
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
sendMessage = "You've already hit this round"
|
||||||
{"$set":{"user hands."+user+".other hand":hand}})
|
logMessage = "They'd already hit this round"
|
||||||
elif handNumber == 3:
|
elif hand["standing"]:
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
sendMessage = "You're already standing"
|
||||||
{"$set":{"user hands."+user+".third hand":hand}})
|
logMessage = "They're already standing"
|
||||||
elif handNumber == 4:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".fourth hand":hand}})
|
|
||||||
else:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user:hand}})
|
|
||||||
|
|
||||||
response = "accept"
|
|
||||||
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
|
|
||||||
|
|
||||||
return response + str(roundDone)[0] + str(game["round"])
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" is already standing")
|
|
||||||
return "You're already standing"
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" has already hit this round")
|
|
||||||
return "You've already hit this round"
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to stand on the first round")
|
|
||||||
return "You can't stand before you see your cards"
|
|
||||||
else:
|
else:
|
||||||
self.bot.log(user+" didn't specify a hand")
|
hand["standing"] = True
|
||||||
return "You need to specify which hand"
|
|
||||||
|
if handNumber == 2:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".other hand":hand}})
|
||||||
|
elif handNumber == 3:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".third hand":hand}})
|
||||||
|
elif handNumber == 4:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".fourth hand":hand}})
|
||||||
|
else:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user:hand}})
|
||||||
|
|
||||||
|
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
|
||||||
|
|
||||||
|
sendMessage = f"{ctx.author.display_name} is standing"
|
||||||
|
logMessage = "They succeeded"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.bot.log(user+" tried to stand without being in the game")
|
logMessage = "They tried to stand without being in the game"
|
||||||
return "You have to enter the game before you can stand"
|
sendMessage = "You have to enter the game before you can stand"
|
||||||
|
|
||||||
|
await ctx.send(sendMessage)
|
||||||
|
self.bot.log(logMessage)
|
||||||
|
|
||||||
|
if roundDone:
|
||||||
|
gameID = game["gameID"]
|
||||||
|
self.bot.log("Stand calling self.blackjackLoop()", channel)
|
||||||
|
await self.blackjackLoop(ctx.channel, game["round"]+1, gameID)
|
||||||
|
|
||||||
# When players try to split
|
# When players try to split
|
||||||
def blackjackSplit(self,channel,user,handNumber = 0):
|
async def split(self, ctx, handNumber = 0):
|
||||||
|
try:
|
||||||
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("Defer failed")
|
||||||
|
channel = str(ctx.channel_id)
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
roundDone = False
|
||||||
|
handNumberError = False
|
||||||
|
|
||||||
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
||||||
|
|
||||||
if game["user hands"][user]["split"] == 0:
|
if game["user hands"][user]["split"] == 0:
|
||||||
@ -347,166 +395,200 @@ class Blackjack():
|
|||||||
handNumber = 0
|
handNumber = 0
|
||||||
otherHand = 2
|
otherHand = 2
|
||||||
else:
|
else:
|
||||||
if handNumber != 0:
|
if handNumber == 1:
|
||||||
if handNumber == 1:
|
hand = game["user hands"][user]
|
||||||
hand = game["user hands"][user]
|
elif handNumber == 2:
|
||||||
elif handNumber == 2:
|
hand = game["user hands"][user]["other hand"]
|
||||||
hand = game["user hands"][user]["other hand"]
|
elif handNumber == 3:
|
||||||
elif handNumber == 3:
|
hand = game["user hands"][user]["third hand"]
|
||||||
hand = game["user hands"][user]["third hand"]
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to hit without specifying which hand")
|
|
||||||
return "You have to specify the hand you're hitting with."
|
|
||||||
|
|
||||||
if game["user hands"][user]["split"] == 1:
|
|
||||||
newHand = game["user hands"][user]["third hand"]
|
|
||||||
otherHand = 3
|
|
||||||
else:
|
|
||||||
newHand = game["user hands"][user]["fourth hand"]
|
|
||||||
otherHand = 4
|
|
||||||
else:
|
else:
|
||||||
self.bot.log(user+" tried to split without specifying which hand")
|
handNumberError = True
|
||||||
return "You have to specify the hand you're splitting.",""
|
|
||||||
|
|
||||||
if game["user hands"][user]["split"] < 3:
|
if game["user hands"][user]["split"] == 1:
|
||||||
if game["round"] != 0:
|
newHand = game["user hands"][user]["third hand"]
|
||||||
if hand["hit"] == False:
|
otherHand = 3
|
||||||
if hand["standing"] == False:
|
|
||||||
if len(hand["hand"]) == 2:
|
|
||||||
firstCard = self.calcHandValue([hand["hand"][0]])
|
|
||||||
secondCard = self.calcHandValue([hand["hand"][1]])
|
|
||||||
if firstCard == secondCard:
|
|
||||||
bet = hand["bet"]
|
|
||||||
if self.bot.money.checkBalance(user) >= bet:
|
|
||||||
self.bot.money.addMoney(user,-1 * bet)
|
|
||||||
|
|
||||||
hand["hit"] = True
|
|
||||||
newHand["hit"] = True
|
|
||||||
|
|
||||||
newHand = {
|
|
||||||
"hand":[],"bet":0,"standing":False,"busted":False,
|
|
||||||
"blackjack":False,"hit":True,"doubled":False}
|
|
||||||
|
|
||||||
newHand["bet"] = hand["bet"]
|
|
||||||
|
|
||||||
newHand["hand"].append(hand["hand"].pop(1))
|
|
||||||
newHand["hand"].append(self.drawCard(channel))
|
|
||||||
hand["hand"].append(self.drawCard(channel))
|
|
||||||
|
|
||||||
handValue = self.calcHandValue(hand["hand"])
|
|
||||||
otherHandValue = self.calcHandValue(newHand["hand"])
|
|
||||||
if handValue > 21:
|
|
||||||
hand["busted"] = True
|
|
||||||
elif handValue == 21:
|
|
||||||
hand["blackjack"] = True
|
|
||||||
|
|
||||||
if otherHandValue > 21:
|
|
||||||
newHand["busted"] = True
|
|
||||||
elif otherHandValue == 21:
|
|
||||||
newHand["blackjack"] = True
|
|
||||||
|
|
||||||
if handNumber == 2:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".other hand":hand}})
|
|
||||||
elif handNumber == 3:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".third hand":hand}})
|
|
||||||
else:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user:hand}})
|
|
||||||
|
|
||||||
if otherHand == 3:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".third hand":newHand}})
|
|
||||||
elif otherHand == 4:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".fourth hand":newHand}})
|
|
||||||
else:
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user+".other hand":newHand}})
|
|
||||||
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$inc":{"user hands."+user+".split":1}})
|
|
||||||
|
|
||||||
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
|
|
||||||
|
|
||||||
return "Splitting "+self.bot.databaseFuncs.getName(user)+"'s hand into 2. Adding their original bet to the second hand. You can use \"/blackjack hit/stand/double 1\" and \"/blackjack hit/stand/double 2\" to play the different hands.",str(roundDone)[0] + str(game["round"])
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" doesn't have enough GwendoBucks")
|
|
||||||
return "You don't have enough GwendoBucks",""
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to split 2 different cards")
|
|
||||||
return "Your cards need to have the same value to split",""
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to split later than they could")
|
|
||||||
return "You can only split on the first round",""
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" is already standing")
|
|
||||||
return "You can't split when you're standing",""
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" has already hit this round")
|
|
||||||
return "You've already hit this round",""
|
|
||||||
else:
|
else:
|
||||||
self.bot.log(user+" tried to split on the 0th round")
|
newHand = game["user hands"][user]["fourth hand"]
|
||||||
return "You can't split before you see your cards",""
|
otherHand = 4
|
||||||
|
|
||||||
|
if handNumberError:
|
||||||
|
logMessage = "They didn't specify a hand"
|
||||||
|
sendMessage = "You have to specify the hand you're hitting with"
|
||||||
|
elif game["round"] == 0:
|
||||||
|
logMessage = "They tried to split on round 0"
|
||||||
|
sendMessage = "You can't split before you see your cards"
|
||||||
|
elif game["user hands"][user]["split"] > 3:
|
||||||
|
logMessage = "They tried to split more than three times"
|
||||||
|
sendMessage = "You can only split 3 times"
|
||||||
|
elif hand["hit"]:
|
||||||
|
logMessage = "They've already hit"
|
||||||
|
sendMessage = "You've already hit"
|
||||||
|
elif hand["standing"]:
|
||||||
|
logMessage = "They're already standing"
|
||||||
|
sendMessage = "You're already standing"
|
||||||
|
elif len(hand["hand"]) != 2:
|
||||||
|
logMessage = "They tried to split after the first round"
|
||||||
|
sendMessage = "You can only split on the first round"
|
||||||
else:
|
else:
|
||||||
self.bot.log(user+" tried to split more than three times")
|
firstCard = self.calcHandValue([hand["hand"][0]])
|
||||||
return "You can only split 3 times",""
|
secondCard = self.calcHandValue([hand["hand"][1]])
|
||||||
|
if firstCard != secondCard:
|
||||||
|
logMessage = "They tried to split two different cards"
|
||||||
|
sendMessage = "You can only split if your cards have the same value"
|
||||||
|
else:
|
||||||
|
bet = hand["bet"]
|
||||||
|
if self.bot.money.checkBalance(user) < bet:
|
||||||
|
logMessage = "They didn't have enough GwendoBucks"
|
||||||
|
sendMessage = "You don't have enough GwendoBucks"
|
||||||
|
else:
|
||||||
|
self.bot.money.addMoney(user,-1 * bet)
|
||||||
|
|
||||||
|
hand["hit"] = True
|
||||||
|
newHand["hit"] = True
|
||||||
|
|
||||||
|
newHand = {
|
||||||
|
"hand":[],"bet":0,"standing":False,"busted":False,
|
||||||
|
"blackjack":False,"hit":True,"doubled":False}
|
||||||
|
|
||||||
|
newHand["bet"] = hand["bet"]
|
||||||
|
|
||||||
|
newHand["hand"].append(hand["hand"].pop(1))
|
||||||
|
newHand["hand"].append(self.drawCard(channel))
|
||||||
|
hand["hand"].append(self.drawCard(channel))
|
||||||
|
|
||||||
|
handValue = self.calcHandValue(hand["hand"])
|
||||||
|
otherHandValue = self.calcHandValue(newHand["hand"])
|
||||||
|
if handValue > 21:
|
||||||
|
hand["busted"] = True
|
||||||
|
elif handValue == 21:
|
||||||
|
hand["blackjack"] = True
|
||||||
|
|
||||||
|
if otherHandValue > 21:
|
||||||
|
newHand["busted"] = True
|
||||||
|
elif otherHandValue == 21:
|
||||||
|
newHand["blackjack"] = True
|
||||||
|
|
||||||
|
if handNumber == 2:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".other hand":hand}})
|
||||||
|
elif handNumber == 3:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".third hand":hand}})
|
||||||
|
else:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user:hand}})
|
||||||
|
|
||||||
|
if otherHand == 3:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".third hand":newHand}})
|
||||||
|
elif otherHand == 4:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".fourth hand":newHand}})
|
||||||
|
else:
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"user hands."+user+".other hand":newHand}})
|
||||||
|
|
||||||
|
self.bot.database["blackjack games"].update_one({"_id":channel},
|
||||||
|
{"$inc":{"user hands."+user+".split":1}})
|
||||||
|
|
||||||
|
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
|
||||||
|
|
||||||
|
sendMessage = f"Splitting {self.bot.databaseFuncs.getName(user)}'s hand into 2. Adding their original bet to the second hand. You can use \"/blackjack hit/stand/double 1\" and \"/blackjack hit/stand/double 2\" to play the different hands."
|
||||||
|
logMessage = "They succeeded"
|
||||||
|
|
||||||
|
await ctx.send(sendMessage)
|
||||||
|
self.bot.log(logMessage)
|
||||||
|
|
||||||
|
if roundDone:
|
||||||
|
gameID = game["gameID"]
|
||||||
|
self.bot.log("Stand calling self.blackjackLoop()", channel)
|
||||||
|
await self.blackjackLoop(ctx.channel, game["round"]+1, gameID)
|
||||||
|
|
||||||
# Player enters the game and draws a hand
|
# Player enters the game and draws a hand
|
||||||
def blackjackPlayerDrawHand(self,channel,user,bet):
|
async def playerDrawHand(self, ctx, bet : int):
|
||||||
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
try:
|
||||||
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("Defer failed")
|
||||||
|
channel = str(ctx.channel_id)
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
collection = self.bot.database["blackjack games"]
|
||||||
|
game = collection.find_one({"_id":channel})
|
||||||
|
userName = self.bot.databaseFuncs.getName(user)
|
||||||
|
|
||||||
self.bot.log(self.bot.databaseFuncs.getName(user)+" is trying to join the game in "+channel)
|
self.bot.log(f"{userName} is trying to join the Blackjack game")
|
||||||
|
|
||||||
if game != None:
|
if game == None:
|
||||||
if user not in game["user hands"]:
|
sendMessage = "There is no game going on in this channel"
|
||||||
if len(game["user hands"]) < 5:
|
logMessage = sendMessage
|
||||||
if game["round"] == 0:
|
elif user in game["user hands"]:
|
||||||
if bet >= 0:
|
sendMessage = "You're already in the game!"
|
||||||
if self.bot.money.checkBalance(user) >= bet:
|
logMessage = "They're already in the game"
|
||||||
self.bot.money.addMoney(user,-1 * bet)
|
elif len(game["user hands"]) >= 5:
|
||||||
playerHand = [self.drawCard(channel),self.drawCard(channel)]
|
sendMessage = "There can't be more than 5 players in a game"
|
||||||
|
logMessage = "There were already 5 players in the game"
|
||||||
handValue = self.calcHandValue(playerHand)
|
elif game["round"] != 0:
|
||||||
|
sendMessage = "The table is no longer taking bets"
|
||||||
if handValue == 21:
|
logMessage = "They tried to join after the game begun"
|
||||||
blackjackHand = True
|
elif bet < 0:
|
||||||
else:
|
sendMessage = "You can't bet a negative amount"
|
||||||
blackjackHand = False
|
logMessage = "They tried to bet a negative amount"
|
||||||
|
elif self.bot.money.checkBalance(user) < bet:
|
||||||
newHand = {"hand":playerHand,
|
sendMessage = "You don't have enough GwendoBucks"
|
||||||
"bet":bet,"standing":False,"busted":False,"blackjack":blackjackHand,"hit":True,
|
logMessage = "They didn't have enough GwendoBucks"
|
||||||
"doubled":False,"split":0,"other hand":{},"third hand":{},"fourth hand":{}}
|
|
||||||
self.bot.database["blackjack games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"user hands."+user:newHand}})
|
|
||||||
|
|
||||||
self.bot.log(f"{self.bot.databaseFuncs.getName(user)} entered the game with a bet of {bet}")
|
|
||||||
return f"{self.bot.databaseFuncs.getName(user)} entered the game with a bet of {bet}"
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" doesn't have enough GwendoBucks")
|
|
||||||
return "You don't have enough GwendoBucks to place that bet"
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" tried to bet a negative amount")
|
|
||||||
return "You can't bet a negative amount"
|
|
||||||
else:
|
|
||||||
self.bot.log("The table is no longer open for bets")
|
|
||||||
return "The table is no longer open for bets"
|
|
||||||
else:
|
|
||||||
self.bot.log("There are already 5 players in the game.")
|
|
||||||
return "There's already a maximum of players at the table."
|
|
||||||
else:
|
|
||||||
self.bot.log(user+" is already in the game")
|
|
||||||
return "You've already entered this game"
|
|
||||||
else:
|
else:
|
||||||
self.bot.log("There is no game going on in "+channel)
|
self.bot.money.addMoney(user,-1 * bet)
|
||||||
return "There is no game going on in this channel"
|
playerHand = [self.drawCard(channel) for _ in range(2)]
|
||||||
|
|
||||||
|
handValue = self.calcHandValue(playerHand)
|
||||||
|
|
||||||
|
if handValue == 21:
|
||||||
|
blackjackHand = True
|
||||||
|
else:
|
||||||
|
blackjackHand = False
|
||||||
|
|
||||||
|
newHand = {"hand":playerHand, "bet":bet, "standing":False,
|
||||||
|
"busted":False, "blackjack":blackjackHand, "hit":True,
|
||||||
|
"doubled":False, "split":0, "other hand":{},
|
||||||
|
"third hand":{}, "fourth hand":{}}
|
||||||
|
|
||||||
|
function = {"$set":{f"user hands.{user}":newHand}}
|
||||||
|
collection.update_one({"_id":channel}, function)
|
||||||
|
|
||||||
|
enterGameText = "entered the game with a bet of"
|
||||||
|
betText = f"{bet} GwendoBucks"
|
||||||
|
sendMessage = f"{userName} {enterGameText} {betText}"
|
||||||
|
logMessage = sendMessage
|
||||||
|
|
||||||
|
self.bot.log(sendMessage)
|
||||||
|
await ctx.send(logMessage)
|
||||||
|
|
||||||
# Starts a game of blackjack
|
# Starts a game of blackjack
|
||||||
def blackjackStart(self,channel:str):
|
async def start(self, ctx):
|
||||||
|
try:
|
||||||
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("Defer failed")
|
||||||
|
channel = str(ctx.channel_id)
|
||||||
|
blackjackMinCards = 50
|
||||||
|
blackjackDecks = 4
|
||||||
|
|
||||||
|
await ctx.send("Starting a new game of blackjack")
|
||||||
|
cardsLeft = 0
|
||||||
|
cards = self.bot.database["blackjack cards"].find_one({"_id":channel})
|
||||||
|
if cards != None:
|
||||||
|
cardsLeft = len(cards["cards"])
|
||||||
|
|
||||||
|
# Shuffles if not enough cards
|
||||||
|
if cardsLeft < blackjackMinCards:
|
||||||
|
self.blackjackShuffle(blackjackDecks, channel)
|
||||||
|
self.bot.log("Shuffling the blackjack deck...", channel)
|
||||||
|
await ctx.channel.send("Shuffling the deck...")
|
||||||
|
|
||||||
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
||||||
|
|
||||||
self.bot.log("Trying to start a blackjack game in "+channel)
|
self.bot.log("Trying to start a blackjack game in "+channel)
|
||||||
|
gameStarted = False
|
||||||
|
|
||||||
if game == None:
|
if game == None:
|
||||||
|
|
||||||
@ -522,10 +604,39 @@ class Blackjack():
|
|||||||
|
|
||||||
copyfile("resources/games/blackjackTable.png","resources/games/blackjackTables/blackjackTable"+channel+".png")
|
copyfile("resources/games/blackjackTable.png","resources/games/blackjackTables/blackjackTable"+channel+".png")
|
||||||
|
|
||||||
return "started"
|
gameStarted = True
|
||||||
|
|
||||||
|
if gameStarted:
|
||||||
|
sendMessage = "Blackjack game started. Use \"/blackjack bet [amount]\" to enter the game within the next 30 seconds."
|
||||||
|
await ctx.channel.send(sendMessage)
|
||||||
|
filePath = f"resources/games/blackjackTables/blackjackTable{channel}.png"
|
||||||
|
|
||||||
|
oldImage = await ctx.channel.send(file = discord.File(filePath))
|
||||||
|
|
||||||
|
with open("resources/games/oldImages/blackjack"+channel, "w") as f:
|
||||||
|
f.write(str(oldImage.id))
|
||||||
|
|
||||||
|
await asyncio.sleep(30)
|
||||||
|
|
||||||
|
gamedone = False
|
||||||
|
|
||||||
|
game = self.bot.database["blackjack games"].find_one({"_id":str(channel)})
|
||||||
|
|
||||||
|
if len(game["user hands"]) == 0:
|
||||||
|
gamedone = True
|
||||||
|
await ctx.channel.send("No one entered the game. Ending the game.")
|
||||||
|
gameID = game["gameID"]
|
||||||
|
|
||||||
|
# Loop of game rounds
|
||||||
|
if gamedone == False:
|
||||||
|
self.bot.log("start() calling blackjackLoop()", channel)
|
||||||
|
await self.blackjackLoop(ctx.channel,1,gameID)
|
||||||
|
else:
|
||||||
|
new_message = self.blackjackFinish(channel)
|
||||||
|
await ctx.channel.send(new_message)
|
||||||
else:
|
else:
|
||||||
self.bot.log("There is already a blackjack game going on in "+channel)
|
await ctx.channel.send("There's already a blackjack game going on. Try again in a few minutes.")
|
||||||
return "There's already a blackjack game going on. Try again in a few minutes."
|
self.bot.log("There was already a game going on")
|
||||||
|
|
||||||
# Ends the game and calculates winnings
|
# Ends the game and calculates winnings
|
||||||
def blackjackFinish(self,channel):
|
def blackjackFinish(self,channel):
|
||||||
@ -562,7 +673,6 @@ class Blackjack():
|
|||||||
|
|
||||||
return finalWinnings
|
return finalWinnings
|
||||||
|
|
||||||
|
|
||||||
def calcWinnings(self,hand, dealerValue, topLevel, dealerBlackjack, dealerBusted):
|
def calcWinnings(self,hand, dealerValue, topLevel, dealerBlackjack, dealerBusted):
|
||||||
self.bot.log("Calculating winnings")
|
self.bot.log("Calculating winnings")
|
||||||
reason = ""
|
reason = ""
|
||||||
@ -703,178 +813,34 @@ class Blackjack():
|
|||||||
else:
|
else:
|
||||||
self.bot.log("Ending loop on round "+str(gameRound),str(channel.id))
|
self.bot.log("Ending loop on round "+str(gameRound),str(channel.id))
|
||||||
|
|
||||||
async def parseBlackjack(self,content, ctx):
|
# Returning current hi-lo value
|
||||||
# Blackjack shuffle variables
|
async def hilo(self, ctx):
|
||||||
blackjackMinCards = 50
|
|
||||||
blackjackDecks = 4
|
|
||||||
|
|
||||||
channel = ctx.channel_id
|
channel = ctx.channel_id
|
||||||
# Starts the game
|
data = self.bot.database["hilo"].find_one({"_id":str(channel)})
|
||||||
if content == "":
|
if data != None:
|
||||||
await ctx.send("Starting a new game of blackjack")
|
hilo = str(data["hilo"])
|
||||||
cardsLeft = 0
|
|
||||||
cards = self.bot.database["blackjack cards"].find_one({"_id":str(channel)})
|
|
||||||
if cards != None:
|
|
||||||
cardsLeft = len(cards["cards"])
|
|
||||||
|
|
||||||
# Shuffles if not enough cards
|
|
||||||
if cardsLeft < blackjackMinCards:
|
|
||||||
self.blackjackShuffle(blackjackDecks,str(channel))
|
|
||||||
self.bot.log("Shuffling the blackjack deck...",str(channel))
|
|
||||||
await ctx.channel.send("Shuffling the deck...")
|
|
||||||
|
|
||||||
new_message = self.blackjackStart(str(channel))
|
|
||||||
if new_message == "started":
|
|
||||||
|
|
||||||
new_message = "Blackjack game started. Use \"/blackjack bet [amount]\" to enter the game within the next 30 seconds."
|
|
||||||
await ctx.channel.send(new_message)
|
|
||||||
oldImage = await ctx.channel.send(file = discord.File("resources/games/blackjackTables/blackjackTable"+str(channel)+".png"))
|
|
||||||
|
|
||||||
with open("resources/games/oldImages/blackjack"+str(channel), "w") as f:
|
|
||||||
f.write(str(oldImage.id))
|
|
||||||
|
|
||||||
await asyncio.sleep(30)
|
|
||||||
|
|
||||||
gamedone = False
|
|
||||||
|
|
||||||
game = self.bot.database["blackjack games"].find_one({"_id":str(channel)})
|
|
||||||
|
|
||||||
if len(game["user hands"]) == 0:
|
|
||||||
gamedone = True
|
|
||||||
await ctx.channel.send("No one entered the game. Ending the game.")
|
|
||||||
gameID = game["gameID"]
|
|
||||||
|
|
||||||
# Loop of game rounds
|
|
||||||
if gamedone == False:
|
|
||||||
self.bot.log("/blackjack calling self.blackjackLoop()",str(channel))
|
|
||||||
await self.blackjackLoop(ctx.channel,1,gameID)
|
|
||||||
else:
|
|
||||||
new_message = self.blackjackFinish(str(channel))
|
|
||||||
await ctx.channel.send(new_message)
|
|
||||||
else:
|
|
||||||
await ctx.channel.send(new_message)
|
|
||||||
|
|
||||||
# Entering game and placing bet
|
|
||||||
elif content.startswith("bet"):
|
|
||||||
commands = content.split(" ")
|
|
||||||
amount = int(commands[1])
|
|
||||||
response = self.blackjackPlayerDrawHand(str(channel),"#"+str(ctx.author.id),amount)
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
# Hitting
|
|
||||||
elif content.startswith("hit"):
|
|
||||||
if content == "hit":
|
|
||||||
response = self.blackjackHit(str(channel),"#"+str(ctx.author.id))
|
|
||||||
else:
|
|
||||||
commands = content.split(" ")
|
|
||||||
try:
|
|
||||||
handNumber = int(commands[1])
|
|
||||||
except:
|
|
||||||
handNumber = 0
|
|
||||||
response = self.blackjackHit(str(channel),"#"+str(ctx.author.id),handNumber)
|
|
||||||
|
|
||||||
if response.startswith("accept"):
|
|
||||||
await ctx.send(f"{ctx.author.display_name} hit")
|
|
||||||
#try:
|
|
||||||
if response[6] == "T":
|
|
||||||
gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"]
|
|
||||||
self.bot.log("Hit calling self.blackjackLoop()",str(channel))
|
|
||||||
await self.blackjackLoop(ctx.channel,int(response[7:])+1,gameID)
|
|
||||||
#except:
|
|
||||||
# self.bot.log("Something fucked up (error code 1320)",str(channel))
|
|
||||||
else:
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
|
|
||||||
# Standing
|
|
||||||
elif content.startswith("stand"):
|
|
||||||
if content == "hit":
|
|
||||||
response = self.blackjackStand(str(channel),"#"+str(ctx.author.id))
|
|
||||||
else:
|
|
||||||
commands = content.split(" ")
|
|
||||||
try:
|
|
||||||
handNumber = int(commands[1])
|
|
||||||
except:
|
|
||||||
handNumber = 0
|
|
||||||
response = self.blackjackStand(str(channel),"#"+str(ctx.author.id),handNumber)
|
|
||||||
|
|
||||||
if response.startswith("accept"):
|
|
||||||
await ctx.send(f"{ctx.author.display_name} is standing")
|
|
||||||
#try:
|
|
||||||
if response[6] == "T":
|
|
||||||
gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"]
|
|
||||||
self.bot.log("Stand calling self.blackjackLoop()",str(channel))
|
|
||||||
await self.blackjackLoop(ctx.channel,int(response[7:])+1,gameID)
|
|
||||||
#except:
|
|
||||||
# self.bot.log("Something fucked up (error code 1320)",str(channel))
|
|
||||||
else:
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
# Doubling bet
|
|
||||||
elif content.startswith("double"):
|
|
||||||
commands = content.split(" ")
|
|
||||||
try:
|
|
||||||
handNumber = int(commands[1])
|
|
||||||
except:
|
|
||||||
handNumber = 0
|
|
||||||
response, roundDone = self.blackjackDouble(str(channel),"#"+str(ctx.author.id),handNumber)
|
|
||||||
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
try:
|
|
||||||
if roundDone[0] == "T":
|
|
||||||
gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"]
|
|
||||||
self.bot.log("Double calling self.blackjackLoop()",str(channel))
|
|
||||||
await self.blackjackLoop(ctx.channel,int(roundDone[1:])+1,gameID)
|
|
||||||
except:
|
|
||||||
self.bot.log("Something fucked up (error code 1320)",str(channel))
|
|
||||||
|
|
||||||
# Splitting hand
|
|
||||||
elif content.startswith("split"):
|
|
||||||
commands = content.split(" ")
|
|
||||||
try:
|
|
||||||
handNumber = int(commands[1])
|
|
||||||
except:
|
|
||||||
handNumber = 0
|
|
||||||
response, roundDone = self.blackjackSplit(str(channel),"#"+str(ctx.author.id),handNumber)
|
|
||||||
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
try:
|
|
||||||
if roundDone[0] == "T":
|
|
||||||
gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"]
|
|
||||||
self.bot.log("Split calling self.blackjackLoop()",str(channel))
|
|
||||||
await self.blackjackLoop(ctx.channel,int(roundDone[1:])+1,gameID)
|
|
||||||
except:
|
|
||||||
self.bot.log("Something fucked up (error code 1320)")
|
|
||||||
|
|
||||||
# Returning current hi-lo value
|
|
||||||
elif content.startswith("hilo"):
|
|
||||||
data = self.bot.database["hilo"].find_one({"_id":str(channel)})
|
|
||||||
if data != None:
|
|
||||||
hilo = str(data["hilo"])
|
|
||||||
else:
|
|
||||||
hilo = "0"
|
|
||||||
await ctx.send(hilo, hidden=True)
|
|
||||||
|
|
||||||
# Shuffles the blackjack deck
|
|
||||||
elif content.startswith("shuffle"):
|
|
||||||
self.blackjackShuffle(blackjackDecks,str(channel))
|
|
||||||
self.bot.log("Shuffling the blackjack deck...",str(channel))
|
|
||||||
await ctx.send("Shuffling the deck...")
|
|
||||||
|
|
||||||
|
|
||||||
# Tells you the amount of cards left
|
|
||||||
elif content.startswith("cards"):
|
|
||||||
cardsLeft = 0
|
|
||||||
cards = self.bot.database["blackjack cards"].find_one({"_id":str(channel)})
|
|
||||||
if cards != None:
|
|
||||||
cardsLeft = len(cards["cards"])
|
|
||||||
|
|
||||||
decksLeft = round(cardsLeft/52,1)
|
|
||||||
await ctx.send(str(cardsLeft)+" cards, "+str(decksLeft)+" decks", hidden=True)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.bot.log("Not a command (error code 1301)")
|
hilo = "0"
|
||||||
await ctx.send("I didn't quite understand that (error code 1301)")
|
await ctx.send(f"Hi-lo value: {hilo}", hidden=True)
|
||||||
|
|
||||||
|
# Shuffles the blackjack deck
|
||||||
|
async def shuffle(self, ctx):
|
||||||
|
blackjackDecks = 4
|
||||||
|
channel = ctx.channel_id
|
||||||
|
self.blackjackShuffle(blackjackDecks,str(channel))
|
||||||
|
self.bot.log("Shuffling the blackjack deck...",str(channel))
|
||||||
|
await ctx.send("Shuffling the deck...")
|
||||||
|
|
||||||
|
|
||||||
|
# Tells you the amount of cards left
|
||||||
|
async def cards(self, ctx):
|
||||||
|
channel = ctx.channel_id
|
||||||
|
cardsLeft = 0
|
||||||
|
cards = self.bot.database["blackjack cards"].find_one({"_id":str(channel)})
|
||||||
|
if cards != None:
|
||||||
|
cardsLeft = len(cards["cards"])
|
||||||
|
|
||||||
|
decksLeft = round(cardsLeft/52,1)
|
||||||
|
await ctx.send(f"Cards left:\n{cardsLeft} cards, {decksLeft} decks", hidden=True)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import random
|
import random
|
||||||
import copy
|
import copy
|
||||||
import math
|
import math
|
||||||
|
import discord
|
||||||
|
|
||||||
from .connectFourDraw import drawConnectFour
|
from .connectFourDraw import drawConnectFour
|
||||||
|
|
||||||
AIScores = {
|
AISCORES = {
|
||||||
"middle": 3,
|
"middle": 3,
|
||||||
"two in a row": 10,
|
"two in a row": 10,
|
||||||
"three in a row": 50,
|
"three in a row": 50,
|
||||||
@ -15,75 +16,127 @@ AIScores = {
|
|||||||
"avoid losing": 100
|
"avoid losing": 100
|
||||||
}
|
}
|
||||||
|
|
||||||
rowCount = 6
|
ROWCOUNT = 6
|
||||||
columnCount = 7
|
COLUMNCOUNT = 7
|
||||||
easy = True
|
|
||||||
|
|
||||||
class connectFour():
|
class ConnectFour():
|
||||||
def __init__(self,bot):
|
def __init__(self,bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.draw = drawConnectFour(bot)
|
self.draw = drawConnectFour(bot)
|
||||||
|
|
||||||
# Starts the game
|
# Starts the game
|
||||||
def connectFourStart(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["connect 4 games"].find_one({"_id":channel})
|
game = self.bot.database["connect 4 games"].find_one({"_id":channel})
|
||||||
|
|
||||||
if game == None:
|
startedGame = False
|
||||||
|
canStart = True
|
||||||
|
|
||||||
if opponent in ["1","2","3","4","5"]:
|
if game != None:
|
||||||
difficulty = int(opponent)
|
sendMessage = "There's already a connect 4 game going on in this channel"
|
||||||
diffText = " with difficulty "+opponent
|
logMessage = "There was already a game going on"
|
||||||
opponent = "Gwendolyn"
|
canStart = False
|
||||||
elif opponent.lower() == "gwendolyn":
|
else:
|
||||||
difficulty = 3
|
if type(opponent) == int:
|
||||||
diffText = " with difficulty 3"
|
# Opponent is Gwendolyn
|
||||||
opponent = "Gwendolyn"
|
if opponent in range(1, 6):
|
||||||
else:
|
difficulty = int(opponent)
|
||||||
try:
|
diffText = f" with difficulty {difficulty}"
|
||||||
int(opponent)
|
opponent = f"#{self.bot.user.id}"
|
||||||
return "That difficulty doesn't exist", False, False, False, False
|
else:
|
||||||
except:
|
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
|
||||||
|
difficulty = 3
|
||||||
|
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:
|
||||||
# Opponent is another player
|
# Opponent is another player
|
||||||
opponent = self.bot.databaseFuncs.getID(opponent)
|
if ctx.author != opponent:
|
||||||
if opponent != None:
|
opponent = f"#{opponent.id}"
|
||||||
difficulty = 5
|
difficulty = 5
|
||||||
diffText = ""
|
diffText = ""
|
||||||
else:
|
else:
|
||||||
return "I can't find that user", False, False, False, False
|
sendMessage = "You can't play against yourself"
|
||||||
|
logMessage = "They tried to play against themself"
|
||||||
|
canStart = False
|
||||||
|
|
||||||
if user == opponent:
|
if canStart:
|
||||||
return "You can't play against yourself", False, False, False, False
|
board = [[0 for _ in range(COLUMNCOUNT)] for _ in range(ROWCOUNT)]
|
||||||
|
players = [user, opponent]
|
||||||
board = [ [ 0 for i in range(columnCount) ] for j in range(rowCount) ]
|
|
||||||
players = [user,opponent]
|
|
||||||
random.shuffle(players)
|
random.shuffle(players)
|
||||||
|
|
||||||
newGame = {"_id":channel,"board": board,"winner":0,"win direction":"",
|
newGame = {"_id":channel, "board": board, "winner":0,
|
||||||
"win coordinates":[0,0],"players":players,"turn":0,"difficulty":difficulty}
|
"win direction":"", "win coordinates":[0, 0],
|
||||||
|
"players":players, "turn":0, "difficulty":difficulty}
|
||||||
|
|
||||||
self.bot.database["connect 4 games"].insert_one(newGame)
|
self.bot.database["connect 4 games"].insert_one(newGame)
|
||||||
|
|
||||||
self.draw.drawImage(channel)
|
self.draw.drawImage(channel)
|
||||||
|
|
||||||
gwendoTurn = False
|
gwendoTurn = (players[0] == f"#{self.bot.user.id}")
|
||||||
|
startedGame = True
|
||||||
|
|
||||||
if players[0] == "Gwendolyn":
|
opponentName = self.bot.databaseFuncs.getName(opponent)
|
||||||
gwendoTurn = True
|
turnName = self.bot.databaseFuncs.getName(players[0])
|
||||||
|
|
||||||
return "Started game against "+self.bot.databaseFuncs.getName(opponent)+diffText+". It's "+self.bot.databaseFuncs.getName(players[0])+"'s turn", True, False, False, gwendoTurn
|
startedText = f"Started game against {opponentName}{diffText}."
|
||||||
else:
|
turnText = f"It's {turnName}'s turn"
|
||||||
return "There's already a connect 4 game going on in this channel", False, False, False, False
|
sendMessage = f"{startedText} {turnText}"
|
||||||
|
logMessage = "They started a game"
|
||||||
|
|
||||||
|
self.bot.log(logMessage)
|
||||||
|
await ctx.send(sendMessage)
|
||||||
|
|
||||||
|
# Sets the whole game in motion
|
||||||
|
if startedGame:
|
||||||
|
filePath = f"resources/games/connect4Boards/board{ctx.channel_id}.png"
|
||||||
|
oldImage = await ctx.channel.send(file = discord.File(filePath))
|
||||||
|
|
||||||
|
with open(f"resources/games/oldImages/connectFour{ctx.channel_id}", "w") as f:
|
||||||
|
f.write(str(oldImage.id))
|
||||||
|
|
||||||
|
if gwendoTurn:
|
||||||
|
await self.connectFourAI(ctx)
|
||||||
|
else:
|
||||||
|
reactions = ["1️⃣","2️⃣","3️⃣","4️⃣","5️⃣","6️⃣","7️⃣"]
|
||||||
|
for reaction in reactions:
|
||||||
|
await oldImage.add_reaction(reaction)
|
||||||
|
|
||||||
# Places a piece at the lowest available point in a specific column
|
# Places a piece at the lowest available point in a specific column
|
||||||
def placePiece(self, channel : str,player : int,column : int):
|
async def placePiece(self, ctx, user, column):
|
||||||
|
channel = str(ctx.channel.id)
|
||||||
game = self.bot.database["connect 4 games"].find_one({"_id":channel})
|
game = self.bot.database["connect 4 games"].find_one({"_id":channel})
|
||||||
|
playerNumber = game["players"].index(user)+1
|
||||||
|
userName = self.bot.databaseFuncs.getName(user)
|
||||||
|
placedPiece = False
|
||||||
|
|
||||||
if game != None:
|
if game is None:
|
||||||
|
sendMessage = "There's no game in this channel"
|
||||||
|
logMessage = "There was no game in the channel"
|
||||||
|
else:
|
||||||
board = game["board"]
|
board = game["board"]
|
||||||
|
board = self.placeOnBoard(board, playerNumber, column)
|
||||||
|
|
||||||
board = self.placeOnBoard(board,player,column)
|
if board is None:
|
||||||
|
sendMessage = "There isn't any room in that column"
|
||||||
if board != None:
|
logMessage = "There wasn't any room in the column"
|
||||||
|
else:
|
||||||
self.bot.database["connect 4 games"].update_one({"_id":channel},{"$set":{"board":board}})
|
self.bot.database["connect 4 games"].update_one({"_id":channel},{"$set":{"board":board}})
|
||||||
turn = (game["turn"]+1)%2
|
turn = (game["turn"]+1)%2
|
||||||
self.bot.database["connect 4 games"].update_one({"_id":channel},{"$set":{"turn":turn}})
|
self.bot.database["connect 4 games"].update_one({"_id":channel},{"$set":{"turn":turn}})
|
||||||
@ -98,82 +151,115 @@ class connectFour():
|
|||||||
self.bot.database["connect 4 games"].update_one({"_id":channel},
|
self.bot.database["connect 4 games"].update_one({"_id":channel},
|
||||||
{"$set":{"win coordinates":winCoordinates}})
|
{"$set":{"win coordinates":winCoordinates}})
|
||||||
|
|
||||||
message = self.bot.databaseFuncs.getName(game["players"][won-1])+" placed a piece in column "+str(column+1)+" and won."
|
sendMessage = f"{userName} placed a piece in column {column+1} and won."
|
||||||
|
logMessage = f"{userName} won"
|
||||||
winAmount = int(game["difficulty"])**2+5
|
winAmount = int(game["difficulty"])**2+5
|
||||||
if game["players"][won-1] != "Gwendolyn":
|
if game["players"][won-1] != f"#{self.bot.user.id}":
|
||||||
message += " Adding "+str(winAmount)+" GwendoBucks to their account."
|
sendMessage += " Adding "+str(winAmount)+" GwendoBucks to their account"
|
||||||
elif 0 not in board[0]:
|
elif 0 not in board[0]:
|
||||||
gameWon = True
|
gameWon = True
|
||||||
message = "It's a draw!"
|
sendMessage = "It's a draw!"
|
||||||
|
logMessage = "The game ended in a draw"
|
||||||
else:
|
else:
|
||||||
gameWon = False
|
gameWon = False
|
||||||
message = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed a piece in column "+str(column+1)+". It's now "+self.bot.databaseFuncs.getName(game["players"][turn])+"'s turn."
|
otherUserName = self.bot.databaseFuncs.getName(game["players"][turn])
|
||||||
|
sendMessage = f"{userName} placed a piece in column {column+1}. It's now {otherUserName}'s turn"
|
||||||
|
logMessage = "They placed the piece"
|
||||||
|
|
||||||
gwendoTurn = False
|
gwendoTurn = (game["players"][turn] == f"#{self.bot.user.id}")
|
||||||
|
|
||||||
if game["players"][turn] == "Gwendolyn":
|
placedPiece = True
|
||||||
self.bot.log("It's Gwendolyn's turn")
|
|
||||||
gwendoTurn = True
|
|
||||||
|
|
||||||
self.draw.drawImage(channel)
|
await ctx.channel.send(sendMessage)
|
||||||
return message, True, True, gameWon, gwendoTurn
|
self.bot.log(logMessage)
|
||||||
|
|
||||||
|
if placedPiece:
|
||||||
|
self.draw.drawImage(channel)
|
||||||
|
|
||||||
|
with open(f"resources/games/oldImages/connectFour{channel}", "r") as f:
|
||||||
|
oldImage = await ctx.channel.fetch_message(int(f.read()))
|
||||||
|
|
||||||
|
if oldImage is not None:
|
||||||
|
await oldImage.delete()
|
||||||
else:
|
else:
|
||||||
return "There isn't any room in that column", True, True, False, False
|
self.bot.log("The old image was already deleted")
|
||||||
else:
|
|
||||||
return "There's no game in this channel", False, False, False, False
|
filePath = f"resources/games/connect4Boards/board{channel}.png"
|
||||||
|
oldImage = await ctx.channel.send(file = discord.File(filePath))
|
||||||
|
|
||||||
|
if gameWon:
|
||||||
|
self.endGame(channel)
|
||||||
|
else:
|
||||||
|
with open(f"resources/games/oldImages/connectFour{channel}", "w") as f:
|
||||||
|
f.write(str(oldImage.id))
|
||||||
|
if gwendoTurn:
|
||||||
|
await self.connectFourAI(ctx)
|
||||||
|
else:
|
||||||
|
reactions = ["1️⃣","2️⃣","3️⃣","4️⃣","5️⃣","6️⃣","7️⃣"]
|
||||||
|
for reaction in reactions:
|
||||||
|
await oldImage.add_reaction(reaction)
|
||||||
|
|
||||||
# Returns a board where a piece has been placed in the column
|
# Returns a board where a piece has been placed in the column
|
||||||
def placeOnBoard(self,board,player,column):
|
def placeOnBoard(self, board, player, column):
|
||||||
placementx, placementy = -1, column
|
placementX, placementY = -1, column
|
||||||
|
|
||||||
for x, line in enumerate(board):
|
for x, line in enumerate(board):
|
||||||
if line[column] == 0:
|
if line[column] == 0:
|
||||||
placementx = x
|
placementX = x
|
||||||
|
|
||||||
board[placementx][placementy] = player
|
board[placementX][placementY] = player
|
||||||
|
|
||||||
if placementx == -1:
|
if placementX == -1:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return board
|
return board
|
||||||
|
|
||||||
|
def endGame(self, channel):
|
||||||
|
game = self.bot.database["connect 4 games"].find_one({"_id":channel})
|
||||||
|
|
||||||
|
winner = game["winner"]
|
||||||
|
if winner != 0:
|
||||||
|
if game["players"][winner-1] != f"#{self.bot.user.id}":
|
||||||
|
difficulty = int(game["difficulty"])
|
||||||
|
reward = difficulty**2 + 5
|
||||||
|
self.bot.money.addMoney(game["players"][winner-1], reward)
|
||||||
|
|
||||||
|
self.bot.databaseFuncs.deleteGame("connect 4 games", channel)
|
||||||
|
|
||||||
# Parses command
|
# Parses command
|
||||||
def parseconnectFour(self, command, channel, user):
|
async def surrender(self, ctx):
|
||||||
commands = command.split()
|
try:
|
||||||
if command == "" or command == " ":
|
await ctx.defer()
|
||||||
return "I didn't get that. Use \"/connectFour start [opponent]\" to start a game. To play against the computer, use difficulty 1 through 5 as the [opponent].", False, False, False, False
|
except:
|
||||||
elif commands[0] == "start":
|
self.bot.log("Defer failed")
|
||||||
# Starting a game
|
channel = str(ctx.channel_id)
|
||||||
if len(commands) == 1: # if the commands is "/connectFour start", the opponent is Gwendolyn
|
game = self.bot.database["connect 4 games"].find_one({"_id":channel})
|
||||||
commands.append("3")
|
|
||||||
return self.connectFourStart(channel,user,commands[1]) # commands[1] is the opponent
|
|
||||||
|
|
||||||
# Stopping the game
|
if f"#{ctx.author.id}" in game["players"]:
|
||||||
elif commands[0] == "stop":
|
loserIndex = game["players"].index(f"#{ctx.author.id}")
|
||||||
game = self.bot.database["connect 4 games"].find_one({"_id":channel})
|
winnerIndex = (loserIndex+1)%2
|
||||||
|
winnerID = game["players"][winnerIndex]
|
||||||
|
winnerName = self.bot.databaseFuncs.getName(winnerID)
|
||||||
|
|
||||||
if user in game["players"]:
|
sendMessage = f"{ctx.author.display_name} surrenders."
|
||||||
return "Ending game.", False, False, True, False
|
sendMessage += f" This means {winnerName} is the winner."
|
||||||
|
if winnerID != f"#{self.bot.user.id}":
|
||||||
|
difficulty = int(game["difficulty"])
|
||||||
|
reward = difficulty**2 + 5
|
||||||
|
sendMessage += f" Adding {reward} to their account"
|
||||||
|
|
||||||
|
await ctx.send(sendMessage)
|
||||||
|
with open(f"resources/games/oldImages/connectFour{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 can't end a game where you're not a player.", False, False, False, False
|
self.bot.log("The old image was already deleted")
|
||||||
|
|
||||||
# Placing manually
|
self.endGame(channel)
|
||||||
elif commands[0] == "place":
|
|
||||||
if len(commands) == 2:
|
|
||||||
game = self.bot.database["connect 4 games"].find_one({"_id":channel})
|
|
||||||
turn = game["turn"]
|
|
||||||
if user == game["players"][turn]:
|
|
||||||
piece = turn + 1
|
|
||||||
else:
|
|
||||||
self.bot.log("It wasn't their turn")
|
|
||||||
return "It's not your turn!", False, False, False, False
|
|
||||||
column = int(commands[1])-1
|
|
||||||
else:
|
|
||||||
column = int(commands[2])-1
|
|
||||||
piece = int(commands[1])
|
|
||||||
return self.placePiece(channel, piece, column)
|
|
||||||
else:
|
else:
|
||||||
return "I didn't get that. Use \"/connectFour start [opponent]\" to start a game. To play against the computer, use difficulty 1 through 5 as the [opponent].", False, False, False, False
|
await ctx.send("You can't surrender when you're not a player")
|
||||||
|
|
||||||
# Checks if someone has won the game and returns the winner
|
# Checks if someone has won the game and returns the winner
|
||||||
def isWon(self, board):
|
def isWon(self, board):
|
||||||
@ -181,13 +267,13 @@ class connectFour():
|
|||||||
winDirection = ""
|
winDirection = ""
|
||||||
winCoordinates = [0,0]
|
winCoordinates = [0,0]
|
||||||
|
|
||||||
for row in range(rowCount):
|
for row in range(ROWCOUNT):
|
||||||
for place in range(columnCount):
|
for place in range(COLUMNCOUNT):
|
||||||
if won == 0:
|
if won == 0:
|
||||||
piecePlayer = board[row][place]
|
piecePlayer = board[row][place]
|
||||||
if piecePlayer != 0:
|
if piecePlayer != 0:
|
||||||
# Checks horizontal
|
# Checks horizontal
|
||||||
if place <= columnCount-4:
|
if place <= COLUMNCOUNT-4:
|
||||||
pieces = [board[row][place+1],board[row][place+2],board[row][place+3]]
|
pieces = [board[row][place+1],board[row][place+2],board[row][place+3]]
|
||||||
else:
|
else:
|
||||||
pieces = [0]
|
pieces = [0]
|
||||||
@ -198,7 +284,7 @@ class connectFour():
|
|||||||
winCoordinates = [row,place]
|
winCoordinates = [row,place]
|
||||||
|
|
||||||
# Checks vertical
|
# Checks vertical
|
||||||
if row <= rowCount-4:
|
if row <= ROWCOUNT-4:
|
||||||
pieces = [board[row+1][place],board[row+2][place],board[row+3][place]]
|
pieces = [board[row+1][place],board[row+2][place],board[row+3][place]]
|
||||||
else:
|
else:
|
||||||
pieces = [0]
|
pieces = [0]
|
||||||
@ -209,7 +295,7 @@ class connectFour():
|
|||||||
winCoordinates = [row,place]
|
winCoordinates = [row,place]
|
||||||
|
|
||||||
# Checks right diagonal
|
# Checks right diagonal
|
||||||
if row <= rowCount-4 and place <= columnCount-4:
|
if row <= ROWCOUNT-4 and place <= COLUMNCOUNT-4:
|
||||||
pieces = [board[row+1][place+1],board[row+2][place+2],board[row+3][place+3]]
|
pieces = [board[row+1][place+1],board[row+2][place+2],board[row+3][place+3]]
|
||||||
else:
|
else:
|
||||||
pieces = [0]
|
pieces = [0]
|
||||||
@ -220,7 +306,7 @@ class connectFour():
|
|||||||
winCoordinates = [row,place]
|
winCoordinates = [row,place]
|
||||||
|
|
||||||
# Checks left diagonal
|
# Checks left diagonal
|
||||||
if row <= rowCount-4 and place >= 3:
|
if row <= ROWCOUNT-4 and place >= 3:
|
||||||
pieces = [board[row+1][place-1],board[row+2][place-2],board[row+3][place-3]]
|
pieces = [board[row+1][place-1],board[row+2][place-2],board[row+3][place-3]]
|
||||||
else:
|
else:
|
||||||
pieces = [0]
|
pieces = [0]
|
||||||
@ -234,21 +320,23 @@ class connectFour():
|
|||||||
return won, winDirection, winCoordinates
|
return won, winDirection, winCoordinates
|
||||||
|
|
||||||
# Plays as the AI
|
# Plays as the AI
|
||||||
async def connectFourAI(self, channel):
|
async def connectFourAI(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["connect 4 games"].find_one({"_id":channel})
|
game = self.bot.database["connect 4 games"].find_one({"_id":channel})
|
||||||
|
|
||||||
board = game["board"]
|
board = game["board"]
|
||||||
player = game["players"].index("Gwendolyn")+1
|
player = game["players"].index(f"#{self.bot.user.id}")+1
|
||||||
difficulty = game["difficulty"]
|
difficulty = game["difficulty"]
|
||||||
|
|
||||||
scores = [-math.inf,-math.inf,-math.inf,-math.inf,-math.inf,-math.inf,-math.inf]
|
scores = [-math.inf for _ in range(COLUMNCOUNT)]
|
||||||
for column in range(0,columnCount):
|
for column in range(COLUMNCOUNT):
|
||||||
testBoard = copy.deepcopy(board)
|
testBoard = copy.deepcopy(board)
|
||||||
testBoard = self.placeOnBoard(testBoard,player,column)
|
testBoard = self.placeOnBoard(testBoard,player,column)
|
||||||
if testBoard != None:
|
if testBoard != None:
|
||||||
scores[column] = await self.minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False)
|
scores[column] = await self.minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False)
|
||||||
self.bot.log("Best score for column "+str(column)+" is "+str(scores[column]))
|
self.bot.log(f"Best score for column {column} is {scores[column]}")
|
||||||
|
|
||||||
possibleScores = scores.copy()
|
possibleScores = scores.copy()
|
||||||
|
|
||||||
@ -257,9 +345,10 @@ class connectFour():
|
|||||||
|
|
||||||
highest_score = random.choice(possibleScores)
|
highest_score = random.choice(possibleScores)
|
||||||
|
|
||||||
indices = [i for i, x in enumerate(scores) if x == highest_score]
|
bestColumns = [i for i, x in enumerate(scores) if x == highest_score]
|
||||||
placement = random.choice(indices)
|
placement = random.choice(bestColumns)
|
||||||
return self.placePiece(channel,player,placement)
|
|
||||||
|
await self.placePiece(ctx, f"#{self.bot.user.id}", placement)
|
||||||
|
|
||||||
# Calculates points for a board
|
# Calculates points for a board
|
||||||
def AICalcPoints(self,board,player):
|
def AICalcPoints(self,board,player):
|
||||||
@ -268,28 +357,28 @@ class connectFour():
|
|||||||
|
|
||||||
# Adds points for middle placement
|
# Adds points for middle placement
|
||||||
# Checks horizontal
|
# Checks horizontal
|
||||||
for row in range(rowCount):
|
for row in range(ROWCOUNT):
|
||||||
if board[row][3] == player:
|
if board[row][3] == player:
|
||||||
score += AIScores["middle"]
|
score += AISCORES["middle"]
|
||||||
rowArray = [int(i) for i in list(board[row])]
|
rowArray = [int(i) for i in list(board[row])]
|
||||||
for place in range(columnCount-3):
|
for place in range(COLUMNCOUNT-3):
|
||||||
window = rowArray[place:place+4]
|
window = rowArray[place:place+4]
|
||||||
score += self.evaluateWindow(window,player,otherPlayer)
|
score += self.evaluateWindow(window,player,otherPlayer)
|
||||||
|
|
||||||
# Checks Vertical
|
# Checks Vertical
|
||||||
for column in range(columnCount):
|
for column in range(COLUMNCOUNT):
|
||||||
columnArray = [int(i[column]) for i in list(board)]
|
columnArray = [int(i[column]) for i in list(board)]
|
||||||
for place in range(rowCount-3):
|
for place in range(ROWCOUNT-3):
|
||||||
window = columnArray[place:place+4]
|
window = columnArray[place:place+4]
|
||||||
score += self.evaluateWindow(window,player,otherPlayer)
|
score += self.evaluateWindow(window,player,otherPlayer)
|
||||||
|
|
||||||
# Checks right diagonal
|
# Checks right diagonal
|
||||||
for row in range(rowCount-3):
|
for row in range(ROWCOUNT-3):
|
||||||
for place in range(columnCount-3):
|
for place in range(COLUMNCOUNT-3):
|
||||||
window = [board[row][place],board[row+1][place+1],board[row+2][place+2],board[row+3][place+3]]
|
window = [board[row][place],board[row+1][place+1],board[row+2][place+2],board[row+3][place+3]]
|
||||||
score += self.evaluateWindow(window,player,otherPlayer)
|
score += self.evaluateWindow(window,player,otherPlayer)
|
||||||
|
|
||||||
for place in range(3,columnCount):
|
for place in range(3,COLUMNCOUNT):
|
||||||
window = [board[row][place],board[row+1][place-1],board[row+2][place-2],board[row+3][place-3]]
|
window = [board[row][place],board[row+1][place-1],board[row+2][place-2],board[row+3][place-3]]
|
||||||
score += self.evaluateWindow(window,player,otherPlayer)
|
score += self.evaluateWindow(window,player,otherPlayer)
|
||||||
|
|
||||||
@ -299,20 +388,19 @@ class connectFour():
|
|||||||
|
|
||||||
## Add points if AI wins
|
## Add points if AI wins
|
||||||
#if won == player:
|
#if won == player:
|
||||||
# score += AIScores["win"]
|
# score += AISCORES["win"]
|
||||||
|
|
||||||
return score
|
return score
|
||||||
|
|
||||||
|
|
||||||
def evaluateWindow(self, window,player,otherPlayer):
|
def evaluateWindow(self, window,player,otherPlayer):
|
||||||
if window.count(player) == 4:
|
if window.count(player) == 4:
|
||||||
return AIScores["win"]
|
return AISCORES["win"]
|
||||||
elif window.count(player) == 3 and window.count(0) == 1:
|
elif window.count(player) == 3 and window.count(0) == 1:
|
||||||
return AIScores["three in a row"]
|
return AISCORES["three in a row"]
|
||||||
elif window.count(player) == 2 and window.count(0) == 2:
|
elif window.count(player) == 2 and window.count(0) == 2:
|
||||||
return AIScores["two in a row"]
|
return AISCORES["two in a row"]
|
||||||
elif window.count(otherPlayer) == 4:
|
elif window.count(otherPlayer) == 4:
|
||||||
return AIScores["enemy win"]
|
return AISCORES["enemy win"]
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ -325,24 +413,24 @@ class connectFour():
|
|||||||
return points
|
return points
|
||||||
if maximizingPlayer:
|
if maximizingPlayer:
|
||||||
value = -math.inf
|
value = -math.inf
|
||||||
for column in range(0,columnCount):
|
for column in range(0,COLUMNCOUNT):
|
||||||
testBoard = copy.deepcopy(board)
|
testBoard = copy.deepcopy(board)
|
||||||
testBoard = self.placeOnBoard(testBoard,player,column)
|
testBoard = self.placeOnBoard(testBoard,player,column)
|
||||||
if testBoard != None:
|
if testBoard != None:
|
||||||
evaluation = await self.minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,False)
|
evaluation = await self.minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,False)
|
||||||
if evaluation < -9000: evaluation += AIScores["avoid losing"]
|
if evaluation < -9000: evaluation += AISCORES["avoid losing"]
|
||||||
value = max(value,evaluation)
|
value = max(value,evaluation)
|
||||||
alpha = max(alpha,evaluation)
|
alpha = max(alpha,evaluation)
|
||||||
if beta <= alpha: break
|
if beta <= alpha: break
|
||||||
return value
|
return value
|
||||||
else:
|
else:
|
||||||
value = math.inf
|
value = math.inf
|
||||||
for column in range(0,columnCount):
|
for column in range(0,COLUMNCOUNT):
|
||||||
testBoard = copy.deepcopy(board)
|
testBoard = copy.deepcopy(board)
|
||||||
testBoard = self.placeOnBoard(testBoard,player,column)
|
testBoard = self.placeOnBoard(testBoard,player,column)
|
||||||
if testBoard != None:
|
if testBoard != None:
|
||||||
evaluation = await self.minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,True)
|
evaluation = await self.minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,True)
|
||||||
if evaluation < -9000: evaluation += AIScores["avoid losing"]
|
if evaluation < -9000: evaluation += AISCORES["avoid losing"]
|
||||||
value = min(value,evaluation)
|
value = min(value,evaluation)
|
||||||
beta = min(beta,evaluation)
|
beta = min(beta,evaluation)
|
||||||
if beta <= alpha: break
|
if beta <= alpha: break
|
||||||
|
@ -1,172 +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 connect four
|
|
||||||
async def connectFour(self, ctx, command, user = None, channelId = None):
|
|
||||||
if user is None:
|
|
||||||
user = "#"+str(ctx.author.id)
|
|
||||||
|
|
||||||
if channelId is None:
|
|
||||||
channelId = str(ctx.channel_id)
|
|
||||||
|
|
||||||
response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.games.connectFour.parseconnectFour(command,channelId, user)
|
|
||||||
|
|
||||||
if hasattr(ctx, "send"):
|
|
||||||
await ctx.send(response)
|
|
||||||
else:
|
|
||||||
await ctx.channel.send(response)
|
|
||||||
self.bot.log(response, channelId)
|
|
||||||
if showImage:
|
|
||||||
if deleteImage:
|
|
||||||
oldImage = await self.deleteMessage("connectFour"+channelId,ctx.channel)
|
|
||||||
oldImage = await ctx.channel.send(file = discord.File("resources/games/connect4Boards/board"+channelId+".png"))
|
|
||||||
if gameDone == False:
|
|
||||||
if gwendoTurn:
|
|
||||||
response, showImage, deleteImage, gameDone, gwendoTurn = await self.bot.games.connectFour.connectFourAI(channelId)
|
|
||||||
await ctx.channel.send(response)
|
|
||||||
self.bot.log(response,channelId)
|
|
||||||
if showImage:
|
|
||||||
if deleteImage:
|
|
||||||
await oldImage.delete()
|
|
||||||
oldImage = await ctx.channel.send(file = discord.File("resources/games/connect4Boards/board"+channelId+".png"))
|
|
||||||
if gameDone == False:
|
|
||||||
with open("resources/games/oldImages/connectFour"+channelId, "w") as f:
|
|
||||||
f.write(str(oldImage.id))
|
|
||||||
try:
|
|
||||||
reactions = ["1️⃣","2️⃣","3️⃣","4️⃣","5️⃣","6️⃣","7️⃣"]
|
|
||||||
for reaction in reactions:
|
|
||||||
await oldImage.add_reaction(reaction)
|
|
||||||
|
|
||||||
except:
|
|
||||||
self.bot.log("Image deleted before I could react to all of them")
|
|
||||||
|
|
||||||
else:
|
|
||||||
with open("resources/games/oldImages/connectFour"+channelId, "w") as f:
|
|
||||||
f.write(str(oldImage.id))
|
|
||||||
try:
|
|
||||||
reactions = ["1️⃣","2️⃣","3️⃣","4️⃣","5️⃣","6️⃣","7️⃣"]
|
|
||||||
for reaction in reactions:
|
|
||||||
await oldImage.add_reaction(reaction)
|
|
||||||
except:
|
|
||||||
self.bot.log("Image deleted before I could react to all of them")
|
|
||||||
|
|
||||||
if gameDone:
|
|
||||||
game = self.bot.database["connect 4 games"].find_one({"_id":channelId})
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open("resources/games/oldImages/connectFour"+channelId, "r") as f:
|
|
||||||
oldImage = await channel.fetch_message(int(f.read()))
|
|
||||||
|
|
||||||
await oldImage.delete()
|
|
||||||
except:
|
|
||||||
self.bot.log("The old image was already deleted")
|
|
||||||
|
|
||||||
winner = game["winner"]
|
|
||||||
difficulty = int(game["difficulty"])
|
|
||||||
reward = difficulty**2 + 5
|
|
||||||
if winner != 0:
|
|
||||||
if game["players"][winner-1].lower() != "gwendolyn":
|
|
||||||
self.bot.money.addMoney(game["players"][winner-1].lower(),reward)
|
|
||||||
|
|
||||||
self.bot.databaseFuncs.deleteGame("connect 4 games",channelId)
|
|
||||||
|
|
||||||
async def runHangman(self,channel,user,command = "start", ctx = None):
|
|
||||||
try:
|
|
||||||
response, showImage, deleteImage, remainingLetters = self.bot.games.hangman.parseHangman(str(channel.id),user,command)
|
|
||||||
except:
|
|
||||||
self.bot.log("Error parsing command (error code 1701)")
|
|
||||||
if response != "":
|
|
||||||
if ctx is None:
|
|
||||||
await channel.send(response)
|
|
||||||
else:
|
|
||||||
await ctx.send(response)
|
|
||||||
self.bot.log(response,str(channel.id))
|
|
||||||
if showImage:
|
|
||||||
if deleteImage:
|
|
||||||
await self.deleteMessage("hangman"+str(channel.id),channel)
|
|
||||||
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:
|
|
||||||
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:
|
|
||||||
self.bot.log("Image deleted before adding all reactions")
|
|
||||||
|
|
||||||
# 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))
|
|
@ -1,8 +1,7 @@
|
|||||||
from .invest import Invest
|
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
|
||||||
|
|
||||||
@ -13,7 +12,6 @@ class Games():
|
|||||||
self.invest = Invest(bot)
|
self.invest = Invest(bot)
|
||||||
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)
|
@ -1,4 +1,4 @@
|
|||||||
import json, urllib, datetime, string
|
import json, urllib, datetime, string, discord
|
||||||
|
|
||||||
from .hangmanDraw import DrawHangman
|
from .hangmanDraw import DrawHangman
|
||||||
|
|
||||||
@ -9,8 +9,13 @@ class Hangman():
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.draw = DrawHangman(bot)
|
self.draw = DrawHangman(bot)
|
||||||
|
|
||||||
def hangmanStart(self,channel,user):
|
async def start(self, ctx):
|
||||||
|
await ctx.defer()
|
||||||
|
channel = str(ctx.channel_id)
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
||||||
|
userName = self.bot.databaseFuncs.getName(user)
|
||||||
|
startedGame = False
|
||||||
|
|
||||||
if game == None:
|
if game == None:
|
||||||
apiKey = self.bot.credentials.wordnikKey
|
apiKey = self.bot.credentials.wordnikKey
|
||||||
@ -26,86 +31,135 @@ class Hangman():
|
|||||||
|
|
||||||
remainingLetters = list(string.ascii_uppercase)
|
remainingLetters = list(string.ascii_uppercase)
|
||||||
|
|
||||||
try:
|
self.draw.drawImage(channel)
|
||||||
self.draw.drawImage(channel)
|
|
||||||
except:
|
logMessage = "Game started"
|
||||||
self.bot.log("Error drawing image (error code 1710)")
|
sendMessage = f"{userName} started game of hangman."
|
||||||
return f"{self.bot.databaseFuncs.getName(user)} started game of hangman.", True, False, remainingLetters
|
startedGame = True
|
||||||
else:
|
else:
|
||||||
return "There's already a Hangman game going on in the channel", False, False, []
|
logMessage = "There was already a game going on"
|
||||||
|
sendMessage = "There's already a Hangman game going on in the channel"
|
||||||
|
|
||||||
def hangmanStop(self,channel):
|
self.bot.log(logMessage)
|
||||||
self.bot.database["hangman games"].delete_one({"_id":channel})
|
await ctx.send(sendMessage)
|
||||||
|
|
||||||
return "Game stopped.", False, False, []
|
if startedGame:
|
||||||
|
filePath = f"resources/games/hangmanBoards/hangmanBoard{channel}.png"
|
||||||
|
newImage = await ctx.channel.send(file = discord.File(filePath))
|
||||||
|
|
||||||
def hangmanGuess(self,channel,user,guess):
|
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})
|
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
||||||
|
|
||||||
if game != None:
|
gameExists = (game != None)
|
||||||
if user == game["player"]:
|
singleLetter = (len(guess) == 1 and guess.isalpha())
|
||||||
if len(guess) == 1 and guess in list(string.ascii_uppercase):
|
newGuess = (guess not in game["guessed letters"])
|
||||||
if guess not in game["guessed letters"]:
|
validGuess = (gameExists and singleLetter and newGuess)
|
||||||
correctGuess = 0
|
|
||||||
|
|
||||||
for x, letter in enumerate(game["word"]):
|
if validGuess:
|
||||||
if guess == letter:
|
self.bot.log("Guessed the letter")
|
||||||
correctGuess += 1
|
correctGuess = 0
|
||||||
self.bot.database["hangman games"].update_one({"_id":channel},{"$set":{"guessed."+str(x):True}})
|
|
||||||
|
|
||||||
if correctGuess == 0:
|
for x, letter in enumerate(game["word"]):
|
||||||
self.bot.database["hangman games"].update_one({"_id":channel},{"$inc":{"misses":1}})
|
if guess == letter:
|
||||||
|
correctGuess += 1
|
||||||
|
self.bot.database["hangman games"].update_one({"_id":channel},{"$set":{"guessed."+str(x):True}})
|
||||||
|
|
||||||
self.bot.database["hangman games"].update_one({"_id":channel},{"$push":{"guessed letters":guess}})
|
if correctGuess == 0:
|
||||||
|
self.bot.database["hangman games"].update_one({"_id":channel},{"$inc":{"misses":1}})
|
||||||
|
|
||||||
remainingLetters = list(string.ascii_uppercase)
|
self.bot.database["hangman games"].update_one({"_id":channel},{"$push":{"guessed letters":guess}})
|
||||||
|
|
||||||
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
remainingLetters = list(string.ascii_uppercase)
|
||||||
|
|
||||||
for letter in game["guessed letters"]:
|
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
||||||
remainingLetters.remove(letter)
|
|
||||||
|
|
||||||
if correctGuess == 1:
|
for letter in game["guessed letters"]:
|
||||||
message = f"Guessed {guess}. There was 1 {guess} in the word."
|
remainingLetters.remove(letter)
|
||||||
else:
|
|
||||||
message = f"Guessed {guess}. There were {correctGuess} {guess}s in the word."
|
|
||||||
|
|
||||||
try:
|
if correctGuess == 1:
|
||||||
self.draw.drawImage(channel)
|
sendMessage = f"Guessed {guess}. There was 1 {guess} in the word."
|
||||||
except:
|
|
||||||
self.bot.log("Error drawing image (error code 1710)")
|
|
||||||
|
|
||||||
if game["misses"] == 6:
|
|
||||||
self.hangmanStop(channel)
|
|
||||||
return message+" You've guessed wrong six times and have lost the game.", True, True, []
|
|
||||||
elif all(i == True for i in game["guessed"]):
|
|
||||||
self.hangmanStop(channel)
|
|
||||||
self.bot.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:
|
else:
|
||||||
return "", False, False, []
|
sendMessage = f"Guessed {guess}. There were {correctGuess} {guess}s in the word."
|
||||||
else:
|
|
||||||
return "There's no Hangman game going on in this channel", False, False, []
|
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)
|
||||||
|
|
||||||
|
|
||||||
def parseHangman(self,channel,user,command):
|
|
||||||
if command == "start":
|
|
||||||
try:
|
|
||||||
return self.hangmanStart(channel,user)
|
|
||||||
except:
|
|
||||||
self.bot.log("Error starting game (error code 1730)")
|
|
||||||
elif command == "stop":
|
|
||||||
return self.hangmanStop(channel)
|
|
||||||
elif command.startswith("guess "):
|
|
||||||
guess = command[6:].upper()
|
|
||||||
try:
|
|
||||||
return self.hangmanGuess(channel,user,guess)
|
|
||||||
except:
|
|
||||||
self.bot.log("Error in guessing (Error Code 1720)")
|
|
||||||
else:
|
|
||||||
return "I didn't understand that", False, False, []
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
@ -13,102 +14,146 @@ for position in ALL_POSITIONS:
|
|||||||
HEX_DIRECTIONS = [(0,1),(-1,1),(-1,0),(0,-1),(1,-1),(1,0)]
|
HEX_DIRECTIONS = [(0,1),(-1,1),(-1,0),(0,-1),(1,-1),(1,0)]
|
||||||
|
|
||||||
class HexGame():
|
class HexGame():
|
||||||
def __init__(self,bot):
|
def __init__(self, bot):
|
||||||
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
|
players = game["players"]
|
||||||
|
|
||||||
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"]
|
|
||||||
if user in players:
|
|
||||||
opponent = (players.index(user) + 1) % 2
|
|
||||||
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":opponent + 1}})
|
|
||||||
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:
|
|
||||||
return "You can't surrender when you're not a player.", False, False, False, False
|
|
||||||
|
|
||||||
# Swap
|
|
||||||
elif commands[0] == "swap":
|
|
||||||
if len(game["gameHistory"]) == 1: # Only after the first move
|
|
||||||
self.bot.database["hex games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"players":game["players"][::-1]}}) # Swaps their player-number
|
|
||||||
|
|
||||||
# Swaps the color of the hexes on the board drawing:
|
|
||||||
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
|
|
||||||
|
|
||||||
|
if user not in players:
|
||||||
|
await ctx.send("You can't surrender when you're not a player.")
|
||||||
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
|
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
|
||||||
|
async def swap(self, ctx):
|
||||||
|
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},
|
||||||
|
{"$set":{"players":game["players"][::-1]}}) # Swaps their player-number
|
||||||
|
|
||||||
|
# Swaps the color of the hexes on the board drawing:
|
||||||
|
self.draw.drawSwap(channel)
|
||||||
|
|
||||||
|
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:
|
||||||
|
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
|
|
||||||
opponent = "Gwendolyn"
|
|
||||||
elif opponent.lower() == "gwendolyn":
|
|
||||||
difficulty = 2
|
|
||||||
diffText = " with difficulty 2"
|
|
||||||
opponent = "Gwendolyn"
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
int(opponent)
|
|
||||||
return "That difficulty doesn't exist", False, False, False, False
|
|
||||||
except:
|
|
||||||
opponent = self.bot.databaseFuncs.getID(opponent)
|
|
||||||
if opponent == None:
|
|
||||||
return "I can't find that user", False, False, False, False
|
|
||||||
else:
|
|
||||||
# Opponent is another player
|
|
||||||
difficulty = 3
|
|
||||||
diffText = ""
|
|
||||||
|
|
||||||
|
if game != None:
|
||||||
|
sendMessage = "There's already a hex game going on in this channel"
|
||||||
|
logMessage = "There was already a game going on"
|
||||||
|
canStart = False
|
||||||
|
else:
|
||||||
|
if type(opponent) == int:
|
||||||
|
# Opponent is Gwendolyn
|
||||||
|
if opponent in range(1, 6):
|
||||||
|
opponentName = "Gwendolyn"
|
||||||
|
difficulty = int(opponent)
|
||||||
|
diffText = f" with difficulty {difficulty}"
|
||||||
|
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:
|
||||||
|
# Opponent is another player
|
||||||
|
if ctx.author != opponent:
|
||||||
|
opponentName = opponent.display_name
|
||||||
|
opponent = f"#{opponent.id}"
|
||||||
|
difficulty = 5
|
||||||
|
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]
|
||||||
random.shuffle(players) # random starting player
|
random.shuffle(players) # random starting player
|
||||||
gameHistory = []
|
gameHistory = []
|
||||||
|
|
||||||
@ -120,137 +165,196 @@ 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) in [2, 3]):
|
||||||
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:
|
|
||||||
player = players.index(user)+1
|
|
||||||
|
|
||||||
if player == turn:
|
|
||||||
board = game["board"]
|
|
||||||
|
|
||||||
self.bot.log("Placing a piece on the board with placeHex()")
|
|
||||||
# Places on board
|
|
||||||
board = self.placeOnHexBoard(board,player,position)
|
|
||||||
|
|
||||||
if isinstance(board, list):
|
|
||||||
# If the move is valid:
|
|
||||||
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"board":board}})
|
|
||||||
turn = 1 if turn == 2 else 2
|
|
||||||
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"turn":turn}})
|
|
||||||
|
|
||||||
# Checking for a win
|
|
||||||
self.bot.log("Checking for win")
|
|
||||||
winner = self.evaluateBoard(game["board"])[1]
|
|
||||||
|
|
||||||
if winner == 0: # Continue with the game.
|
|
||||||
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)
|
|
||||||
|
|
||||||
else: # Congratulations!
|
|
||||||
gameWon = True
|
|
||||||
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!"
|
|
||||||
if game["players"][winner-1] != "Gwendolyn":
|
|
||||||
winAmount = game["difficulty"]*10
|
|
||||||
message += " Adding "+str(winAmount)+" GwendoBucks to their account."
|
|
||||||
|
|
||||||
self.bot.database["hex games"].update_one({"_id":channel},
|
|
||||||
{"$push":{"gameHistory":(int(position[1])-1, ord(position[0])-97)}})
|
|
||||||
|
|
||||||
# Is it now Gwendolyn's turn?
|
|
||||||
gwendoTurn = False
|
|
||||||
if game["players"][turn-1] == "Gwendolyn":
|
|
||||||
self.bot.log("It's Gwendolyn's turn")
|
|
||||||
gwendoTurn = True
|
|
||||||
|
|
||||||
# Update the board
|
|
||||||
self.draw.drawHexPlacement(channel,player,position)
|
|
||||||
|
|
||||||
return message, True, True, gameWon, gwendoTurn
|
|
||||||
else:
|
|
||||||
# Invalid move. "board" is the error message
|
|
||||||
message = board
|
|
||||||
return message, False, False, False, False
|
|
||||||
else:
|
|
||||||
# Move out of turn
|
|
||||||
message = "It isn't your turn, it is "+self.bot.databaseFuncs.getName(game["players"][turn-1])+"'s turn."
|
|
||||||
return message, False, False, False, False
|
|
||||||
else:
|
|
||||||
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])+"."
|
|
||||||
return message, False, False, False, False
|
|
||||||
else:
|
else:
|
||||||
return "There's no game in this channel", False, False, False, False
|
players = game["players"]
|
||||||
|
if user not in players:
|
||||||
|
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"]
|
||||||
|
|
||||||
|
self.bot.log("Placing a piece on the board with placeHex()")
|
||||||
|
# Places on board
|
||||||
|
board = self.placeOnHexBoard(board,player,position)
|
||||||
|
|
||||||
|
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:
|
||||||
|
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"board":board}})
|
||||||
|
turn = (turn % 2) + 1
|
||||||
|
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"turn":turn}})
|
||||||
|
|
||||||
|
# Checking for a win
|
||||||
|
self.bot.log("Checking for win")
|
||||||
|
winner = self.evaluateBoard(game["board"])[1]
|
||||||
|
|
||||||
|
if winner == 0: # Continue with the game.
|
||||||
|
gameWon = False
|
||||||
|
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!
|
||||||
|
gameWon = True
|
||||||
|
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":winner}})
|
||||||
|
sendMessage = self.bot.databaseFuncs.getName(game["players"][player-1])+" placed at "+position.upper()+" and won!"
|
||||||
|
if game["players"][winner-1] != f"#{self.bot.user.id}":
|
||||||
|
winAmount = game["difficulty"]*10
|
||||||
|
sendMessage += " Adding "+str(winAmount)+" GwendoBucks to their account."
|
||||||
|
|
||||||
|
self.bot.database["hex games"].update_one({"_id":channel},
|
||||||
|
{"$push":{"gameHistory":(int(position[1])-1, ord(position[0])-97)}})
|
||||||
|
|
||||||
|
# Is it now Gwendolyn's turn?
|
||||||
|
gwendoTurn = False
|
||||||
|
if game["players"][turn-1] == f"#{self.bot.user.id}":
|
||||||
|
self.bot.log("It's Gwendolyn's turn")
|
||||||
|
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
|
||||||
|
self.draw.drawHexPlacement(channel,player, position)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
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:
|
||||||
|
with open(f"resources/games/oldImages/hex{channel}", "w") as f:
|
||||||
|
f.write(str(oldImage.id))
|
||||||
|
|
||||||
|
if gwendoTurn:
|
||||||
|
await self.hexAI(ctx)
|
||||||
|
|
||||||
# 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")
|
||||||
self.bot.log("Position out of bounds (error code 1533)")
|
return None
|
||||||
return "Error. That position is out of bounds."
|
|
||||||
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"
|
||||||
turn = game["turn"]
|
elif len(game["gameHistory"]) == 0:
|
||||||
# You can only undo after your turn, which is the opponent's turn.
|
sendMessage = "You can't undo nothing"
|
||||||
if user == game["players"][(turn % 2)]: # If it's not your turn
|
elif user != game["players"][(game["turn"] % 2)]: # If it's not your turn
|
||||||
self.bot.log("Undoing {}'s last move".format(self.bot.databaseFuncs.getName(user)))
|
sendMessage = "It's not your turn"
|
||||||
|
|
||||||
lastMove = game["gameHistory"].pop()
|
|
||||||
game["board"][lastMove[0]][lastMove[1]] = 0
|
|
||||||
self.bot.database["hex games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"board":game["board"]}})
|
|
||||||
self.bot.database["hex games"].update_one({"_id":channel},
|
|
||||||
{"$set":{"turn":turn%2 + 1}})
|
|
||||||
|
|
||||||
# Update the board
|
|
||||||
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
|
|
||||||
else:
|
|
||||||
# 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
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return "You're not a player in the game", False, False, False, False
|
turn = game["turn"]
|
||||||
|
self.bot.log("Undoing {}'s last move".format(self.bot.databaseFuncs.getName(user)))
|
||||||
|
|
||||||
|
lastMove = game["gameHistory"].pop()
|
||||||
|
game["board"][lastMove[0]][lastMove[1]] = 0
|
||||||
|
self.bot.database["hex games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"board":game["board"]}})
|
||||||
|
self.bot.database["hex games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"turn":turn%2 + 1}})
|
||||||
|
|
||||||
|
# Update the board
|
||||||
|
self.draw.drawHexPlacement(channel,0,"abcdefghijk"[lastMove[1]]+str(lastMove[0]+1)) # The zero makes the hex disappear
|
||||||
|
sendMessage = f"You undid your last move at {lastMove}"
|
||||||
|
undid = True
|
||||||
|
|
||||||
|
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:
|
||||||
|
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):
|
||||||
|
@ -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()
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import discord
|
||||||
|
|
||||||
class Invest():
|
class Invest():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
@ -103,35 +105,48 @@ class Invest():
|
|||||||
else:
|
else:
|
||||||
return "no"
|
return "no"
|
||||||
|
|
||||||
def parseInvest(self, content: str, user : str):
|
async def parseInvest(self, ctx, parameters):
|
||||||
if content.startswith("check"):
|
try:
|
||||||
commands = content.split(" ")
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("Defer failed")
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
|
||||||
|
if parameters.startswith("check"):
|
||||||
|
commands = parameters.split(" ")
|
||||||
if len(commands) == 1:
|
if len(commands) == 1:
|
||||||
return self.getPortfolio(user)
|
response = self.getPortfolio(user)
|
||||||
else:
|
else:
|
||||||
price = self.getPrice(commands[1])
|
price = self.getPrice(commands[1])
|
||||||
if price == 0:
|
if price == 0:
|
||||||
return f"{commands[1].upper()} is not traded on the american market."
|
response = f"{commands[1].upper()} is not traded on the american market."
|
||||||
else:
|
else:
|
||||||
price = f"{price:,}".replace(",",".")
|
price = f"{price:,}".replace(",",".")
|
||||||
return f"The current {commands[1].upper()} stock is valued at **{price}** GwendoBucks"
|
response = f"The current {commands[1].upper()} stock is valued at **{price}** GwendoBucks"
|
||||||
|
|
||||||
elif content.startswith("buy"):
|
elif parameters.startswith("buy"):
|
||||||
commands = content.split(" ")
|
commands = parameters.split(" ")
|
||||||
if len(commands) == 3:
|
if len(commands) == 3:
|
||||||
#try:
|
response = self.buyStock(user,commands[1],int(commands[2]))
|
||||||
return self.buyStock(user,commands[1],int(commands[2]))
|
|
||||||
#except:
|
|
||||||
# return "The command must be given as \"/invest buy [stock] [amount of GwendoBucks to purchase with]\""
|
|
||||||
else:
|
else:
|
||||||
return "You must give both a stock name and an amount of gwendobucks you wish to spend."
|
response = "You must give both a stock name and an amount of gwendobucks you wish to spend."
|
||||||
|
|
||||||
elif content.startswith("sell"):
|
elif parameters.startswith("sell"):
|
||||||
commands = content.split(" ")
|
commands = parameters.split(" ")
|
||||||
if len(commands) == 3:
|
if len(commands) == 3:
|
||||||
try:
|
try:
|
||||||
return self.sellStock(user,commands[1],int(commands[2]))
|
response = self.sellStock(user,commands[1],int(commands[2]))
|
||||||
except:
|
except:
|
||||||
return "The command must be given as \"/invest sell [stock] [amount of GwendoBucks to sell stocks for]\""
|
response = "The command must be given as \"/invest sell [stock] [amount of GwendoBucks to sell stocks for]\""
|
||||||
else:
|
else:
|
||||||
return "You must give both a stock name and an amount of GwendoBucks you wish to sell stocks for."
|
response = "You must give both a stock name and an amount of GwendoBucks you wish to sell stocks for."
|
||||||
|
|
||||||
|
else:
|
||||||
|
response = "Incorrect parameters"
|
||||||
|
|
||||||
|
if response.startswith("**"):
|
||||||
|
responses = response.split("\n")
|
||||||
|
em = discord.Embed(title=responses[0],description="\n".join(responses[1:]),colour=0x00FF00)
|
||||||
|
await ctx.send(embed=em)
|
||||||
|
else:
|
||||||
|
await ctx.send(response)
|
||||||
|
@ -14,6 +14,15 @@ class Money():
|
|||||||
return userData["money"]
|
return userData["money"]
|
||||||
else: return 0
|
else: return 0
|
||||||
|
|
||||||
|
async def sendBalance(self, ctx):
|
||||||
|
await ctx.defer()
|
||||||
|
response = self.checkBalance("#"+str(ctx.author.id))
|
||||||
|
if response == 1:
|
||||||
|
new_message = ctx.author.display_name + " has " + str(response) + " GwendoBuck"
|
||||||
|
else:
|
||||||
|
new_message = ctx.author.display_name + " has " + str(response) + " GwendoBucks"
|
||||||
|
await ctx.send(new_message)
|
||||||
|
|
||||||
# Adds money to the account of a user
|
# Adds money to the account of a user
|
||||||
def addMoney(self,user,amount):
|
def addMoney(self,user,amount):
|
||||||
self.bot.log("adding "+str(amount)+" to "+user+"'s account")
|
self.bot.log("adding "+str(amount)+" to "+user+"'s account")
|
||||||
@ -26,26 +35,39 @@ class Money():
|
|||||||
self.database["users"].insert_one({"_id":user,"user name":self.bot.databaseFuncs.getName(user),"money":amount})
|
self.database["users"].insert_one({"_id":user,"user name":self.bot.databaseFuncs.getName(user),"money":amount})
|
||||||
|
|
||||||
# Transfers money from one user to another
|
# Transfers money from one user to another
|
||||||
def giveMoney(self,user,targetUser,amount):
|
async def giveMoney(self, ctx, user, amount):
|
||||||
userData = self.database["users"].find_one({"_id":user})
|
try:
|
||||||
targetUser = self.bot.databaseFuncs.getID(targetUser)
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("Defer failed")
|
||||||
|
username = user.display_name
|
||||||
|
if self.bot.databaseFuncs.getID(username) == None:
|
||||||
|
async for member in ctx.guild.fetch_members(limit=None):
|
||||||
|
if member.display_name.lower() == username.lower():
|
||||||
|
username = member.display_name
|
||||||
|
userID = "#" + str(member.id)
|
||||||
|
newUser = {"_id":userID,"user name":username,"money":0}
|
||||||
|
self.bot.database["users"].insert_one(newUser)
|
||||||
|
|
||||||
|
userData = self.database["users"].find_one({"_id":f"#{ctx.author.id}"})
|
||||||
|
targetUser = self.bot.databaseFuncs.getID(username)
|
||||||
|
|
||||||
if amount > 0:
|
if amount > 0:
|
||||||
if targetUser != None:
|
if targetUser != None:
|
||||||
if userData != None:
|
if userData != None:
|
||||||
if userData["money"] >= amount:
|
if userData["money"] >= amount:
|
||||||
self.addMoney(user,-1 * amount)
|
self.addMoney(f"#{ctx.author.id}",-1 * amount)
|
||||||
self.addMoney(targetUser,amount)
|
self.addMoney(targetUser,amount)
|
||||||
return "Transferred "+str(amount)+" GwendoBucks to "+self.bot.databaseFuncs.getName(targetUser)
|
await ctx.send(f"Transferred {amount} GwendoBucks to {username}")
|
||||||
else:
|
else:
|
||||||
self.bot.log("They didn't have enough GwendoBucks (error code 1223b)")
|
self.bot.log("They didn't have enough GwendoBucks")
|
||||||
return "You don't have that many GwendoBucks (error code 1223b)"
|
await ctx.send("You don't have that many GwendoBucks")
|
||||||
else:
|
else:
|
||||||
self.bot.log("They didn't have enough GwendoBucks (error code 1223a)")
|
self.bot.log("They didn't have enough GwendoBucks")
|
||||||
return "You don't have that many GwendoBucks (error code 1223a)"
|
await ctx.send("You don't have that many GwendoBuck")
|
||||||
else:
|
else:
|
||||||
self.bot.log("They weren't in the system")
|
self.bot.log("They weren't in the system")
|
||||||
return "The target doesn't exist"
|
await ctx.send("The target doesn't exist")
|
||||||
else:
|
else:
|
||||||
self.bot.log("They tried to steal")
|
self.bot.log("They tried to steal")
|
||||||
return "Yeah, no. You can't do that"
|
await ctx.send("Yeah, no. You can't do that")
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import urllib
|
import urllib
|
||||||
import random
|
import random
|
||||||
|
import asyncio
|
||||||
|
|
||||||
class Trivia():
|
class Trivia():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
@ -83,3 +84,38 @@ class Trivia():
|
|||||||
self.bot.log("Couldn't find the question (error code 1102)")
|
self.bot.log("Couldn't find the question (error code 1102)")
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def triviaParse(self, ctx, answer):
|
||||||
|
try:
|
||||||
|
await ctx.defer()
|
||||||
|
except:
|
||||||
|
self.bot.log("defer failed")
|
||||||
|
if answer == "":
|
||||||
|
question, options, correctAnswer = self.triviaStart(str(ctx.channel_id))
|
||||||
|
if options != "":
|
||||||
|
results = "**"+question+"**\n"
|
||||||
|
for x, option in enumerate(options):
|
||||||
|
results += chr(x+97) + ") "+option+"\n"
|
||||||
|
|
||||||
|
await ctx.send(results)
|
||||||
|
|
||||||
|
await asyncio.sleep(60)
|
||||||
|
|
||||||
|
self.triviaCountPoints(str(ctx.channel_id))
|
||||||
|
|
||||||
|
self.bot.databaseFuncs.deleteGame("trivia questions",str(ctx.channel_id))
|
||||||
|
|
||||||
|
self.bot.log("Time's up for the trivia question",str(ctx.channel_id))
|
||||||
|
await ctx.send("Time's up The answer was \"*"+chr(correctAnswer)+") "+options[correctAnswer-97]+"*\". Anyone who answered that has gotten 1 GwendoBuck")
|
||||||
|
else:
|
||||||
|
await ctx.send(question, hidden=True)
|
||||||
|
|
||||||
|
elif answer in ["a","b","c","d"]:
|
||||||
|
response = self.triviaAnswer("#"+str(ctx.author.id), str(ctx.channel_id), answer)
|
||||||
|
if response.startswith("Locked in "):
|
||||||
|
await ctx.send(f"{ctx.author.display_name} answered **{answer}**")
|
||||||
|
else:
|
||||||
|
await ctx.send(response)
|
||||||
|
else:
|
||||||
|
self.bot.log("I didn't understand that (error code 1101)",str(ctx.channel_id))
|
||||||
|
await ctx.send("I didn't understand that (error code 1101)")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import math
|
import math
|
||||||
import json
|
import json
|
||||||
|
import discord
|
||||||
|
|
||||||
from utils import cap
|
from utils import cap
|
||||||
|
|
||||||
@ -18,27 +19,28 @@ class LookupFuncs():
|
|||||||
return(str(mods))
|
return(str(mods))
|
||||||
|
|
||||||
# Looks up a monster
|
# Looks up a monster
|
||||||
def monsterFunc(self, command):
|
async def monsterFunc(self, ctx, query):
|
||||||
self.bot.log("Looking up "+command)
|
query = cap(query)
|
||||||
|
self.bot.log("Looking up "+query)
|
||||||
|
|
||||||
# 1-letter monsters don't exist
|
# 1-letter monsters don't exist
|
||||||
if len(command) < 2:
|
if len(query) < 2:
|
||||||
self.bot.log("Monster name too short (error code 601)")
|
self.bot.log("Monster name too short")
|
||||||
return("I don't know that monster... (error code 601)","","","","","")
|
await ctx.send("I don't know that monster...")
|
||||||
else:
|
else:
|
||||||
# Opens "monsters.json"
|
# Opens "monsters.json"
|
||||||
data = json.load(open('resources/lookup/monsters.json', encoding = "utf8"))
|
data = json.load(open('resources/lookup/monsters.json', encoding = "utf8"))
|
||||||
for monster in data:
|
for monster in data:
|
||||||
if "name" in monster and str(command) == monster["name"]:
|
if "name" in monster and str(query) == monster["name"]:
|
||||||
self.bot.log("Found it!")
|
self.bot.log("Found it!")
|
||||||
|
|
||||||
# Looks at the information about the monster and returns that information
|
# Looks at the information about the monster and returns that information
|
||||||
# in separate variables, allowing Gwendolyn to know where to separate
|
# in separate variables, allowing Gwendolyn to know where to separate
|
||||||
# the messages
|
# the messages
|
||||||
if monster["subtype"] != "":
|
if monster["subtype"] != "":
|
||||||
typs = (monster["type"]+" ("+monster["subtype"]+")")
|
types = (monster["type"]+" ("+monster["subtype"]+")")
|
||||||
else:
|
else:
|
||||||
typs = monster["type"]
|
types = monster["type"]
|
||||||
con_mod = math.floor((monster["constitution"]-10)/2)
|
con_mod = math.floor((monster["constitution"]-10)/2)
|
||||||
hit_dice = monster["hit_dice"]
|
hit_dice = monster["hit_dice"]
|
||||||
|
|
||||||
@ -80,10 +82,10 @@ class LookupFuncs():
|
|||||||
if c_immunities != "":
|
if c_immunities != "":
|
||||||
c_immunities = "\n**Condition Immunities** "+c_immunities
|
c_immunities = "\n**Condition Immunities** "+c_immunities
|
||||||
|
|
||||||
spec_ab = ""
|
specialAbilities = ""
|
||||||
if "special_abilities" in monster:
|
if "special_abilities" in monster:
|
||||||
for ability in monster["special_abilities"]:
|
for ability in monster["special_abilities"]:
|
||||||
spec_ab += "\n\n***"+ability["name"]+".*** "+ability["desc"]
|
specialAbilities += "\n\n***"+ability["name"]+".*** "+ability["desc"]
|
||||||
|
|
||||||
act = ""
|
act = ""
|
||||||
if "actions" in monster:
|
if "actions" in monster:
|
||||||
@ -95,10 +97,10 @@ class LookupFuncs():
|
|||||||
for reaction in monster["reactions"]:
|
for reaction in monster["reactions"]:
|
||||||
react += "\n\n***"+reaction["name"]+".*** "+reaction["desc"]
|
react += "\n\n***"+reaction["name"]+".*** "+reaction["desc"]
|
||||||
|
|
||||||
leg_act = ""
|
legendaryActions = ""
|
||||||
if "legendary_actions" in monster:
|
if "legendary_actions" in monster:
|
||||||
for action in monster["legendary_actions"]:
|
for action in monster["legendary_actions"]:
|
||||||
leg_act += "\n\n***"+action["name"]+".*** "+action["desc"]
|
legendaryActions += "\n\n***"+action["name"]+".*** "+action["desc"]
|
||||||
|
|
||||||
if con_mod < 0:
|
if con_mod < 0:
|
||||||
hit_dice += (" - "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])*(-1)))
|
hit_dice += (" - "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])*(-1)))
|
||||||
@ -107,33 +109,56 @@ class LookupFuncs():
|
|||||||
|
|
||||||
new_part = "\n--------------------"
|
new_part = "\n--------------------"
|
||||||
|
|
||||||
monster_type = monster["size"]+" "+typs+", "+monster["alignment"]+"*"
|
monster_type = monster["size"]+" "+types+", "+monster["alignment"]+"*"
|
||||||
|
|
||||||
basic_info = "\n**Armor Class** "+str(monster["armor_class"])+"\n**Hit Points** "+str(monster["hit_points"])+" ("+hit_dice+")\n**Speed **"+monster["speed"]+new_part+"\n"
|
basic_info = "\n**Armor Class** "+str(monster["armor_class"])+"\n**Hit Points** "+str(monster["hit_points"])+" ("+hit_dice+")\n**Speed **"+monster["speed"]+new_part+"\n"
|
||||||
|
|
||||||
text1 = (monster_type+new_part+basic_info+stats+new_part+saving_throws+skills+vulnerabilities+resistances+immunities+c_immunities+"\n**Senses** "+monster["senses"]+"\n**Languages** "+monster["languages"]+"\n**Challenge** "+monster["challenge_rating"])
|
info = (monster_type+new_part+basic_info+stats+new_part+saving_throws+skills+vulnerabilities+resistances+immunities+c_immunities+"\n**Senses** "+monster["senses"]+"\n**Languages** "+monster["languages"]+"\n**Challenge** "+monster["challenge_rating"])
|
||||||
|
|
||||||
text2 = (spec_ab)
|
monsterInfo = [(info, query),
|
||||||
text3 = (act)
|
(specialAbilities, "Special Abilities"),
|
||||||
text4 = (react)
|
(act, "Actions"),
|
||||||
text5 = (leg_act)
|
(react, "Reactions"),
|
||||||
|
(legendaryActions, "Legendary Actions")]
|
||||||
|
|
||||||
self.bot.log("Returning monster information")
|
self.bot.log("Returning monster information")
|
||||||
return(str(command),text1,text2,text3,text4,text5)
|
|
||||||
self.bot.log("Monster not in database (error code 602)")
|
# Sends the received information. Separates into separate messages if
|
||||||
return("I don't know that monster... (error code 602)","","","","","")
|
# there is too much text
|
||||||
|
await ctx.send(f"Result for \"{query}\"")
|
||||||
|
for text, title in monsterInfo:
|
||||||
|
if text != "":
|
||||||
|
if len(text) < 2000:
|
||||||
|
em = discord.Embed(title = title, description = text, colour=0xDEADBF)
|
||||||
|
await ctx.channel.send(embed = em)
|
||||||
|
else:
|
||||||
|
index = text[:2000].rfind(".")+1
|
||||||
|
em1 = discord.Embed(title = title, description = text[:index], colour=0xDEADBF)
|
||||||
|
await ctx.channel.send(embed = em1)
|
||||||
|
em2 = discord.Embed(title = "", description = text[index+1:], colour=0xDEADBF)
|
||||||
|
await ctx.channel.send(embed = em2)
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.bot.log("Monster not in database")
|
||||||
|
await ctx.send("I don't know that monster...")
|
||||||
|
|
||||||
# Looks up a spell
|
# Looks up a spell
|
||||||
def spellFunc(self, command):
|
async def spellFunc(self, ctx, query):
|
||||||
self.bot.log("Looking up "+command)
|
query = cap(query)
|
||||||
|
self.bot.log("Looking up "+query)
|
||||||
|
|
||||||
# Opens "spells.json"
|
# Opens "spells.json"
|
||||||
data = json.load(open('resources/lookup/spells.json', encoding = "utf8"))
|
data = json.load(open('resources/lookup/spells.json', encoding = "utf8"))
|
||||||
if str(command) in data:
|
if query in data:
|
||||||
self.bot.log("Returning spell information")
|
self.bot.log("Returning spell information")
|
||||||
spell_output = ("***"+str(command)+"***\n*"+str(data[str(command)]["level"])+" level "+str(data[str(command)]["school"])+"\nCasting Time: "+str(data[str(command)]["casting_time"])+"\nRange: "+str(data[str(command)]["range"])+"\nComponents: "+str(data[str(command)]["components"])+"\nDuration: "+str(data[str(command)]["duration"])+"*\n \n"+str(data[str(command)]["description"]))
|
sendMessage = (f"***{query}***\n*{data[query]['level']} level {data[query]['school']}\nCasting Time: {data[query]['casting_time']}\nRange:{data[query]['range']}\nComponents:{data[query]['components']}\nDuration:{data[query]['duration']}*\n \n{data[query]['description']}")
|
||||||
else:
|
else:
|
||||||
self.bot.log("I don't know that spell (error code 501)")
|
self.bot.log("I don't know that spell (error code 501)")
|
||||||
spell_output = "I don't think that's a spell (error code 501)"
|
sendMessage = "I don't think that's a spell (error code 501)"
|
||||||
self.bot.log("Successfully ran /spell")
|
|
||||||
return(spell_output)
|
if len(sendMessage) > 2000:
|
||||||
|
await ctx.send(sendMessage[:2000])
|
||||||
|
await ctx.send(sendMessage[2000:])
|
||||||
|
else:
|
||||||
|
await ctx.send(sendMessage)
|
||||||
|
@ -13,6 +13,8 @@ class BedreNetflix():
|
|||||||
|
|
||||||
#Returns a list of no more than 5 options when user requests a movie
|
#Returns a list of no more than 5 options when user requests a movie
|
||||||
async def requestMovie(self, ctx, movieName):
|
async def requestMovie(self, ctx, movieName):
|
||||||
|
await ctx.defer()
|
||||||
|
|
||||||
self.bot.log("Searching for "+movieName)
|
self.bot.log("Searching for "+movieName)
|
||||||
movieList = imdb.IMDb().search_movie(movieName)
|
movieList = imdb.IMDb().search_movie(movieName)
|
||||||
movies = []
|
movies = []
|
||||||
@ -89,6 +91,8 @@ class BedreNetflix():
|
|||||||
|
|
||||||
#Returns a list of no more than 5 options when user requests a show
|
#Returns a list of no more than 5 options when user requests a show
|
||||||
async def requestShow(self, ctx, showName):
|
async def requestShow(self, ctx, showName):
|
||||||
|
await ctx.defer()
|
||||||
|
|
||||||
self.bot.log("Searching for "+showName)
|
self.bot.log("Searching for "+showName)
|
||||||
movies = imdb.IMDb().search_movie(showName) #Replace with tvdb
|
movies = imdb.IMDb().search_movie(showName) #Replace with tvdb
|
||||||
shows = []
|
shows = []
|
||||||
@ -301,6 +305,8 @@ class BedreNetflix():
|
|||||||
await ctx.send("```"+messageText[:cutOffIndex]+"```")
|
await ctx.send("```"+messageText[:cutOffIndex]+"```")
|
||||||
await SendLongMessage(ctx,messageText[cutOffIndex+1:])
|
await SendLongMessage(ctx,messageText[cutOffIndex+1:])
|
||||||
|
|
||||||
|
await ctx.defer()
|
||||||
|
|
||||||
# showDM, showMovies, showShows, episodes
|
# showDM, showMovies, showShows, episodes
|
||||||
params = [False, False, False, False]
|
params = [False, False, False, False]
|
||||||
showDMArgs = ["d", "dm", "downloading", "downloadmanager"]
|
showDMArgs = ["d", "dm", "downloading", "downloadmanager"]
|
||||||
|
@ -15,7 +15,7 @@ class Generators():
|
|||||||
yield (corpus[i], corpus[i+1], corpus[i+2])
|
yield (corpus[i], corpus[i+1], corpus[i+2])
|
||||||
|
|
||||||
# Generates a random name
|
# Generates a random name
|
||||||
def nameGen(self):
|
async def nameGen(self, ctx):
|
||||||
# Makes a list of all names from "names.txt"
|
# Makes a list of all names from "names.txt"
|
||||||
names = open('resources/names.txt', encoding='utf8').read()
|
names = open('resources/names.txt', encoding='utf8').read()
|
||||||
corpus = list(names)
|
corpus = list(names)
|
||||||
@ -74,11 +74,12 @@ class Generators():
|
|||||||
done = True
|
done = True
|
||||||
genName = "".join(chain)
|
genName = "".join(chain)
|
||||||
self.bot.log("Generated "+genName[:-1])
|
self.bot.log("Generated "+genName[:-1])
|
||||||
|
|
||||||
# Returns the name
|
# Returns the name
|
||||||
return(genName)
|
await ctx.send(genName)
|
||||||
|
|
||||||
# Generates a random tavern name
|
# Generates a random tavern name
|
||||||
def tavernGen(self):
|
async def tavernGen(self, ctx):
|
||||||
# Lists first parts, second parts and third parts of tavern names
|
# Lists first parts, second parts and third parts of tavern names
|
||||||
fp = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic","The Trusty","The Busty"]
|
fp = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic","The Trusty","The Busty"]
|
||||||
sp = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","Arsonist"]
|
sp = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","Arsonist"]
|
||||||
@ -89,4 +90,4 @@ class Generators():
|
|||||||
self.bot.log("Generated "+genTav)
|
self.bot.log("Generated "+genTav)
|
||||||
|
|
||||||
# Return the name
|
# Return the name
|
||||||
return(genTav)
|
await ctx.send(genTav)
|
||||||
|
@ -10,6 +10,8 @@ from .bedreNetflix import BedreNetflix
|
|||||||
from .nerdShit import NerdShit
|
from .nerdShit import NerdShit
|
||||||
from .generators import Generators
|
from .generators import Generators
|
||||||
|
|
||||||
|
from utils import cap
|
||||||
|
|
||||||
class MyStringifier(d20.MarkdownStringifier):
|
class MyStringifier(d20.MarkdownStringifier):
|
||||||
def _str_expression(self, node):
|
def _str_expression(self, node):
|
||||||
if node.comment == None:
|
if node.comment == None:
|
||||||
@ -57,29 +59,31 @@ class Other():
|
|||||||
await ctx.send(embed = embed)
|
await ctx.send(embed = embed)
|
||||||
|
|
||||||
# Responds with a greeting of a time-appropriate maner
|
# Responds with a greeting of a time-appropriate maner
|
||||||
def helloFunc(self, author):
|
async def helloFunc(self, ctx):
|
||||||
def time_in_range(start, end, x):
|
def time_in_range(start, end, x):
|
||||||
# Return true if x is in the range [start, end]
|
# Return true if x is in the range [start, end]
|
||||||
if start <= end:
|
if start <= end:
|
||||||
return start <= x <= end
|
return start <= x <= end
|
||||||
else:
|
else:
|
||||||
return start <= x or x <= end
|
return start <= x or x <= end
|
||||||
|
|
||||||
|
author = ctx.author.display_name
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
if time_in_range(now.replace(hour=5, minute=0, second=0, microsecond=0),now.replace(hour=10, minute=0, second=0, microsecond=0), now):
|
if time_in_range(now.replace(hour=5, minute=0, second=0, microsecond=0),now.replace(hour=10, minute=0, second=0, microsecond=0), now):
|
||||||
return("Good morning, "+str(author))
|
sendMessage = "Good morning, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=10, minute=0, second=0, microsecond=0),now.replace(hour=13, minute=0, second=0, microsecond=0), now):
|
|
||||||
return("Good day, "+str(author))
|
|
||||||
elif time_in_range(now.replace(hour=13, minute=0, second=0, microsecond=0),now.replace(hour=18, minute=0, second=0, microsecond=0), now):
|
elif time_in_range(now.replace(hour=13, minute=0, second=0, microsecond=0),now.replace(hour=18, minute=0, second=0, microsecond=0), now):
|
||||||
return("Good afternoon, "+str(author))
|
sendMessage = "Good afternoon, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=18, minute=0, second=0, microsecond=0),now.replace(hour=22, minute=0, second=0, microsecond=0), now):
|
elif time_in_range(now.replace(hour=18, minute=0, second=0, microsecond=0),now.replace(hour=22, minute=0, second=0, microsecond=0), now):
|
||||||
return("Good evening, "+str(author))
|
sendMessage = "Good evening, "+str(author)
|
||||||
elif time_in_range(now.replace(hour=22, minute=0, second=0, microsecond=0),now.replace(hour=23, minute=59, second=59, microsecond=0), now):
|
elif time_in_range(now.replace(hour=22, minute=0, second=0, microsecond=0),now.replace(hour=23, minute=59, second=59, microsecond=0), now):
|
||||||
return("Good night, "+str(author))
|
sendMessage = "Good night, "+str(author)
|
||||||
else:
|
else:
|
||||||
return("Hello, "+str(author))
|
sendMessage = "Hello, "+str(author)
|
||||||
|
|
||||||
|
await ctx.send(sendMessage)
|
||||||
|
|
||||||
# Finds a random picture online
|
# Finds a random picture online
|
||||||
def imageFunc(self):
|
async def imageFunc(self, ctx):
|
||||||
# Picks a type of camera, which decides the naming scheme
|
# Picks a type of camera, which decides the naming scheme
|
||||||
cams = ("one","two","three","four")
|
cams = ("one","two","three","four")
|
||||||
cam = random.choice(cams)
|
cam = random.choice(cams)
|
||||||
@ -113,22 +117,31 @@ class Other():
|
|||||||
tree = lxml.etree.HTML(read)
|
tree = lxml.etree.HTML(read)
|
||||||
images = tree.xpath('//a[@class = "thumb"]/@href')
|
images = tree.xpath('//a[@class = "thumb"]/@href')
|
||||||
|
|
||||||
# Picks an image
|
if len(images) == 0:
|
||||||
number = random.randint(1,len(images))-1
|
await ctx.send("Found no images")
|
||||||
image = images[number]
|
else:
|
||||||
|
# Picks an image
|
||||||
|
number = random.randint(1,len(images))-1
|
||||||
|
image = images[number]
|
||||||
|
|
||||||
self.bot.log("Picked image number "+str(number))
|
self.bot.log("Picked image number "+str(number))
|
||||||
|
|
||||||
# Returns the image
|
# Returns the image
|
||||||
self.bot.log("Successfully returned an image")
|
self.bot.log("Successfully returned an image")
|
||||||
return(image)
|
|
||||||
|
await ctx.send(image)
|
||||||
|
|
||||||
# Finds a page from the Senkulpa Wikia
|
# Finds a page from the Senkulpa Wikia
|
||||||
def findWikiPage(self, search : str):
|
async def findWikiPage(self, ctx, search : str):
|
||||||
|
await ctx.defer()
|
||||||
|
search = cap(search)
|
||||||
|
foundPage = False
|
||||||
|
|
||||||
self.bot.log("Trying to find wiki page for "+search)
|
self.bot.log("Trying to find wiki page for "+search)
|
||||||
wikia.set_lang("da")
|
wikia.set_lang("da")
|
||||||
searchResults = wikia.search("senkulpa",search)
|
searchResults = wikia.search("senkulpa",search)
|
||||||
if len(searchResults) > 0:
|
if len(searchResults) > 0:
|
||||||
|
foundPage = True
|
||||||
searchResult = searchResults[0].replace(",","%2C")
|
searchResult = searchResults[0].replace(",","%2C")
|
||||||
self.bot.log("Found page \""+searchResult+"\"")
|
self.bot.log("Found page \""+searchResult+"\"")
|
||||||
page = wikia.page("senkulpa",searchResult)
|
page = wikia.page("senkulpa",searchResult)
|
||||||
@ -137,15 +150,39 @@ class Other():
|
|||||||
images = page.images
|
images = page.images
|
||||||
if len(images) > 0:
|
if len(images) > 0:
|
||||||
image = images[len(images)-1]+"/revision/latest?path-prefix=da"
|
image = images[len(images)-1]+"/revision/latest?path-prefix=da"
|
||||||
return page.title, content, image
|
|
||||||
else:
|
else:
|
||||||
return page.title, content, ""
|
image = ""
|
||||||
else:
|
else:
|
||||||
self.bot.log("Couldn't find the page (error code 1002)")
|
self.bot.log("Couldn't find the page")
|
||||||
return "", "Couldn't find page (error code 1002)", ""
|
await ctx.send("Couldn't find page (error code 1002)")
|
||||||
|
|
||||||
def rollDice(self, user, rollString):
|
if foundPage:
|
||||||
|
self.bot.log("Sending the embedded message",str(ctx.channel_id))
|
||||||
|
content += f"\n[Læs mere]({page.url})"
|
||||||
|
embed = discord.Embed(title = page.title, description = content, colour=0xDEADBF)
|
||||||
|
if image != "":
|
||||||
|
embed.set_thumbnail(url=image)
|
||||||
|
|
||||||
|
await ctx.send(embed = embed)
|
||||||
|
|
||||||
|
async def rollDice(self, ctx, rollString):
|
||||||
|
user = ctx.author.display_name
|
||||||
while len(rollString) > 1 and rollString[0] == " ":
|
while len(rollString) > 1 and rollString[0] == " ":
|
||||||
rollString = rollString[1:]
|
rollString = rollString[1:]
|
||||||
return user+" :game_die:\n"+str(d20.roll(rollString, allow_comments=True,stringifier=MyStringifier()))
|
|
||||||
|
roll = d20.roll(rollString, allow_comments=True, stringifier=MyStringifier())
|
||||||
|
await ctx.send(f"{user} :game_die:\n{roll}")
|
||||||
|
|
||||||
|
async def helpFunc(self, ctx, command):
|
||||||
|
if command == "":
|
||||||
|
with open("resources/help/help.txt",encoding="utf-8") as f:
|
||||||
|
text = f.read()
|
||||||
|
em = discord.Embed(title = "Help", description = text,colour = 0x59f442)
|
||||||
|
await ctx.send(embed = em)
|
||||||
|
else:
|
||||||
|
self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id))
|
||||||
|
with open(f"resources/help/help-{command}.txt",encoding="utf-8") as f:
|
||||||
|
text = f.read()
|
||||||
|
em = discord.Embed(title = command.capitalize(), description = text,colour = 0x59f442)
|
||||||
|
await ctx.send(embed = em)
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import string
|
import string
|
||||||
|
import discord
|
||||||
|
|
||||||
class StarWarsChar():
|
class StarWarsChar():
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
@ -470,7 +471,10 @@ class StarWarsChar():
|
|||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def parseChar(self,user : str, cmd : str):
|
async def parseChar(self, ctx, parameters : str):
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
|
cmd = string.capwords(parameters.replace("+","+ ").replace("-","- ").replace(",",", "))
|
||||||
|
returnEmbed = False
|
||||||
|
|
||||||
cmd = self.replaceSpaces(cmd)
|
cmd = self.replaceSpaces(cmd)
|
||||||
|
|
||||||
@ -487,8 +491,9 @@ class StarWarsChar():
|
|||||||
|
|
||||||
if cmd == "":
|
if cmd == "":
|
||||||
if userCharacter != None:
|
if userCharacter != None:
|
||||||
text1, text2 = self.characterSheet(userCharacter)
|
title, text = self.characterSheet(userCharacter)
|
||||||
return text1, self.replaceWithSpaces(text2)
|
text = self.replaceWithSpaces(text)
|
||||||
|
returnEmbed = True
|
||||||
else:
|
else:
|
||||||
self.bot.log("Makin' a character for "+self.bot.databaseFuncs.getName(user))
|
self.bot.log("Makin' a character for "+self.bot.databaseFuncs.getName(user))
|
||||||
with open("resources/starWars/starwarstemplates.json", "r") as f:
|
with open("resources/starWars/starwarstemplates.json", "r") as f:
|
||||||
@ -496,14 +501,20 @@ class StarWarsChar():
|
|||||||
newChar = templates["Character"]
|
newChar = templates["Character"]
|
||||||
newChar["_id"] = user
|
newChar["_id"] = user
|
||||||
self.bot.database["starwars characters"].insert_one(newChar)
|
self.bot.database["starwars characters"].insert_one(newChar)
|
||||||
return "", "Character for " + self.bot.databaseFuncs.getName(user) + " created"
|
await ctx.send("Character for " + self.bot.databaseFuncs.getName(user) + " created")
|
||||||
else:
|
else:
|
||||||
if cmd == "Purge":
|
if cmd == "Purge":
|
||||||
self.bot.log("Deleting "+self.bot.databaseFuncs.getName(user)+"'s character")
|
self.bot.log("Deleting "+self.bot.databaseFuncs.getName(user)+"'s character")
|
||||||
self.bot.database["starwars characters"].delete_one({"_id":user})
|
self.bot.database["starwars characters"].delete_one({"_id":user})
|
||||||
return "", "Character for " + self.bot.databaseFuncs.getName(user) + " deleted"
|
await ctx.send("Character for " + self.bot.databaseFuncs.getName(user) + " deleted")
|
||||||
else:
|
else:
|
||||||
return "", self.replaceWithSpaces(str(self.charData(user,cmd)))
|
await ctx.send(self.replaceWithSpaces(str(self.charData(user,cmd))))
|
||||||
|
|
||||||
|
if returnEmbed:
|
||||||
|
em = discord.Embed(title = title, description = text, colour=0xDEADBF)
|
||||||
|
await ctx.send(embed = em)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def lightsaberChar(self,user : str):
|
def lightsaberChar(self,user : str):
|
||||||
userCharacter = self.bot.database["starwars characters"].find_one({"_id":user})
|
userCharacter = self.bot.database["starwars characters"].find_one({"_id":user})
|
||||||
|
@ -4,13 +4,13 @@ class StarWarsDestiny():
|
|||||||
|
|
||||||
def destinyNew(self, num : int):
|
def destinyNew(self, num : int):
|
||||||
self.bot.log("Creating a new destiny pool with "+str(num)+" players")
|
self.bot.log("Creating a new destiny pool with "+str(num)+" players")
|
||||||
roll, diceResults = self.bot.starwarsroll.roll(0,0,0,0,0,0,num)
|
roll, diceResults = self.bot.starWars.roll.roll(0,0,0,0,0,0,num)
|
||||||
roll = "".join(sorted(roll))
|
roll = "".join(sorted(roll))
|
||||||
|
|
||||||
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
||||||
f.write(roll)
|
f.write(roll)
|
||||||
|
|
||||||
return "Rolled for Destiny Points and got:\n"+self.bot.starwarsroll.diceResultToEmoji(diceResults)+"\n"+self.bot.starwarsroll.resultToEmoji(roll)
|
return "Rolled for Destiny Points and got:\n"+self.bot.starWars.roll.diceResultToEmoji(diceResults)+"\n"+self.bot.starWars.roll.resultToEmoji(roll)
|
||||||
|
|
||||||
def destinyUse(self, user : str):
|
def destinyUse(self, user : str):
|
||||||
with open("resources/starWars/destinyPoints.txt","rt") as f:
|
with open("resources/starWars/destinyPoints.txt","rt") as f:
|
||||||
@ -24,7 +24,7 @@ class StarWarsDestiny():
|
|||||||
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
||||||
f.write(points)
|
f.write(points)
|
||||||
self.bot.log("Did it")
|
self.bot.log("Did it")
|
||||||
return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.starwarsroll.resultToEmoji(points)
|
return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.starWars.roll.resultToEmoji(points)
|
||||||
else:
|
else:
|
||||||
self.bot.log("There were no dark side destiny points")
|
self.bot.log("There were no dark side destiny points")
|
||||||
return "No dark side destiny points"
|
return "No dark side destiny points"
|
||||||
@ -36,31 +36,37 @@ class StarWarsDestiny():
|
|||||||
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
||||||
f.write(points)
|
f.write(points)
|
||||||
self.bot.log("Did it")
|
self.bot.log("Did it")
|
||||||
return "Used a light side destiny point. Destiny pool is now:\n"+self.bot.starwarsroll.resultToEmoji(points)
|
return "Used a light side destiny point. Destiny pool is now:\n"+self.bot.starWars.roll.resultToEmoji(points)
|
||||||
else:
|
else:
|
||||||
self.bot.log("There were no dark side destiny points")
|
self.bot.log("There were no dark side destiny points")
|
||||||
return "No light side destiny points"
|
return "No light side destiny points"
|
||||||
|
|
||||||
def parseDestiny(self, user : str, cmd : str):
|
async def parseDestiny(self, ctx, cmd : str):
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
if cmd != "":
|
if cmd != "":
|
||||||
while cmd[0] == ' ':
|
while cmd[0] == ' ':
|
||||||
cmd = cmd[1:]
|
cmd = cmd[1:]
|
||||||
if cmd == "":
|
if cmd == "":
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
if cmd == "":
|
if cmd == "":
|
||||||
self.bot.log("Retrieving destiny pool info")
|
self.bot.log("Retrieving destiny pool info")
|
||||||
with open("resources/starWars/destinyPoints.txt","rt") as f:
|
with open("resources/starWars/destinyPoints.txt","rt") as f:
|
||||||
return self.bot.starwarsroll.resultToEmoji(f.read())
|
sendMessage = self.bot.starWars.roll.resultToEmoji(f.read())
|
||||||
else:
|
else:
|
||||||
commands = cmd.upper().split(" ")
|
commands = cmd.upper().split(" ")
|
||||||
if commands[0] == "N":
|
if commands[0] == "N":
|
||||||
if len(commands) > 1:
|
if len(commands) > 1:
|
||||||
return self.destinyNew(int(commands[1]))
|
sendMessage = self.destinyNew(int(commands[1]))
|
||||||
else:
|
else:
|
||||||
return "You need to give an amount of players (error code 921)"
|
sendMessage = "You need to give an amount of players (error code 921)"
|
||||||
elif commands[0] == "U":
|
elif commands[0] == "U":
|
||||||
return self.destinyUse(user)
|
sendMessage = self.destinyUse(user)
|
||||||
else:
|
else:
|
||||||
return "I didn't quite understand that (error code 922)"
|
sendMessage = "I didn't quite understand that (error code 922)"
|
||||||
|
|
||||||
|
messageList = sendMessage.split("\n")
|
||||||
|
await ctx.send(messageList[0])
|
||||||
|
if len(messageList) > 1:
|
||||||
|
for messageItem in messageList[1:]:
|
||||||
|
await ctx.channel.send(messageItem)
|
||||||
|
@ -239,7 +239,7 @@ class StarWarsRoll():
|
|||||||
return random.choice(table)
|
return random.choice(table)
|
||||||
|
|
||||||
# Rolls for critical injury
|
# Rolls for critical injury
|
||||||
def critRoll(self, addington : int):
|
async def critRoll(self, ctx, addington : int):
|
||||||
dd = "<:difficulty:690973992470708296>"
|
dd = "<:difficulty:690973992470708296>"
|
||||||
sd = "<:setback:690972157890658415>"
|
sd = "<:setback:690972157890658415>"
|
||||||
bd = "<:boost:690972178216386561>"
|
bd = "<:boost:690972178216386561>"
|
||||||
@ -253,14 +253,14 @@ class StarWarsRoll():
|
|||||||
"**Discouraging Wound**: Flip one light side Destiny point to a dark side Destiny point (reverse if NPC), "+dd] * 5 + [
|
"**Discouraging Wound**: Flip one light side Destiny point to a dark side Destiny point (reverse if NPC), "+dd] * 5 + [
|
||||||
"**Stunned**: The target is staggered until the end of his next turn, "+dd] * 5 + [
|
"**Stunned**: The target is staggered until the end of his next turn, "+dd] * 5 + [
|
||||||
"**Stinger**: Increase the difficulty of next check by one, "+dd] * 5 + [
|
"**Stinger**: Increase the difficulty of next check by one, "+dd] * 5 + [
|
||||||
"**Bowled Over**: The target is knocked prone and suffers 1 sttrain, "+dd+dd] * 5 + [
|
"**Bowled Over**: The target is knocked prone and suffers 1 strain, "+dd+dd] * 5 + [
|
||||||
"**Head Ringer**: The target increases the difficulty of all Intellect and Cunning checks by one until the end of the encounter, "+dd+dd] * 5 + [
|
"**Head Ringer**: The target increases the difficulty of all Intellect and Cunning checks by one until the end of the encounter, "+dd+dd] * 5 + [
|
||||||
"**Fearsome Wound**: The target increases the difficulty of all Presence and Willpower checks by one until the end of the encounter, "+dd+dd] * 5 + [
|
"**Fearsome Wound**: The target increases the difficulty of all Presence and Willpower checks by one until the end of the encounter, "+dd+dd] * 5 + [
|
||||||
"**Agonizing Wound**: The target increases the difficulty of all Brawn and Agility checks by one until the end of the encounter, "+dd+dd] * 5 + [
|
"**Agonizing Wound**: The target increases the difficulty of all Brawn and Agility checks by one until the end of the encounter, "+dd+dd] * 5 + [
|
||||||
"**Slightly Dazed**: The target is disoriented until the end of the encounter, "+dd+dd] * 5 + [
|
"**Slightly Dazed**: The target is disoriented until the end of the encounter, "+dd+dd] * 5 + [
|
||||||
"**Scattered Senses**: The target removes all "+bd+" from skill checks until the end of the encounter, "+dd+dd] * 5 + [
|
"**Scattered Senses**: The target removes all "+bd+" from skill checks until the end of the encounter, "+dd+dd] * 5 + [
|
||||||
"**Hamstrung**: The target loses his free maneuver until the end of the encounter, "+dd+dd] * 5 + [
|
"**Hamstrung**: The target loses his free maneuver until the end of the encounter, "+dd+dd] * 5 + [
|
||||||
"**Overpowered**: The target leaves himselp open, and the attacker may immediately attempt another free attack agains him, using the exact same pool as the original, "+dd+dd] * 5 + [
|
"**Overpowered**: The target leaves himself open, and the attacker may immediately attempt another free attack agains him, using the exact same pool as the original, "+dd+dd] * 5 + [
|
||||||
"**Winded**: Until the end of the encounter, the target cannot voluntarily suffer strain to activate any abilities or gain additional maneuvers, "+dd+dd] * 5 + [
|
"**Winded**: Until the end of the encounter, the target cannot voluntarily suffer strain to activate any abilities or gain additional maneuvers, "+dd+dd] * 5 + [
|
||||||
"**Compromised**: Incerase difficulty of all skill checks by one until the end of the encounter, "+dd+dd] * 5 + [
|
"**Compromised**: Incerase difficulty of all skill checks by one until the end of the encounter, "+dd+dd] * 5 + [
|
||||||
"**At the brink**: The target suffers 1 strain each time he performs an action, "+dd+dd+dd] * 5 + [
|
"**At the brink**: The target suffers 1 strain each time he performs an action, "+dd+dd+dd] * 5 + [
|
||||||
@ -288,56 +288,64 @@ class StarWarsRoll():
|
|||||||
characteristic = random.choice(["brawn"] * 3 + ["agility"] * 3 + ["intellect", "cunning", "presence"])
|
characteristic = random.choice(["brawn"] * 3 + ["agility"] * 3 + ["intellect", "cunning", "presence"])
|
||||||
results = "**Gruesome Injury**: The target's "+characteristic+" is permanently one lower, "+dd+dd+dd+dd
|
results = "**Gruesome Injury**: The target's "+characteristic+" is permanently one lower, "+dd+dd+dd+dd
|
||||||
|
|
||||||
return "Roll: "+str(roll)+"\nInjury:\n"+results
|
sendMessage = "Roll: "+str(roll)+"\nInjury:\n"+results
|
||||||
|
|
||||||
|
messageList = sendMessage.split("\n")
|
||||||
|
await ctx.send(messageList[0])
|
||||||
|
if len(messageList) > 1:
|
||||||
|
for messageItem in messageList[1:]:
|
||||||
|
await ctx.channel.send(messageItem)
|
||||||
|
|
||||||
# Parses the command into something the other functions understand
|
# Parses the command into something the other functions understand
|
||||||
def parseRoll(self, user : str,cmd : str = ""):
|
async def parseRoll(self, ctx, cmd : str = ""):
|
||||||
|
user = f"#{ctx.author.id}"
|
||||||
cmd = re.sub(' +',' ',cmd.upper()) + " "
|
cmd = re.sub(' +',' ',cmd.upper()) + " "
|
||||||
if cmd[0] == " ":
|
if cmd[0] == " ":
|
||||||
cmd = cmd[1:]
|
cmd = cmd[1:]
|
||||||
cmd = self.bot.starwarschar.replaceSpaces(string.capwords(cmd))
|
cmd = self.bot.starWars.character.replaceSpaces(string.capwords(cmd))
|
||||||
commands = cmd.split(" ")
|
commands = cmd.split(" ")
|
||||||
|
validCommand = False
|
||||||
|
|
||||||
if commands[0] == "":
|
if commands[0] == "":
|
||||||
rollParameters = [1,0,3,0,0,0,0]
|
rollParameters = [1,0,3,0,0,0,0]
|
||||||
else:
|
else:
|
||||||
rollParameters = [0,0,0,0,0,0,0]
|
rollParameters = [0,0,0,0,0,0,0]
|
||||||
|
|
||||||
if string.capwords(commands[0]) == "Obligations":
|
if string.capwords(commands[0]) == "Obligations":
|
||||||
try:
|
sendMessage = self.obligationRoll()
|
||||||
return self.obligationRoll()
|
|
||||||
except:
|
|
||||||
self.bot.log("Obligation fucked up (error code 911)")
|
|
||||||
return "An error ocurred (error code 911)"
|
|
||||||
|
|
||||||
elif string.capwords(commands[0]) in skillData:
|
elif string.capwords(commands[0]) in skillData:
|
||||||
self.bot.log("Oh look! This guy has skills!")
|
self.bot.log("Oh look! This guy has skills!")
|
||||||
if self.bot.starwarschar.userHasChar:
|
if self.bot.starWars.character.userHasChar(user):
|
||||||
self.bot.log("They have a character. That much we know")
|
self.bot.log("They have a character. That much we know")
|
||||||
skillLevel = self.bot.starwarschar.charData(user,"Skills " + string.capwords(commands[0]))
|
skillLevel = self.bot.starWars.character.charData(user,"Skills " + string.capwords(commands[0]))
|
||||||
|
|
||||||
if string.capwords(commands[0]) == "Lightsaber":
|
if string.capwords(commands[0]) == "Lightsaber":
|
||||||
self.bot.log("The skill is lightsaber")
|
self.bot.log("The skill is lightsaber")
|
||||||
charLevel = self.bot.starwarschar.charData(user,"Characteristics " + self.bot.starwarschar.lightsaberChar(user))
|
charLevel = self.bot.starWars.character.charData(user,"Characteristics " + self.bot.starWars.character.lightsaberChar(user))
|
||||||
else:
|
else:
|
||||||
charLevel = self.bot.starwarschar.charData(user,"Characteristics " + skillData[string.capwords(commands[0])])
|
charLevel = self.bot.starWars.character.charData(user,"Characteristics " + skillData[string.capwords(commands[0])])
|
||||||
|
|
||||||
abilityDice = abs(charLevel-skillLevel)
|
abilityDice = abs(charLevel-skillLevel)
|
||||||
proficiencyDice = min(skillLevel,charLevel)
|
proficiencyDice = min(skillLevel,charLevel)
|
||||||
|
|
||||||
commands = [str(abilityDice)] + [str(proficiencyDice)] + commands[1:]
|
commands = [str(abilityDice)] + [str(proficiencyDice)] + commands[1:]
|
||||||
self.bot.log("Converted skill to dice")
|
self.bot.log("Converted skill to dice")
|
||||||
|
validCommand = True
|
||||||
else:
|
else:
|
||||||
self.bot.log("Okay, no they don't i guess (error code 912)")
|
self.bot.log("Okay, no they don't i guess")
|
||||||
return "You don't have a user. You can make one with /starwarscharacter (error code 912)"
|
sendMessage = "You don't have a user. You can make one with /starwarscharacter"
|
||||||
|
|
||||||
elif string.capwords(commands[0]) in ["Ranged","Piloting"]:
|
elif string.capwords(commands[0]) in ["Ranged","Piloting"]:
|
||||||
self.bot.log("They fucked up writing the name of a ranged or piloting skill")
|
self.bot.log("They fucked up writing the name of a ranged or piloting skill")
|
||||||
if string.capwords(commands[0]) == "Ranged":
|
if string.capwords(commands[0]) == "Ranged":
|
||||||
return "Did you mean \"Ranged - Heavy\" or \"Ranged - Light\" (error code 913)"
|
sendMessage = "Did you mean \"Ranged - Heavy\" or \"Ranged - Light\" (error code 913)"
|
||||||
else:
|
else:
|
||||||
return "Did you mean \"Piloting - Planetary\" or \"Piloting - Space\" (error code 913)"
|
sendMessage = "Did you mean \"Piloting - Planetary\" or \"Piloting - Space\" (error code 913)"
|
||||||
|
else:
|
||||||
|
validCommand = True
|
||||||
|
|
||||||
try:
|
if validCommand:
|
||||||
self.bot.log("Converting commands to dice")
|
self.bot.log("Converting commands to dice")
|
||||||
for x, command in enumerate(commands):
|
for x, command in enumerate(commands):
|
||||||
if command != "":
|
if command != "":
|
||||||
@ -358,21 +366,26 @@ class StarWarsRoll():
|
|||||||
rollParameters[6] = int(command.replace("F",""))
|
rollParameters[6] = int(command.replace("F",""))
|
||||||
else:
|
else:
|
||||||
rollParameters[x] = int(command)
|
rollParameters[x] = int(command)
|
||||||
except:
|
|
||||||
self.bot.log("Someone fucked u-up! (it was them) (error code 914)")
|
|
||||||
return "Invalid input! (error code 914)"
|
|
||||||
|
|
||||||
self.bot.log("Rolling "+str(rollParameters))
|
self.bot.log("Rolling "+str(rollParameters))
|
||||||
rollResults, diceResults = self.roll(rollParameters[0],rollParameters[1],rollParameters[2],rollParameters[3],rollParameters[4],rollParameters[5],rollParameters[6])
|
rollResults, diceResults = self.roll(rollParameters[0],rollParameters[1],rollParameters[2],rollParameters[3],rollParameters[4],rollParameters[5],rollParameters[6])
|
||||||
|
|
||||||
simplified = self.simplify(rollResults)
|
simplified = self.simplify(rollResults)
|
||||||
|
|
||||||
name = self.bot.starwarschar.getCharName(user)
|
name = self.bot.starWars.character.getCharName(user)
|
||||||
|
|
||||||
self.bot.log("Returns results and simplified results")
|
self.bot.log("Returns results and simplified results")
|
||||||
|
|
||||||
if simplified == "":
|
if simplified == "":
|
||||||
return name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\nEverything cancels out!"
|
sendMessage = name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\nEverything cancels out!"
|
||||||
else:
|
else:
|
||||||
return name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\n" + self.resultToEmoji(simplified)
|
sendMessage = name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\n" + self.resultToEmoji(simplified)
|
||||||
|
|
||||||
|
messageList = sendMessage.split("\n")
|
||||||
|
await ctx.send(messageList[0])
|
||||||
|
if len(messageList) > 1:
|
||||||
|
for messageItem in messageList[1:]:
|
||||||
|
if messageItem == "":
|
||||||
|
self.bot.log("Tried to send empty message")
|
||||||
|
else:
|
||||||
|
await ctx.channel.send(messageItem)
|
||||||
|
@ -44,6 +44,7 @@ Comments, strings, variable names, class names, docstrings, as well as all other
|
|||||||
## Code Style
|
## Code Style
|
||||||
All the Python code should follow the [PEP 8 guidelines](https://www.python.org/dev/peps/pep-0008/), with the following differences:
|
All the Python code should follow the [PEP 8 guidelines](https://www.python.org/dev/peps/pep-0008/), with the following differences:
|
||||||
+ Variable and function names must be camelCase, and must fully consist of either full words or common/understandable abbreviations.
|
+ Variable and function names must be camelCase, and must fully consist of either full words or common/understandable abbreviations.
|
||||||
|
+ Use f-strings when applicable.
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
+ Comment lines should not exede 72 characters.
|
+ Comment lines should not exede 72 characters.
|
||||||
@ -84,7 +85,7 @@ All the Python code should follow the [PEP 8 guidelines](https://www.python.org/
|
|||||||
Code called by a command should not have `try` and `except` statements. All errors should be raised to the `on_command_error()` or `Command.error()` functions, where they can be dealt with.
|
Code called by a command should not have `try` and `except` statements. All errors should be raised to the `on_command_error()` or `Command.error()` functions, where they can be dealt with.
|
||||||
|
|
||||||
## Cogs
|
## Cogs
|
||||||
The `Command` methods in cogs should only exist to perform small tasks or call code from elsewhere in the Gwendolyn code. Therefore, a single `Command` method should not contain more than 3 lines of code and should not use any modules other than `Discord.py` and the Gwendolyn modules.
|
The `Command` methods in cogs should only exist to perform small tasks or call code from elsewhere in the Gwendolyn code. Therefore, a single `Command` method should not contain more than 3 lines of code and should not use any modules other than `Discord.py` and the Gwendolyn modules. If a cog method calls a function in Gwendolyn, ctx must be passed, and the function should handle sending messages.
|
||||||
|
|
||||||
## Codebase Management
|
## Codebase Management
|
||||||
### Folders
|
### Folders
|
||||||
@ -102,11 +103,11 @@ Things you should know about the logging:
|
|||||||
+ The function can take either a list of strings or a string as its first parameter. If the parameter is a string, it is converted to a list of 1 string.
|
+ The function can take either a list of strings or a string as its first parameter. If the parameter is a string, it is converted to a list of 1 string.
|
||||||
+ The first string in the list is printed. All strings in the list are logged to the log-file.
|
+ The first string in the list is printed. All strings in the list are logged to the log-file.
|
||||||
+ If the list is longer than 1 string, `(details in log)` is added to the printed string.
|
+ If the list is longer than 1 string, `(details in log)` is added to the printed string.
|
||||||
+ The level parameter is 20 by default, which means the level is `INFO`. 40 corresponds to a level of `ERROR`, and 10 corresponds to a level of `DEBUG`. Only use these levels when logging.
|
+ The level parameter is 20 by default, which means the level is `INFO`. 40 corresponds to a level of `ERROR`, and 25 corresponds to `print`.
|
||||||
+ Logs of level `DEBUG` are not printed.
|
+ Logs of level `INFO` are not printed.
|
||||||
+ Logs of level `ERROR` should only be created in the `on_command_error()` or `Command.error()` functions.
|
+ Logs of level `ERROR` should only be created in the `on_command_error()`, `on_error()` or `Command.error()` functions.
|
||||||
|
|
||||||
### Logging rules
|
### Logging rules
|
||||||
1. Never call the `logThis()` function from `/utils/utilFuncs/`. Always call `bot.log`.
|
1. Never call the `logThis()` function from `/utils/utilFuncs/`. Always call `bot.log`.
|
||||||
1. The `on_slash_command()` and `on_ready()` events are the only times log should be called at level 20.`DEBUG` level logs should be used for all other logging.
|
1. The `on_slash_command()` and `on_ready()` events are the only times log should be called at level 25. `INFO` level logs should be used for all other logging.
|
||||||
1. Always provide the channel id if available. Although you shouldn't pass the channel id to a function purely to use it in logs.
|
1. Always provide the channel id if available. Although you shouldn't pass the channel id to a function purely to use it in logs.
|
||||||
|
@ -6,7 +6,8 @@ cachetools==4.2.1
|
|||||||
certifi==2020.12.5
|
certifi==2020.12.5
|
||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
d20==1.0.4
|
d20==1.0.4
|
||||||
discord.py==1.6.0
|
discord-py-slash-command @ git+https://github.com/eunwoo1104/discord-py-slash-command.git@3c63f9fe9d186c8492e85c3153aff268f1dd5cae
|
||||||
|
discord.py==1.7.1
|
||||||
dnspython==2.1.0
|
dnspython==2.1.0
|
||||||
finnhub-python==2.1.0
|
finnhub-python==2.1.0
|
||||||
gitdb==4.0.7
|
gitdb==4.0.7
|
||||||
@ -14,7 +15,9 @@ GitPython==3.1.0
|
|||||||
greenlet==1.0.0
|
greenlet==1.0.0
|
||||||
idna==2.10
|
idna==2.10
|
||||||
IMDbPY==6.8
|
IMDbPY==6.8
|
||||||
|
inflect==5.3.0
|
||||||
jaraco.context==4.0.0
|
jaraco.context==4.0.0
|
||||||
|
jaraco.itertools==6.0.1
|
||||||
lark-parser==0.9.0
|
lark-parser==0.9.0
|
||||||
lxml==4.5.0
|
lxml==4.5.0
|
||||||
more-itertools==8.7.0
|
more-itertools==8.7.0
|
||||||
@ -24,9 +27,10 @@ numpy==1.18.2
|
|||||||
Pillow==7.1.1
|
Pillow==7.1.1
|
||||||
pymongo==3.11.3
|
pymongo==3.11.3
|
||||||
requests==2.25.1
|
requests==2.25.1
|
||||||
|
six==1.15.0
|
||||||
smmap==4.0.0
|
smmap==4.0.0
|
||||||
soupsieve==2.2.1
|
soupsieve==2.2.1
|
||||||
SQLAlchemy==1.4.3
|
SQLAlchemy==1.4.5
|
||||||
typing-extensions==3.7.4.3
|
typing-extensions==3.7.4.3
|
||||||
urllib3==1.25.8
|
urllib3==1.25.8
|
||||||
websockets==8.1
|
websockets==8.1
|
||||||
|
@ -1 +1 @@
|
|||||||
Kommandoen `/blackjack` starter et spil blackjack. `/blackjack bet [beløb]` lader dig vædde en mængde af dine GwendoBucks. Du bruger `/blackjack hit`, `/blackjack stand`, `/blackjack split` og `/blackjack double` i løbet af spillet.
|
Kommandoen `/blackjack start` starter et spil blackjack. `/blackjack bet [beløb]` lader dig vædde en mængde af dine GwendoBucks. Du bruger `/blackjack hit`, `/blackjack stand`, `/blackjack split` og `/blackjack double` i løbet af spillet.
|
@ -40,6 +40,29 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"blackjackCards" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "cards",
|
||||||
|
"description" : "Get a count of the cards used in blackjack games"
|
||||||
|
},
|
||||||
|
"blackjackDouble" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "double",
|
||||||
|
"description" : "Double your bet in blackjack",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "hand",
|
||||||
|
"description" : "The number of the hand to double your bet on",
|
||||||
|
"type" : 4,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blackjackHilo" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "hilo",
|
||||||
|
"description" : "Get the current hi-lo value for the cards used in blackjack games"
|
||||||
|
},
|
||||||
"blackjackHit" : {
|
"blackjackHit" : {
|
||||||
"base" : "blackjack",
|
"base" : "blackjack",
|
||||||
"name" : "hit",
|
"name" : "hit",
|
||||||
@ -53,6 +76,24 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"blackjackShuffle" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "shuffle",
|
||||||
|
"description" : "Shuffle the cards used in blackjack games"
|
||||||
|
},
|
||||||
|
"blackjackSplit" : {
|
||||||
|
"base" : "blackjack",
|
||||||
|
"name" : "split",
|
||||||
|
"description" : "Split your hand in blackjack",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "hand",
|
||||||
|
"description" : "The number of the hand to split, in case you've already split once",
|
||||||
|
"type" : 4,
|
||||||
|
"required" : "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"blackjackStand" : {
|
"blackjackStand" : {
|
||||||
"base" : "blackjack",
|
"base" : "blackjack",
|
||||||
"name" : "stand",
|
"name" : "stand",
|
||||||
@ -99,23 +140,10 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"connectFourStop" : {
|
"connectFourSurrender" : {
|
||||||
"base" : "connectFour",
|
"base" : "connectFour",
|
||||||
"name" : "stop",
|
"name" : "surrender",
|
||||||
"description" : "Stop the game of connect four"
|
"description" : "Surrender the game of connect four"
|
||||||
},
|
|
||||||
"connectFourPlace" : {
|
|
||||||
"base" : "connectFour",
|
|
||||||
"name" : "place",
|
|
||||||
"description" : "Place a piece",
|
|
||||||
"options" : [
|
|
||||||
{
|
|
||||||
"name" : "column",
|
|
||||||
"description" : "The column to place the piece",
|
|
||||||
"type" : 4,
|
|
||||||
"required" : "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"downloading" : {
|
"downloading" : {
|
||||||
"name" : "downloading",
|
"name" : "downloading",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""A collections of utilities used by Gwendolyn and her functions"""
|
"""A collections of utilities used by Gwendolyn and her functions"""
|
||||||
|
|
||||||
__all__ = ["Options", "Credentials", "databaseFuncs", "getParams", "logThis", "cap", "makeFiles", "replaceMultiple", "emojiToCommand"]
|
__all__ = ["Options", "Credentials", "databaseFuncs", "EventHandler", "ErrorHandler", "getParams", "logThis", "cap", "makeFiles", "replaceMultiple", "emojiToCommand"]
|
||||||
|
|
||||||
from .helperClasses import Options, Credentials, databaseFuncs
|
from .helperClasses import Options, Credentials, databaseFuncs
|
||||||
|
from .eventHandlers import EventHandler, ErrorHandler
|
||||||
from .utilFunctions import getParams, logThis, cap, makeFiles, replaceMultiple, emojiToCommand
|
from .utilFunctions import getParams, logThis, cap, makeFiles, replaceMultiple, emojiToCommand
|
103
utils/eventHandlers.py
Normal file
103
utils/eventHandlers.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import discord, traceback, discord_slash, sys
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
from .utilFunctions import emojiToCommand
|
||||||
|
|
||||||
|
class EventHandler():
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
async def on_slash_command(self, ctx):
|
||||||
|
if ctx.subcommand_name is not None:
|
||||||
|
subcommand = f" {ctx.subcommand_name} "
|
||||||
|
else:
|
||||||
|
subcommand = " "
|
||||||
|
args = " ".join([str(i) for i in ctx.args])
|
||||||
|
fullCommand = f"/{ctx.command}{subcommand}{args}"
|
||||||
|
logMessage = f"{ctx.author.display_name} ran {fullCommand}"
|
||||||
|
self.bot.log(logMessage, str(ctx.channel_id), level = 25)
|
||||||
|
|
||||||
|
async def on_ready(self):
|
||||||
|
await self.bot.databaseFuncs.syncCommands()
|
||||||
|
self.bot.log("Logged in as "+self.bot.user.name+", "+str(self.bot.user.id), level = 25)
|
||||||
|
game = discord.Game("Use /help for commands")
|
||||||
|
await self.bot.change_presence(activity=game, status = discord.Status.online)
|
||||||
|
|
||||||
|
async def on_reaction_add(self, reaction, user):
|
||||||
|
if user.bot == False:
|
||||||
|
message = reaction.message
|
||||||
|
channel = message.channel
|
||||||
|
self.bot.log(f"{user.display_name} reacted to a message",str(channel.id))
|
||||||
|
try:
|
||||||
|
connectFourTheirTurn, piece = self.bot.databaseFuncs.connectFourReactionTest(channel,message,"#"+str(user.id))
|
||||||
|
except:
|
||||||
|
connectFourTheirTurn = False
|
||||||
|
|
||||||
|
bedreNetflixMessage, addMovie, imdbIds = self.bot.databaseFuncs.bedreNetflixReactionTest(channel, message)
|
||||||
|
|
||||||
|
if connectFourTheirTurn:
|
||||||
|
column = emojiToCommand(reaction.emoji)
|
||||||
|
await self.bot.games.connectFour.placePiece(message, f"#{user.id}", column-1)
|
||||||
|
elif bedreNetflixMessage and addMovie:
|
||||||
|
moviePick = emojiToCommand(reaction.emoji)
|
||||||
|
await message.delete()
|
||||||
|
if moviePick == "none":
|
||||||
|
imdbID = None
|
||||||
|
else:
|
||||||
|
imdbID = imdbIds[moviePick-1]
|
||||||
|
await self.bot.other.bedreNetflix.addMovie(channel,imdbID)
|
||||||
|
elif bedreNetflixMessage and not addMovie:
|
||||||
|
showPick = emojiToCommand(reaction.emoji)
|
||||||
|
await message.delete()
|
||||||
|
if showPick == "none":
|
||||||
|
imdbName = None
|
||||||
|
else:
|
||||||
|
imdbName = imdbIds[showPick-1]
|
||||||
|
await self.bot.other.bedreNetflix.addShow(channel,imdbName)
|
||||||
|
elif self.bot.databaseFuncs.hangmanReactionTest(channel, message, f"#{user.id}"):
|
||||||
|
self.bot.log("They reacted to the hangman message")
|
||||||
|
if ord(reaction.emoji) in range(127462,127488):
|
||||||
|
guess = chr(ord(reaction.emoji)-127397)
|
||||||
|
await self.bot.games.hangman.guess(message, f"#{user.id}", guess)
|
||||||
|
else:
|
||||||
|
self.bot.log("Bot they didn't react with a valid guess")
|
||||||
|
|
||||||
|
class ErrorHandler():
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
async def on_slash_command_error(self, ctx, error):
|
||||||
|
if isinstance(error, commands.CommandNotFound):
|
||||||
|
await ctx.send("That's not a command (error code 001)")
|
||||||
|
elif isinstance(error, discord.errors.NotFound):
|
||||||
|
self.bot.log("Deleted message before I could add all reactions")
|
||||||
|
elif isinstance(error, commands.errors.MissingRequiredArgument):
|
||||||
|
self.bot.log(f"{error}",str(ctx.channel_id))
|
||||||
|
await ctx.send("Missing command parameters (error code 002). Try using `!help [command]` to find out how to use the command.")
|
||||||
|
else:
|
||||||
|
exception = traceback.format_exception(type(error), error, error.__traceback__)
|
||||||
|
stopAt = "\nThe above exception was the direct cause of the following exception:\n\n"
|
||||||
|
if stopAt in exception:
|
||||||
|
index = exception.index(stopAt)
|
||||||
|
exception = exception[:index]
|
||||||
|
|
||||||
|
exceptionString = "".join(exception)
|
||||||
|
self.bot.log([f"exception in /{ctx.name}", f"{exceptionString}"],str(ctx.channel_id), 40)
|
||||||
|
if isinstance(error, discord.errors.NotFound):
|
||||||
|
self.bot.log("Context is non-existant", level = 40)
|
||||||
|
else:
|
||||||
|
await ctx.send("Something went wrong (error code 000)")
|
||||||
|
|
||||||
|
async def on_error(self, method):
|
||||||
|
errorType = sys.exc_info()[0]
|
||||||
|
if errorType == discord.errors.NotFound:
|
||||||
|
self.bot.log("Deleted message before I could add all reactions")
|
||||||
|
else:
|
||||||
|
exception = traceback.format_exc()
|
||||||
|
stopAt = "\nThe above exception was the direct cause of the following exception:\n\n"
|
||||||
|
if stopAt in exception:
|
||||||
|
index = exception.index(stopAt)
|
||||||
|
exception = exception[:index]
|
||||||
|
|
||||||
|
exceptionString = "".join(exception)
|
||||||
|
self.bot.log([f"exception in {method}", f"{exceptionString}"], level = 40)
|
@ -53,12 +53,12 @@ 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 "Gwendolyn"
|
||||||
|
elif user != None:
|
||||||
return user["user name"]
|
return user["user name"]
|
||||||
elif userID == "Gwendolyn":
|
|
||||||
return userID
|
|
||||||
else:
|
else:
|
||||||
self.bot.log("Couldn't find user "+userID)
|
self.bot.log(f"Couldn't find user {userID}")
|
||||||
return userID
|
return userID
|
||||||
|
|
||||||
def getID(self,userName):
|
def getID(self,userName):
|
||||||
@ -70,7 +70,7 @@ class databaseFuncs():
|
|||||||
self.bot.log("Couldn't find user "+userName)
|
self.bot.log("Couldn't find user "+userName)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def deleteGame(self, gameType,channel):
|
def deleteGame(self, gameType, channel):
|
||||||
self.bot.database[gameType].delete_one({"_id":channel})
|
self.bot.database[gameType].delete_one({"_id":channel})
|
||||||
|
|
||||||
def stopServer(self):
|
def stopServer(self):
|
||||||
@ -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("")
|
||||||
@ -100,7 +101,7 @@ class databaseFuncs():
|
|||||||
else:
|
else:
|
||||||
return False, 0
|
return False, 0
|
||||||
|
|
||||||
def hangmanReactionTest(self, channel,message):
|
def hangmanReactionTest(self, channel, message, user):
|
||||||
try:
|
try:
|
||||||
with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f:
|
with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f:
|
||||||
oldMessages = f.read().splitlines()
|
oldMessages = f.read().splitlines()
|
||||||
@ -111,8 +112,11 @@ class databaseFuncs():
|
|||||||
for oldMessage in oldMessages:
|
for oldMessage in oldMessages:
|
||||||
oldMessageID = int(oldMessage)
|
oldMessageID = int(oldMessage)
|
||||||
if message.id == oldMessageID:
|
if message.id == oldMessageID:
|
||||||
self.bot.log("They reacted to the hangman game")
|
game = self.bot.database["hangman games"].find_one({"_id":str(channel.id)})
|
||||||
gameMessage = True
|
if user == game["player"]:
|
||||||
|
gameMessage = True
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
return gameMessage
|
return gameMessage
|
||||||
|
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
import json
|
import json
|
||||||
import time
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from .helperClasses import Options
|
from .helperClasses import Options
|
||||||
|
|
||||||
|
FORMAT = " %(asctime)s | %(name)-16s | %(levelname)-8s | %(message)s"
|
||||||
|
PRINTFORMAT = "%(asctime)s - %(message)s"
|
||||||
|
DATEFORMAT = "%Y-%m-%d %H:%M:%S"
|
||||||
|
|
||||||
logging.addLevelName(25, "PRINT")
|
logging.addLevelName(25, "PRINT")
|
||||||
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
logging.basicConfig(format=FORMAT, datefmt=DATEFORMAT, level=logging.INFO, filename="gwendolyn.log")
|
||||||
|
logger = logging.getLogger("Gwendolyn")
|
||||||
|
printer = logging.getLogger("printer")
|
||||||
|
handler = logging.StreamHandler(sys.stdout)
|
||||||
|
handler.setFormatter(logging.Formatter(fmt = PRINTFORMAT, datefmt=DATEFORMAT))
|
||||||
|
printer.addHandler(handler)
|
||||||
|
printer.propagate = False
|
||||||
|
|
||||||
def getParams():
|
def getParams():
|
||||||
with open("resources/slashParameters.json", "r") as f:
|
with open("resources/slashParameters.json", "r") as f:
|
||||||
@ -20,25 +30,24 @@ def getParams():
|
|||||||
return params
|
return params
|
||||||
|
|
||||||
def logThis(messages, channel : str = "", level : int = 20):
|
def logThis(messages, channel : str = "", level : int = 20):
|
||||||
localtime = time.asctime(time.localtime(time.time()))
|
|
||||||
channel = channel.replace("Direct Message with ","")
|
channel = channel.replace("Direct Message with ","")
|
||||||
if type(messages) is str:
|
if type(messages) is str:
|
||||||
messages = [messages]
|
messages = [messages]
|
||||||
|
|
||||||
|
printMessage = messages[0]
|
||||||
|
|
||||||
for x, msg in enumerate(messages):
|
for x, msg in enumerate(messages):
|
||||||
if channel == "":
|
if channel != "":
|
||||||
messages[x] = localtime+" - "+msg
|
messages[x] = f"{msg} - ({channel})"
|
||||||
else:
|
|
||||||
messages[x] = localtime+" ("+channel+") - "+msg
|
|
||||||
|
|
||||||
if len(messages) > 1:
|
if len(messages) > 1:
|
||||||
messages[0] += " (details in log)"
|
printMessage += " (details in log)"
|
||||||
|
|
||||||
if level >= 25:
|
if level >= 25:
|
||||||
print(messages[0])
|
printer.log(level, printMessage)
|
||||||
|
|
||||||
for logMessage in messages:
|
for logMessage in messages:
|
||||||
logging.log(level, logMessage)
|
logger.log(level, logMessage)
|
||||||
|
|
||||||
# Capitalizes all words except some of them
|
# Capitalizes all words except some of them
|
||||||
def cap(s):
|
def cap(s):
|
||||||
|
Reference in New Issue
Block a user