:spakles: Database and OOP
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -151,6 +151,7 @@ static
|
|||||||
.vscode/
|
.vscode/
|
||||||
token.txt
|
token.txt
|
||||||
credentials.txt
|
credentials.txt
|
||||||
|
options.txt
|
||||||
resources/starWars/swcharacters.json
|
resources/starWars/swcharacters.json
|
||||||
resources/games/games.json
|
resources/games/games.json
|
||||||
resources/games/hexGames.json
|
resources/games/hexGames.json
|
||||||
|
20
Gwendolyn.py
20
Gwendolyn.py
@ -2,7 +2,7 @@ import discord, os, finnhub, pymongo
|
|||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
from funcs import logThis, makeFiles, transferUsers
|
from funcs import logThis, makeFiles, transferUsers, Money, Funcs, SwChar, SwDestiny, SwRoll, Games
|
||||||
|
|
||||||
commandPrefix = "!"
|
commandPrefix = "!"
|
||||||
|
|
||||||
@ -30,8 +30,22 @@ class Gwendolyn(commands.Bot):
|
|||||||
self.options = Options()
|
self.options = Options()
|
||||||
self.credentials = Credentials()
|
self.credentials = Credentials()
|
||||||
self.finnhubClient = finnhub.Client(api_key = self.credentials.finnhubKey)
|
self.finnhubClient = finnhub.Client(api_key = self.credentials.finnhubKey)
|
||||||
self.MongoClient = MongoClient(f"mongodb+srv://{self.credentials.mongoDBUser}:{self.credentials.mongoDBPassword}@gwendolyn.qkwfy.mongodb.net/Gwendolyn-Test?retryWrites=true&w=majority")
|
self.MongoClient = MongoClient(f"mongodb+srv://{self.credentials.mongoDBUser}:{self.credentials.mongoDBPassword}@gwendolyn.qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority")
|
||||||
self.database = self.MongoClient["Gwendolyn-Test"]
|
|
||||||
|
if self.options.testing:
|
||||||
|
self.database = self.MongoClient["Gwendolyn-Test"]
|
||||||
|
else:
|
||||||
|
self.database = self.MongoClient["Gwendolyn"]
|
||||||
|
|
||||||
|
self.swchar = SwChar(self)
|
||||||
|
self.swroll = SwRoll(self)
|
||||||
|
self.swdestiny = SwDestiny(self)
|
||||||
|
|
||||||
|
Games(self)
|
||||||
|
|
||||||
|
self.money = Money(self)
|
||||||
|
self.funcs = Funcs(self)
|
||||||
|
|
||||||
super().__init__(command_prefix=commandPrefix, case_insensitive=True)
|
super().__init__(command_prefix=commandPrefix, case_insensitive=True)
|
||||||
|
|
||||||
# Creates the required files
|
# Creates the required files
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import discord, asyncio
|
import discord, asyncio
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from funcs import logThis, triviaAnswer, triviaCountPoints, triviaStart, deleteGame, checkBalance, giveMoney, parseBlackjack, parseInvest, fiar, runMonopoly, runHex, runHangman
|
from funcs import logThis
|
||||||
|
|
||||||
class GamesCog(commands.Cog):
|
class GamesCog(commands.Cog):
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ class GamesCog(commands.Cog):
|
|||||||
# Checks user balance
|
# Checks user balance
|
||||||
@commands.command(aliases = ["b"])
|
@commands.command(aliases = ["b"])
|
||||||
async def balance(self, ctx):
|
async def balance(self, ctx):
|
||||||
response = checkBalance("#"+str(ctx.message.author.id))
|
response = self.client.money.checkBalance("#"+str(ctx.message.author.id))
|
||||||
if response == 1:
|
if response == 1:
|
||||||
new_message = ctx.message.author.display_name + " has " + str(response) + " GwendoBuck"
|
new_message = ctx.message.author.display_name + " has " + str(response) + " GwendoBuck"
|
||||||
else:
|
else:
|
||||||
@ -25,7 +25,7 @@ class GamesCog(commands.Cog):
|
|||||||
commands = content.split(" ")
|
commands = content.split(" ")
|
||||||
if len(commands) == 2:
|
if len(commands) == 2:
|
||||||
amount = int(commands[1])
|
amount = int(commands[1])
|
||||||
response = giveMoney("#"+str(ctx.message.author.id),commands[0],amount)
|
response = self.client.money.giveMoney("#"+str(ctx.message.author.id),commands[0],amount)
|
||||||
await ctx.send(response)
|
await ctx.send(response)
|
||||||
else:
|
else:
|
||||||
logThis("I didn't understand that (error code 1222)",str(ctx.message.channel.id))
|
logThis("I didn't understand that (error code 1222)",str(ctx.message.channel.id))
|
||||||
@ -34,7 +34,7 @@ class GamesCog(commands.Cog):
|
|||||||
# Invest GwendoBucks in the stock market
|
# Invest GwendoBucks in the stock market
|
||||||
@commands.command(aliases=["i"])
|
@commands.command(aliases=["i"])
|
||||||
async def invest(self, ctx, *, content = "check"):
|
async def invest(self, ctx, *, content = "check"):
|
||||||
response = parseInvest(content,"#"+str(ctx.message.author.id),self.client.finnhubClient)
|
response = self.client.invest.parseInvest(content,"#"+str(ctx.message.author.id))
|
||||||
if response.startswith("**"):
|
if response.startswith("**"):
|
||||||
responses = response.split("\n")
|
responses = response.split("\n")
|
||||||
em = discord.Embed(title=responses[0],description="\n".join(responses[1:]),colour=0x00FF00)
|
em = discord.Embed(title=responses[0],description="\n".join(responses[1:]),colour=0x00FF00)
|
||||||
@ -46,7 +46,7 @@ class GamesCog(commands.Cog):
|
|||||||
@commands.command()
|
@commands.command()
|
||||||
async def trivia(self, ctx, *, content = ""):
|
async def trivia(self, ctx, *, content = ""):
|
||||||
if content == "":
|
if content == "":
|
||||||
question, answers, correctAnswer = triviaStart(str(ctx.message.channel.id))
|
question, answers, correctAnswer = self.client.trivia.triviaStart(str(ctx.message.channel.id))
|
||||||
if answers != "":
|
if answers != "":
|
||||||
results = "**"+question+"**\n"
|
results = "**"+question+"**\n"
|
||||||
for x, answer in enumerate(answers):
|
for x, answer in enumerate(answers):
|
||||||
@ -56,9 +56,9 @@ class GamesCog(commands.Cog):
|
|||||||
|
|
||||||
await asyncio.sleep(60)
|
await asyncio.sleep(60)
|
||||||
|
|
||||||
triviaCountPoints(str(ctx.message.channel.id))
|
self.client.trivia.triviaCountPoints(str(ctx.message.channel.id))
|
||||||
|
|
||||||
deleteGame("trivia questions",str(ctx.message.channel.id))
|
self.client.funcs.deleteGame("trivia questions",str(ctx.message.channel.id))
|
||||||
|
|
||||||
logThis("Time's up for the trivia question",str(ctx.message.channel.id))
|
logThis("Time's up for the trivia question",str(ctx.message.channel.id))
|
||||||
await ctx.send("Time's up The answer was \""+chr(correctAnswer)+") "+answers[correctAnswer-97]+"\". Anyone who answered that has gotten 1 GwendoBuck")
|
await ctx.send("Time's up The answer was \""+chr(correctAnswer)+") "+answers[correctAnswer-97]+"\". Anyone who answered that has gotten 1 GwendoBuck")
|
||||||
@ -66,7 +66,7 @@ class GamesCog(commands.Cog):
|
|||||||
await ctx.send(question)
|
await ctx.send(question)
|
||||||
|
|
||||||
elif content in ["a","b","c","d"]:
|
elif content in ["a","b","c","d"]:
|
||||||
response = triviaAnswer("#"+str(ctx.message.author.id),str(ctx.message.channel.id),content)
|
response = self.client.trivia.triviaAnswer("#"+str(ctx.message.author.id),str(ctx.message.channel.id),content)
|
||||||
if response.startswith("Locked in "):
|
if response.startswith("Locked in "):
|
||||||
await ctx.message.add_reaction("👍")
|
await ctx.message.add_reaction("👍")
|
||||||
else:
|
else:
|
||||||
@ -78,27 +78,27 @@ class GamesCog(commands.Cog):
|
|||||||
# Runs a game of blackjack
|
# Runs a game of blackjack
|
||||||
@commands.command(aliases = ["bj"])
|
@commands.command(aliases = ["bj"])
|
||||||
async def blackjack(self, ctx, *, content = ""):
|
async def blackjack(self, ctx, *, content = ""):
|
||||||
await parseBlackjack(content,ctx)
|
await self.client.blackjack.parseBlackjack(content,ctx)
|
||||||
|
|
||||||
# Runs a game of Connect four
|
# Runs a game of Connect four
|
||||||
@commands.command(aliases = ["fiar","connect4","connectfour","4iar","4inarow"])
|
@commands.command(aliases = ["fiar","connect4","connectfour","4iar","4inarow"])
|
||||||
async def fourinarow(self, ctx, *, content = ""):
|
async def fourinarow(self, ctx, *, content = ""):
|
||||||
await fiar(ctx.message.channel,content,"#"+str(ctx.message.author.id))
|
await self.client.gameLoops.fiar(ctx.message.channel,content,"#"+str(ctx.message.author.id))
|
||||||
|
|
||||||
# Runs a game of Hex
|
|
||||||
@commands.command(name="hex")
|
|
||||||
async def hexCommand(self, ctx, *, content = ""):
|
|
||||||
await runHex(ctx.message.channel,content,"#"+str(ctx.message.author.id))
|
|
||||||
|
|
||||||
# Runs a game of Monopoly
|
# Runs a game of Monopoly
|
||||||
@commands.command(aliases = ["m","mon","mono"])
|
@commands.command(aliases = ["m","mon","mono"])
|
||||||
async def monopoly(self, ctx, *, content = ""):
|
async def monopoly(self, ctx, *, content = ""):
|
||||||
await runMonopoly(ctx.message.channel,content,"#"+str(ctx.message.author.id))
|
await self.client.gameLoops.runMonopoly(ctx.message.channel,content,"#"+str(ctx.message.author.id))
|
||||||
|
|
||||||
# Runs a game of Hangman
|
# Runs a game of Hangman
|
||||||
@commands.command(aliases = ["hm"])
|
@commands.command(aliases = ["hm"])
|
||||||
async def hangman(self, ctx, *, content = "start"):
|
async def hangman(self, ctx, *, content = "start"):
|
||||||
await runHangman(ctx.message.channel,"#"+str(ctx.message.author.id),self.client.credentials.wordnikKey,content)
|
await self.client.gameLoops.runHangman(ctx.message.channel,"#"+str(ctx.message.author.id),content)
|
||||||
|
|
||||||
|
# Runs a game of Hex
|
||||||
|
@commands.command(name="hex")
|
||||||
|
async def hexCommand(self, ctx, *, content = ""):
|
||||||
|
await self.client.gameLoops.runHex(ctx.message.channel,content,"#"+str(ctx.message.author.id))
|
||||||
|
|
||||||
def setup(client):
|
def setup(client):
|
||||||
client.add_cog(GamesCog(client))
|
client.add_cog(GamesCog(client))
|
@ -1,7 +1,7 @@
|
|||||||
import discord, codecs, string
|
import discord, codecs, string
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from funcs import logThis, stopServer, helloFunc, roll_dice, imageFunc, nameGen, tavernGen, movieFunc, cap, findWikiPage
|
from funcs import logThis, helloFunc, roll_dice, imageFunc, nameGen, tavernGen, movieFunc, cap, findWikiPage
|
||||||
|
|
||||||
class MiscCog(commands.Cog):
|
class MiscCog(commands.Cog):
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class MiscCog(commands.Cog):
|
|||||||
if "#"+str(ctx.message.author.id) in ["#266269899859427329", "#380732645602230272"]:
|
if "#"+str(ctx.message.author.id) in ["#266269899859427329", "#380732645602230272"]:
|
||||||
await ctx.send("Pulling git repo and restarting...")
|
await ctx.send("Pulling git repo and restarting...")
|
||||||
|
|
||||||
stopServer()
|
self.client.funcs.stopServer()
|
||||||
|
|
||||||
await self.client.logout()
|
await self.client.logout()
|
||||||
else:
|
else:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from funcs import logThis, fiarReactionTest, monopolyReactionTest, emojiToCommand, fiar, runMonopoly, hangmanReactionTest, runHangman
|
from funcs import logThis, emojiToCommand
|
||||||
|
|
||||||
class ReactionCog(commands.Cog):
|
class ReactionCog(commands.Cog):
|
||||||
def __init__(self, client):
|
def __init__(self, client):
|
||||||
@ -14,17 +14,17 @@ class ReactionCog(commands.Cog):
|
|||||||
channel = message.channel
|
channel = message.channel
|
||||||
logThis(user.display_name+" reacted to a message",str(channel.id))
|
logThis(user.display_name+" reacted to a message",str(channel.id))
|
||||||
try:
|
try:
|
||||||
fourInARowTheirTurn, piece = fiarReactionTest(channel,message,"#"+str(user.id))
|
fourInARowTheirTurn, piece = self.client.funcs.fiarReactionTest(channel,message,"#"+str(user.id))
|
||||||
except:
|
except:
|
||||||
fourInARowTheirTurn = False
|
fourInARowTheirTurn = False
|
||||||
|
|
||||||
if fourInARowTheirTurn:
|
if fourInARowTheirTurn:
|
||||||
place = emojiToCommand(reaction.emoji)
|
place = emojiToCommand(reaction.emoji)
|
||||||
await fiar(channel," place "+str(piece)+" "+str(place),user.id)
|
await self.client.gameLoops.fiar(channel," place "+str(piece)+" "+str(place),user.id)
|
||||||
elif monopolyReactionTest(channel,message):
|
elif self.client.funcs.monopolyReactionTest(channel,message):
|
||||||
await runMonopoly(channel,"roll","#"+str(user.id))
|
await self.client.gameLoops.runMonopoly(channel,"roll","#"+str(user.id))
|
||||||
elif hangmanReactionTest(channel,message):
|
elif self.client.funcs.hangmanReactionTest(channel,message):
|
||||||
guess = chr(ord(reaction.emoji)-127397)
|
guess = chr(ord(reaction.emoji)-127397)
|
||||||
await runHangman(channel,"#"+str(user.id),command="guess "+guess)
|
await self.client.gameLoops.runHangman(channel,"#"+str(user.id),command="guess "+guess)
|
||||||
def setup(client):
|
def setup(client):
|
||||||
client.add_cog(ReactionCog(client))
|
client.add_cog(ReactionCog(client))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import discord, string
|
import discord, string
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from funcs import parseRoll, parseDestiny, critRoll, parseChar, cap
|
from funcs import cap
|
||||||
|
|
||||||
class SwCog(commands.Cog):
|
class SwCog(commands.Cog):
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ class SwCog(commands.Cog):
|
|||||||
@commands.command()
|
@commands.command()
|
||||||
async def swroll(self, ctx, *, content):
|
async def swroll(self, ctx, *, content):
|
||||||
command = cap(content)
|
command = cap(content)
|
||||||
newMessage = parseRoll("#"+str(ctx.message.author.id),command)
|
newMessage = self.client.swroll.parseRoll("#"+str(ctx.message.author.id),command)
|
||||||
messageList = newMessage.split("\n")
|
messageList = newMessage.split("\n")
|
||||||
for messageItem in messageList:
|
for messageItem in messageList:
|
||||||
await ctx.send(messageItem)
|
await ctx.send(messageItem)
|
||||||
@ -21,7 +21,7 @@ class SwCog(commands.Cog):
|
|||||||
# Controls destiny points
|
# Controls destiny points
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def swd(self, ctx, *, content):
|
async def swd(self, ctx, *, content):
|
||||||
newMessage = parseDestiny("#"+str(ctx.message.author.id),content)
|
newMessage = self.client.swdestiny.parseDestiny("#"+str(ctx.message.author.id),content)
|
||||||
messageList = newMessage.split("\n")
|
messageList = newMessage.split("\n")
|
||||||
for messageItem in messageList:
|
for messageItem in messageList:
|
||||||
await ctx.send(messageItem)
|
await ctx.send(messageItem)
|
||||||
@ -29,7 +29,7 @@ class SwCog(commands.Cog):
|
|||||||
# Rolls for critical injuries
|
# Rolls for critical injuries
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def swcrit(self, ctx, arg : int = 0):
|
async def swcrit(self, ctx, arg : int = 0):
|
||||||
newMessage = critRoll(int(arg))
|
newMessage = self.client.swroll.critRoll(int(arg))
|
||||||
|
|
||||||
messageList = newMessage.split("\n")
|
messageList = newMessage.split("\n")
|
||||||
for messageItem in messageList:
|
for messageItem in messageList:
|
||||||
@ -40,7 +40,7 @@ class SwCog(commands.Cog):
|
|||||||
@commands.command(aliases=["sw"])
|
@commands.command(aliases=["sw"])
|
||||||
async def swchar(self, ctx, *, content = ""):
|
async def swchar(self, ctx, *, content = ""):
|
||||||
command = string.capwords(content.replace("+","+ ").replace("-","- ").replace(",",", "))
|
command = string.capwords(content.replace("+","+ ").replace("-","- ").replace(",",", "))
|
||||||
title, desc = parseChar("#"+str(ctx.message.author.id),command)
|
title, desc = self.client.swchar.parseChar("#"+str(ctx.message.author.id),command)
|
||||||
if title != "":
|
if title != "":
|
||||||
em1 = discord.Embed(title = title, description = desc, colour=0xDEADBF)
|
em1 = discord.Embed(title = title, description = desc, colour=0xDEADBF)
|
||||||
await ctx.send(embed = em1)
|
await ctx.send(embed = em1)
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
"""A collection of all Gwendolyn functions."""
|
"""A collection of all Gwendolyn functions."""
|
||||||
|
|
||||||
__all__ = ["helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToCommand", "fiarReactionTest", "deleteGame", "stopServer", "checkBalance", "giveMoney", "addMoney", "triviaCountPoints", "triviaStart", "triviaAnswer", "spellFunc", "monsterFunc", "nameGen", "tavernGen", "movieFunc", "roll_dice", "parseChar", "parseRoll", "critRoll", "parseDestiny", "addToDict", "getName", "getID", "replaceMultiple", "monopolyReactionTest","parseInvest", "fiar", "runMonopoly", "runHex", "runHangman","hangmanReactionTest", "parseBlackjack","transferUsers"]
|
#__all__ = ["Games" ,"helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToCommand", "Money", "spellFunc", "monsterFunc", "nameGen", "tavernGen", "movieFunc", "roll_dice", "SwChar", "SwDestiny", "SwRoll", "addToDict", "replaceMultiple", "transferUsers","Funcs"]
|
||||||
|
|
||||||
from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToCommand, fiarReactionTest, deleteGame, stopServer, addToDict, getName, getID, monopolyReactionTest, hangmanReactionTest, transferUsers
|
from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToCommand, addToDict, transferUsers
|
||||||
|
|
||||||
from .games import checkBalance, giveMoney, addMoney, triviaCountPoints, triviaStart, triviaAnswer, fiar, runMonopoly, runHex, runHangman, parseBlackjack, parseInvest
|
from .funcs import Funcs
|
||||||
|
|
||||||
|
from .games import Money, Games
|
||||||
|
|
||||||
from .lookup import spellFunc, monsterFunc
|
from .lookup import spellFunc, monsterFunc
|
||||||
|
|
||||||
@ -12,4 +14,4 @@ from .other import nameGen, tavernGen, movieFunc
|
|||||||
|
|
||||||
from .roll import roll_dice
|
from .roll import roll_dice
|
||||||
|
|
||||||
from .swfuncs import parseChar, parseRoll, parseDestiny, critRoll
|
from .swfuncs import SwChar, SwDestiny, SwRoll
|
||||||
|
84
funcs/funcs.py
Normal file
84
funcs/funcs.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
from .miscFuncs import logThis
|
||||||
|
import git # Used by stopServer()
|
||||||
|
|
||||||
|
class Funcs():
|
||||||
|
def __init__(self,bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
def getName(self,userID):
|
||||||
|
user = self.bot.database["users"].find_one({"_id":userID})
|
||||||
|
|
||||||
|
if user != None:
|
||||||
|
return user["user name"]
|
||||||
|
else:
|
||||||
|
logThis("Couldn't find user "+userID)
|
||||||
|
return userID
|
||||||
|
|
||||||
|
def getID(self,userName):
|
||||||
|
user = self.bot.database["users"].find_one({"user name":userName})
|
||||||
|
|
||||||
|
if user != None:
|
||||||
|
return user["_id"]
|
||||||
|
else:
|
||||||
|
logThis("Couldn't find user "+userName)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def deleteGame(self, gameType,channel):
|
||||||
|
self.bot.database[gameType].delete_one({"_id":channel})
|
||||||
|
|
||||||
|
def stopServer(self):
|
||||||
|
self.bot.database["trivia questions"].delete_many({})
|
||||||
|
self.bot.database["blackjack games"].delete_many({})
|
||||||
|
self.bot.database["4 in a row games"].delete_many({})
|
||||||
|
self.bot.database["hangman games"].delete_many({})
|
||||||
|
self.bot.database["hex games"].delete_many({})
|
||||||
|
self.bot.database["monopoly games"].delete_many({})
|
||||||
|
|
||||||
|
g = git.cmd.Git("")
|
||||||
|
g.pull()
|
||||||
|
|
||||||
|
def fiarReactionTest(self,channel,message,user):
|
||||||
|
game = self.bot.database["4 in a row games"].find_one({"_id":str(channel.id)})
|
||||||
|
|
||||||
|
with open("resources/games/oldImages/fourInARow"+str(channel.id), "r") as f:
|
||||||
|
oldImage = int(f.read())
|
||||||
|
|
||||||
|
if message.id == oldImage:
|
||||||
|
logThis("They reacted to the fourinarow game")
|
||||||
|
turn = game["turn"]
|
||||||
|
if user == game["players"][turn]:
|
||||||
|
return True, turn+1
|
||||||
|
else:
|
||||||
|
logThis("It wasn't their turn")
|
||||||
|
return False, 0
|
||||||
|
else:
|
||||||
|
return False, 0
|
||||||
|
|
||||||
|
def monopolyReactionTest(self,channel,message):
|
||||||
|
try:
|
||||||
|
with open("resources/games/oldImages/monopoly"+str(channel.id), "r") as f:
|
||||||
|
oldImage = int(f.read())
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if message.id == oldImage:
|
||||||
|
logThis("They reacted to the monopoly game")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def hangmanReactionTest(self, channel,message):
|
||||||
|
try:
|
||||||
|
with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f:
|
||||||
|
oldMessages = f.read().splitlines()
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
gameMessage = False
|
||||||
|
|
||||||
|
for oldMessage in oldMessages:
|
||||||
|
oldMessageID = int(oldMessage)
|
||||||
|
if message.id == oldMessageID:
|
||||||
|
logThis("They reacted to the hangman game")
|
||||||
|
gameMessage = True
|
||||||
|
|
||||||
|
return gameMessage
|
@ -1,9 +1,6 @@
|
|||||||
"""Functions for games Gwendolyn can play."""
|
"""Functions for games Gwendolyn can play."""
|
||||||
|
|
||||||
__all__ = ["checkBalance", "giveMoney", "addMoney","triviaCountPoints", "triviaStart", "triviaAnswer", "parseInvest", "blackjackLoop", "fiar", "runMonopoly", "runHex", "runHangman", "parseBlackjack"]
|
#__all__ = ["Money", "Games"]
|
||||||
|
|
||||||
from .money import checkBalance, giveMoney, addMoney
|
from .money import Money
|
||||||
from .trivia import triviaCountPoints, triviaStart, triviaAnswer
|
from .games import Games
|
||||||
from .invest import parseInvest
|
|
||||||
from .gameLoops import fiar, runMonopoly, runHex, runHangman
|
|
||||||
from .blackjackLoop import blackjackLoop, parseBlackjack
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,140 +1,142 @@
|
|||||||
import json
|
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
from funcs import logThis, getName
|
from funcs import logThis
|
||||||
|
|
||||||
border = 100
|
border = 100
|
||||||
placement = [0,0]
|
placement = [0,0]
|
||||||
rotation = 0
|
rotation = 0
|
||||||
def drawImage(channel):
|
|
||||||
logThis("Drawing blackjack table",channel)
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
fnt = ImageFont.truetype('resources/futura-bold.ttf', 50)
|
class DrawBlackjack():
|
||||||
fntSmol = ImageFont.truetype('resources/futura-bold.ttf', 40)
|
def __init__(self,bot):
|
||||||
borderSmol = int(border/3.5)
|
self.bot = bot
|
||||||
|
|
||||||
table = Image.open("resources/games/blackjackTable.png")
|
def drawImage(self,channel):
|
||||||
placement = [2,1,3,0,4]
|
logThis("Drawing blackjack table",channel)
|
||||||
textImage = ImageDraw.Draw(table)
|
game = self.bot.database["blackjack games"].find_one({"_id":channel})
|
||||||
hands = data["blackjack games"][channel]["user hands"]
|
|
||||||
|
|
||||||
dealerBusted = data["blackjack games"][channel]["dealer busted"]
|
fnt = ImageFont.truetype('resources/futura-bold.ttf', 50)
|
||||||
dealerBlackjack = data["blackjack games"][channel]["dealer blackjack"]
|
fntSmol = ImageFont.truetype('resources/futura-bold.ttf', 40)
|
||||||
|
borderSmol = int(border/3.5)
|
||||||
|
|
||||||
try:
|
table = Image.open("resources/games/blackjackTable.png")
|
||||||
if data["blackjack games"][channel]["all standing"] == False:
|
placement = [2,1,3,0,4]
|
||||||
dealerHand = drawHand(data["blackjack games"][channel]["dealer hand"],True,False,False)
|
textImage = ImageDraw.Draw(table)
|
||||||
else:
|
hands = game["user hands"]
|
||||||
dealerHand = drawHand(data["blackjack games"][channel]["dealer hand"],False,dealerBusted,dealerBlackjack)
|
|
||||||
except:
|
|
||||||
logThis("Error drawing dealer hand (error code 1341a)")
|
|
||||||
|
|
||||||
table.paste(dealerHand,(800-borderSmol,20-borderSmol),dealerHand)
|
dealerBusted = game["dealer busted"]
|
||||||
|
dealerBlackjack = game["dealer blackjack"]
|
||||||
|
|
||||||
for x in range(len(hands)):
|
|
||||||
key, value = list(hands.items())[x]
|
|
||||||
key = getName(key)
|
|
||||||
#logThis("Drawing "+key+"'s hand")
|
|
||||||
userHand = drawHand(value["hand"],False,value["busted"],value["blackjack"])
|
|
||||||
try:
|
try:
|
||||||
if value["split"] == 3:
|
if game["all standing"] == False:
|
||||||
table.paste(userHand,(32-borderSmol+(384*placement[x]),280-borderSmol),userHand)
|
dealerHand = self.drawHand(game["dealer hand"],True,False,False)
|
||||||
userOtherHand = drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
|
|
||||||
table.paste(userOtherHand,(32-borderSmol+(384*placement[x]),420-borderSmol),userOtherHand)
|
|
||||||
userThirdHand = drawHand(value["third hand"]["hand"],False,value["third hand"]["busted"],value["third hand"]["blackjack"])
|
|
||||||
table.paste(userThirdHand,(32-borderSmol+(384*placement[x]),560-borderSmol),userThirdHand)
|
|
||||||
userFourthHand = drawHand(value["fourth hand"]["hand"],False,value["fourth hand"]["busted"],value["fourth hand"]["blackjack"])
|
|
||||||
table.paste(userFourthHand,(32-borderSmol+(384*placement[x]),700-borderSmol),userFourthHand)
|
|
||||||
elif value["split"] == 2:
|
|
||||||
table.paste(userHand,(32-borderSmol+(384*placement[x]),420-borderSmol),userHand)
|
|
||||||
userOtherHand = drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
|
|
||||||
table.paste(userOtherHand,(32-borderSmol+(384*placement[x]),560-borderSmol),userOtherHand)
|
|
||||||
userThirdHand = drawHand(value["third hand"]["hand"],False,value["third hand"]["busted"],value["third hand"]["blackjack"])
|
|
||||||
table.paste(userThirdHand,(32-borderSmol+(384*placement[x]),700-borderSmol),userThirdHand)
|
|
||||||
elif value["split"] == 1:
|
|
||||||
table.paste(userHand,(32-borderSmol+(384*placement[x]),560-borderSmol),userHand)
|
|
||||||
userOtherHand = drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
|
|
||||||
table.paste(userOtherHand,(32-borderSmol+(384*placement[x]),700-borderSmol),userOtherHand)
|
|
||||||
else:
|
else:
|
||||||
table.paste(userHand,(32-borderSmol+(384*placement[x]),680-borderSmol),userHand)
|
dealerHand = self.drawHand(game["dealer hand"],False,dealerBusted,dealerBlackjack)
|
||||||
except:
|
except:
|
||||||
logThis("Error drawing player hands (error code 1341b)")
|
logThis("Error drawing dealer hand (error code 1341a)")
|
||||||
|
|
||||||
textWidth = fnt.getsize(key)[0]
|
table.paste(dealerHand,(800-borderSmol,20-borderSmol),dealerHand)
|
||||||
if textWidth < 360:
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2)-3,1010-3),key,fill=(0,0,0), font=fnt)
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2)+3,1010-3),key,fill=(0,0,0), font=fnt)
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2)-3,1010+3),key,fill=(0,0,0), font=fnt)
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2)+3,1010+3),key,fill=(0,0,0), font=fnt)
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2),1005),key,fill=(255,255,255), font=fnt)
|
|
||||||
else:
|
|
||||||
textWidth = fntSmol.getsize(key)[0]
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2)-2,1020-2),key,fill=(0,0,0), font=fntSmol)
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2)+2,1020-2),key,fill=(0,0,0), font=fntSmol)
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2)-2,1020+2),key,fill=(0,0,0), font=fntSmol)
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2)+2,1020+2),key,fill=(0,0,0), font=fntSmol)
|
|
||||||
textImage.text((32+(384*placement[x])+117-int(textWidth/2),1015),key,fill=(255,255,255), font=fntSmol)
|
|
||||||
|
|
||||||
logThis("Saving table image")
|
for x in range(len(hands)):
|
||||||
table.save("resources/games/blackjackTables/blackjackTable"+channel+".png")
|
key, value = list(hands.items())[x]
|
||||||
|
key = self.bot.funcs.getName(key)
|
||||||
|
#logThis("Drawing "+key+"'s hand")
|
||||||
|
userHand = self.drawHand(value["hand"],False,value["busted"],value["blackjack"])
|
||||||
|
try:
|
||||||
|
if value["split"] == 3:
|
||||||
|
table.paste(userHand,(32-borderSmol+(384*placement[x]),280-borderSmol),userHand)
|
||||||
|
userOtherHand = self.drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
|
||||||
|
table.paste(userOtherHand,(32-borderSmol+(384*placement[x]),420-borderSmol),userOtherHand)
|
||||||
|
userThirdHand = self.drawHand(value["third hand"]["hand"],False,value["third hand"]["busted"],value["third hand"]["blackjack"])
|
||||||
|
table.paste(userThirdHand,(32-borderSmol+(384*placement[x]),560-borderSmol),userThirdHand)
|
||||||
|
userFourthHand = self.drawHand(value["fourth hand"]["hand"],False,value["fourth hand"]["busted"],value["fourth hand"]["blackjack"])
|
||||||
|
table.paste(userFourthHand,(32-borderSmol+(384*placement[x]),700-borderSmol),userFourthHand)
|
||||||
|
elif value["split"] == 2:
|
||||||
|
table.paste(userHand,(32-borderSmol+(384*placement[x]),420-borderSmol),userHand)
|
||||||
|
userOtherHand = self.drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
|
||||||
|
table.paste(userOtherHand,(32-borderSmol+(384*placement[x]),560-borderSmol),userOtherHand)
|
||||||
|
userThirdHand = self.drawHand(value["third hand"]["hand"],False,value["third hand"]["busted"],value["third hand"]["blackjack"])
|
||||||
|
table.paste(userThirdHand,(32-borderSmol+(384*placement[x]),700-borderSmol),userThirdHand)
|
||||||
|
elif value["split"] == 1:
|
||||||
|
table.paste(userHand,(32-borderSmol+(384*placement[x]),560-borderSmol),userHand)
|
||||||
|
userOtherHand = self.drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
|
||||||
|
table.paste(userOtherHand,(32-borderSmol+(384*placement[x]),700-borderSmol),userOtherHand)
|
||||||
|
else:
|
||||||
|
table.paste(userHand,(32-borderSmol+(384*placement[x]),680-borderSmol),userHand)
|
||||||
|
except:
|
||||||
|
logThis("Error drawing player hands (error code 1341b)")
|
||||||
|
|
||||||
return
|
textWidth = fnt.getsize(key)[0]
|
||||||
|
if textWidth < 360:
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2)-3,1010-3),key,fill=(0,0,0), font=fnt)
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2)+3,1010-3),key,fill=(0,0,0), font=fnt)
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2)-3,1010+3),key,fill=(0,0,0), font=fnt)
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2)+3,1010+3),key,fill=(0,0,0), font=fnt)
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2),1005),key,fill=(255,255,255), font=fnt)
|
||||||
|
else:
|
||||||
|
textWidth = fntSmol.getsize(key)[0]
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2)-2,1020-2),key,fill=(0,0,0), font=fntSmol)
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2)+2,1020-2),key,fill=(0,0,0), font=fntSmol)
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2)-2,1020+2),key,fill=(0,0,0), font=fntSmol)
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2)+2,1020+2),key,fill=(0,0,0), font=fntSmol)
|
||||||
|
textImage.text((32+(384*placement[x])+117-int(textWidth/2),1015),key,fill=(255,255,255), font=fntSmol)
|
||||||
|
|
||||||
def drawHand(hand, dealer, busted, blackjack):
|
logThis("Saving table image")
|
||||||
logThis("Drawing hand "+str(hand))
|
table.save("resources/games/blackjackTables/blackjackTable"+channel+".png")
|
||||||
fnt = ImageFont.truetype('resources/futura-bold.ttf', 200)
|
|
||||||
fnt2 = ImageFont.truetype('resources/futura-bold.ttf', 120)
|
|
||||||
length = len(hand)
|
|
||||||
background = Image.new("RGBA", ((border*2)+691+(125*(length-1)),(border*2)+1065),(0,0,0,0))
|
|
||||||
textImage = ImageDraw.Draw(background)
|
|
||||||
|
|
||||||
if dealer:
|
return
|
||||||
img = Image.open("resources/games/cards/"+hand[0].upper()+".png")
|
|
||||||
#rotation = (random.randint(-20,20)/10.0)
|
def drawHand(self, hand, dealer, busted, blackjack):
|
||||||
img = img.rotate(rotation,expand = 1)
|
logThis("Drawing hand "+str(hand)+", "+str(busted)+", "+str(blackjack))
|
||||||
#placement = [random.randint(-20,20),random.randint(-20,20)]
|
fnt = ImageFont.truetype('resources/futura-bold.ttf', 200)
|
||||||
background.paste(img,(border+placement[0],border+placement[1]),img)
|
fnt2 = ImageFont.truetype('resources/futura-bold.ttf', 120)
|
||||||
img = Image.open("resources/games/cards/red_back.png")
|
length = len(hand)
|
||||||
#rotation = (random.randint(-20,20)/10.0)
|
background = Image.new("RGBA", ((border*2)+691+(125*(length-1)),(border*2)+1065),(0,0,0,0))
|
||||||
img = img.rotate(rotation,expand = 1)
|
textImage = ImageDraw.Draw(background)
|
||||||
#placement = [random.randint(-20,20),random.randint(-20,20)]
|
|
||||||
background.paste(img,(125+border+placement[0],border+placement[1]),img)
|
if dealer:
|
||||||
else:
|
img = Image.open("resources/games/cards/"+hand[0].upper()+".png")
|
||||||
for x in range(length):
|
|
||||||
img = Image.open("resources/games/cards/"+hand[x].upper()+".png")
|
|
||||||
#rotation = (random.randint(-20,20)/10.0)
|
#rotation = (random.randint(-20,20)/10.0)
|
||||||
img = img.rotate(rotation,expand = 1)
|
img = img.rotate(rotation,expand = 1)
|
||||||
#placement = [random.randint(-20,20),random.randint(-20,20)]
|
#placement = [random.randint(-20,20),random.randint(-20,20)]
|
||||||
background.paste(img,(border+(x*125)+placement[0],border+placement[1]),img)
|
background.paste(img,(border+placement[0],border+placement[1]),img)
|
||||||
|
img = Image.open("resources/games/cards/red_back.png")
|
||||||
w, h = background.size
|
#rotation = (random.randint(-20,20)/10.0)
|
||||||
textHeight = 290+border
|
img = img.rotate(rotation,expand = 1)
|
||||||
|
#placement = [random.randint(-20,20),random.randint(-20,20)]
|
||||||
|
background.paste(img,(125+border+placement[0],border+placement[1]),img)
|
||||||
|
else:
|
||||||
|
for x in range(length):
|
||||||
|
img = Image.open("resources/games/cards/"+hand[x].upper()+".png")
|
||||||
|
#rotation = (random.randint(-20,20)/10.0)
|
||||||
|
img = img.rotate(rotation,expand = 1)
|
||||||
|
#placement = [random.randint(-20,20),random.randint(-20,20)]
|
||||||
|
background.paste(img,(border+(x*125)+placement[0],border+placement[1]),img)
|
||||||
|
|
||||||
#logThis("Drawing busted/blackjack")
|
w, h = background.size
|
||||||
if busted:
|
textHeight = 290+border
|
||||||
textWidth = fnt.getsize("BUSTED")[0]
|
|
||||||
textImage.text((int(w/2)-int(textWidth/2)-10,textHeight+20-10),"BUSTED",fill=(0,0,0), font=fnt)
|
#logThis("Drawing busted/blackjack")
|
||||||
textImage.text((int(w/2)-int(textWidth/2)+10,textHeight+20-10),"BUSTED",fill=(0,0,0), font=fnt)
|
if busted:
|
||||||
textImage.text((int(w/2)-int(textWidth/2)-10,textHeight+20+10),"BUSTED",fill=(0,0,0), font=fnt)
|
textWidth = fnt.getsize("BUSTED")[0]
|
||||||
textImage.text((int(w/2)-int(textWidth/2)+10,textHeight+20+10),"BUSTED",fill=(0,0,0), font=fnt)
|
textImage.text((int(w/2)-int(textWidth/2)-10,textHeight+20-10),"BUSTED",fill=(0,0,0), font=fnt)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)-5,textHeight-5),"BUSTED",fill=(255,255,255), font=fnt)
|
textImage.text((int(w/2)-int(textWidth/2)+10,textHeight+20-10),"BUSTED",fill=(0,0,0), font=fnt)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)+5,textHeight-5),"BUSTED",fill=(255,255,255), font=fnt)
|
textImage.text((int(w/2)-int(textWidth/2)-10,textHeight+20+10),"BUSTED",fill=(0,0,0), font=fnt)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)-5,textHeight+5),"BUSTED",fill=(255,255,225), font=fnt)
|
textImage.text((int(w/2)-int(textWidth/2)+10,textHeight+20+10),"BUSTED",fill=(0,0,0), font=fnt)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)+5,textHeight+5),"BUSTED",fill=(255,255,255), font=fnt)
|
textImage.text((int(w/2)-int(textWidth/2)-5,textHeight-5),"BUSTED",fill=(255,255,255), font=fnt)
|
||||||
textImage.text((int(w/2)-int(textWidth/2),textHeight),"BUSTED",fill=(255,50,50), font=fnt)
|
textImage.text((int(w/2)-int(textWidth/2)+5,textHeight-5),"BUSTED",fill=(255,255,255), font=fnt)
|
||||||
elif blackjack:
|
textImage.text((int(w/2)-int(textWidth/2)-5,textHeight+5),"BUSTED",fill=(255,255,225), font=fnt)
|
||||||
textWidth = fnt2.getsize("BLACKJACK")[0]
|
textImage.text((int(w/2)-int(textWidth/2)+5,textHeight+5),"BUSTED",fill=(255,255,255), font=fnt)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)-6,textHeight+20-6),"BLACKJACK",fill=(0,0,0), font=fnt2)
|
textImage.text((int(w/2)-int(textWidth/2),textHeight),"BUSTED",fill=(255,50,50), font=fnt)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)+6,textHeight+20-6),"BLACKJACK",fill=(0,0,0), font=fnt2)
|
elif blackjack:
|
||||||
textImage.text((int(w/2)-int(textWidth/2)-6,textHeight+20+6),"BLACKJACK",fill=(0,0,0), font=fnt2)
|
textWidth = fnt2.getsize("BLACKJACK")[0]
|
||||||
textImage.text((int(w/2)-int(textWidth/2)+6,textHeight+20+6),"BLACKJACK",fill=(0,0,0), font=fnt2)
|
textImage.text((int(w/2)-int(textWidth/2)-6,textHeight+20-6),"BLACKJACK",fill=(0,0,0), font=fnt2)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)-3,textHeight-3),"BLACKJACK",fill=(255,255,255), font=fnt2)
|
textImage.text((int(w/2)-int(textWidth/2)+6,textHeight+20-6),"BLACKJACK",fill=(0,0,0), font=fnt2)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)+3,textHeight-3),"BLACKJACK",fill=(255,255,255), font=fnt2)
|
textImage.text((int(w/2)-int(textWidth/2)-6,textHeight+20+6),"BLACKJACK",fill=(0,0,0), font=fnt2)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)-3,textHeight+3),"BLACKJACK",fill=(255,255,255), font=fnt2)
|
textImage.text((int(w/2)-int(textWidth/2)+6,textHeight+20+6),"BLACKJACK",fill=(0,0,0), font=fnt2)
|
||||||
textImage.text((int(w/2)-int(textWidth/2)+3,textHeight+3),"BLACKJACK",fill=(255,255,255), font=fnt2)
|
textImage.text((int(w/2)-int(textWidth/2)-3,textHeight-3),"BLACKJACK",fill=(255,255,255), font=fnt2)
|
||||||
textImage.text((int(w/2)-int(textWidth/2),textHeight),"BLACKJACK",fill=(155,123,0), font=fnt2)
|
textImage.text((int(w/2)-int(textWidth/2)+3,textHeight-3),"BLACKJACK",fill=(255,255,255), font=fnt2)
|
||||||
|
textImage.text((int(w/2)-int(textWidth/2)-3,textHeight+3),"BLACKJACK",fill=(255,255,255), font=fnt2)
|
||||||
#logThis("Returning resized image")
|
textImage.text((int(w/2)-int(textWidth/2)+3,textHeight+3),"BLACKJACK",fill=(255,255,255), font=fnt2)
|
||||||
return background.resize((int(w/3.5),int(h/3.5)),resample=Image.BILINEAR)
|
textImage.text((int(w/2)-int(textWidth/2),textHeight),"BLACKJACK",fill=(155,123,0), font=fnt2)
|
||||||
|
|
||||||
|
#logThis("Returning resized image")
|
||||||
|
return background.resize((int(w/3.5),int(h/3.5)),resample=Image.BILINEAR)
|
||||||
|
@ -1,231 +0,0 @@
|
|||||||
import discord, json, os, asyncio
|
|
||||||
|
|
||||||
from .blackjack import blackjackContinue, blackjackSplit, blackjackShuffle, blackjackStart, blackjackFinish, blackjackPlayerDrawHand, blackjackHit, blackjackStand, blackjackDouble
|
|
||||||
from funcs import logThis
|
|
||||||
|
|
||||||
# Loop of blackjack game rounds
|
|
||||||
async def blackjackLoop(channel,gameRound,gameID):
|
|
||||||
logThis("Loop "+str(gameRound),str(channel.id))
|
|
||||||
|
|
||||||
with open("resources/games/oldImages/blackjack"+str(channel.id), "r") as f:
|
|
||||||
oldImage = await channel.fetch_message(int(f.read()))
|
|
||||||
|
|
||||||
new_message, allStanding, gamedone = blackjackContinue(str(channel.id))
|
|
||||||
if new_message != "":
|
|
||||||
logThis(new_message,str(channel.id))
|
|
||||||
await channel.send(new_message)
|
|
||||||
if gamedone == False:
|
|
||||||
await oldImage.delete()
|
|
||||||
oldImage = await channel.send(file = discord.File("resources/games/blackjackTables/blackjackTable"+str(channel.id)+".png"))
|
|
||||||
with open("resources/games/oldImages/blackjack"+str(channel.id), "w") as f:
|
|
||||||
f.write(str(oldImage.id))
|
|
||||||
|
|
||||||
try:
|
|
||||||
if allStanding:
|
|
||||||
await asyncio.sleep(5)
|
|
||||||
else:
|
|
||||||
await asyncio.sleep(120)
|
|
||||||
except:
|
|
||||||
logThis("Loop "+str(gameRound)+" interrupted (error code 1321)")
|
|
||||||
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if str(channel.id) in data["blackjack games"]:
|
|
||||||
realRound = data["blackjack games"][str(channel.id)]["round"]
|
|
||||||
realGameID = data["blackjack games"][str(channel.id)]["id"]
|
|
||||||
|
|
||||||
if gameRound == realRound and realGameID == gameID:
|
|
||||||
if gamedone == False:
|
|
||||||
logThis("Loop "+str(gameRound)+" calling blackjackLoop()",str(channel.id))
|
|
||||||
await blackjackLoop(channel,gameRound+1,gameID)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
new_message = blackjackFinish(str(channel.id))
|
|
||||||
except:
|
|
||||||
logThis("Something fucked up (error code 1310)")
|
|
||||||
await channel.send(new_message)
|
|
||||||
else:
|
|
||||||
logThis("Ending loop on round "+str(gameRound),str(channel.id))
|
|
||||||
else:
|
|
||||||
logThis("Ending loop on round "+str(gameRound),str(channel.id))
|
|
||||||
|
|
||||||
async def parseBlackjack(content, ctx):
|
|
||||||
# Blackjack shuffle variables
|
|
||||||
blackjackMinCards = 50
|
|
||||||
blackjackDecks = 4
|
|
||||||
|
|
||||||
channel = ctx.message.channel.id
|
|
||||||
# Starts the game
|
|
||||||
if content == "":
|
|
||||||
cardsLeft = 0
|
|
||||||
if os.path.exists("resources/games/blackjackCards/"+str(channel)+".txt"):
|
|
||||||
with open("resources/games/blackjackCards/"+str(channel)+".txt","r") as f:
|
|
||||||
for _ in f:
|
|
||||||
cardsLeft += 1
|
|
||||||
|
|
||||||
# Shuffles if not enough cards
|
|
||||||
if cardsLeft < blackjackMinCards:
|
|
||||||
blackjackShuffle(blackjackDecks,str(channel))
|
|
||||||
logThis("Shuffling the blackjack deck...",str(channel))
|
|
||||||
await ctx.send("Shuffling the deck...")
|
|
||||||
|
|
||||||
new_message = 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.send(new_message)
|
|
||||||
oldImage = await ctx.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
|
|
||||||
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
if len(data["blackjack games"][str(channel)]["user hands"]) == 0:
|
|
||||||
gamedone = True
|
|
||||||
await ctx.send("No one entered the game. Ending the game.")
|
|
||||||
gameID = data["blackjack games"][str(channel)]["id"]
|
|
||||||
|
|
||||||
# Loop of game rounds
|
|
||||||
if gamedone == False:
|
|
||||||
logThis("!blackjack calling blackjackLoop()",str(channel))
|
|
||||||
await blackjackLoop(ctx.message.channel,1,gameID)
|
|
||||||
else:
|
|
||||||
new_message = blackjackFinish(str(channel))
|
|
||||||
await ctx.send(new_message)
|
|
||||||
else:
|
|
||||||
await ctx.send(new_message)
|
|
||||||
|
|
||||||
# Entering game and placing bet
|
|
||||||
elif content.startswith("bet"):
|
|
||||||
commands = content.split(" ")
|
|
||||||
amount = int(commands[1])
|
|
||||||
response = blackjackPlayerDrawHand(str(channel),"#"+str(ctx.message.author.id),amount)
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
# Hitting
|
|
||||||
elif content.startswith("hit"):
|
|
||||||
if content == "hit":
|
|
||||||
response = blackjackHit(str(channel),"#"+str(ctx.message.author.id))
|
|
||||||
else:
|
|
||||||
commands = content.split(" ")
|
|
||||||
try:
|
|
||||||
handNumber = int(commands[1])
|
|
||||||
except:
|
|
||||||
handNumber = 0
|
|
||||||
response = blackjackHit(str(channel),"#"+str(ctx.message.author.id),handNumber)
|
|
||||||
|
|
||||||
if response.startswith("accept"):
|
|
||||||
await ctx.message.add_reaction("👍")
|
|
||||||
try:
|
|
||||||
if response[6] == "T":
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
gameID = json.load(f)["blackjack games"][str(channel)]["id"]
|
|
||||||
logThis("Hit calling blackjackLoop()",str(channel))
|
|
||||||
await blackjackLoop(ctx.message.channel,int(response[7:])+1,gameID)
|
|
||||||
except:
|
|
||||||
logThis("Something fucked up (error code 1320)",str(channel))
|
|
||||||
else:
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
|
|
||||||
# Standing
|
|
||||||
elif content.startswith("stand"):
|
|
||||||
if content == "hit":
|
|
||||||
response = blackjackStand(str(channel),"#"+str(ctx.message.author.id))
|
|
||||||
else:
|
|
||||||
commands = content.split(" ")
|
|
||||||
try:
|
|
||||||
handNumber = int(commands[1])
|
|
||||||
except:
|
|
||||||
handNumber = 0
|
|
||||||
response = blackjackStand(str(channel),"#"+str(ctx.message.author.id),handNumber)
|
|
||||||
|
|
||||||
if response.startswith("accept"):
|
|
||||||
await ctx.message.add_reaction("👍")
|
|
||||||
try:
|
|
||||||
if response[6] == "T":
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
gameID = json.load(f)["blackjack games"][str(channel)]["id"]
|
|
||||||
logThis("Stand calling blackjackLoop()",str(channel))
|
|
||||||
await blackjackLoop(ctx.message.channel,int(response[7:])+1,gameID)
|
|
||||||
except:
|
|
||||||
logThis("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 = blackjackDouble(str(channel),"#"+str(ctx.message.author.id),handNumber)
|
|
||||||
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
try:
|
|
||||||
if roundDone[0] == "T":
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
gameID = json.load(f)["blackjack games"][str(channel)]["id"]
|
|
||||||
logThis("Double calling blackjackLoop()",str(channel))
|
|
||||||
await blackjackLoop(ctx.message.channel,int(roundDone[1:])+1,gameID)
|
|
||||||
except:
|
|
||||||
logThis("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 = blackjackSplit(str(channel),"#"+str(ctx.message.author.id),handNumber)
|
|
||||||
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
try:
|
|
||||||
if roundDone[0] == "T":
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
gameID = json.load(f)["blackjack games"][str(channel)]["id"]
|
|
||||||
logThis("Split calling blackjackLoop()",str(channel))
|
|
||||||
await blackjackLoop(ctx.message.channel,int(roundDone[1:])+1,gameID)
|
|
||||||
except:
|
|
||||||
logThis("Something fucked up (error code 1320)")
|
|
||||||
|
|
||||||
# Returning current hi-lo value
|
|
||||||
elif content.startswith("hilo") and "#"+str(ctx.message.author.id) == "#266269899859427329":
|
|
||||||
if os.path.exists("resources/games/blackjackCards/"+str(channel)+".txt"):
|
|
||||||
with open("resources/games/hilo/"+str(channel)+".txt", "r") as f:
|
|
||||||
data = f.read()
|
|
||||||
else:
|
|
||||||
data = "0"
|
|
||||||
await ctx.send(data)
|
|
||||||
|
|
||||||
# Shuffles the blackjack deck
|
|
||||||
elif content.startswith("shuffle"):
|
|
||||||
blackjackShuffle(blackjackDecks,str(channel))
|
|
||||||
logThis("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
|
|
||||||
if os.path.exists("resources/games/blackjackCards/"+str(channel)+".txt"):
|
|
||||||
with open("resources/games/blackjackCards/"+str(channel)+".txt","r") as f:
|
|
||||||
for _ in f:
|
|
||||||
cardsLeft += 1
|
|
||||||
|
|
||||||
decksLeft = round(cardsLeft/52,1)
|
|
||||||
await ctx.send(str(cardsLeft)+" cards, "+str(decksLeft)+" decks")
|
|
||||||
|
|
||||||
else:
|
|
||||||
logThis("Not a command (error code 1301)")
|
|
||||||
await ctx.send("I didn't quite understand that (error code 1301)")
|
|
@ -1,11 +1,10 @@
|
|||||||
import json
|
|
||||||
import random
|
import random
|
||||||
import copy
|
import copy
|
||||||
import math
|
import math
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from . import fourInARowDraw
|
from .fourInARowDraw import DrawFourInARow
|
||||||
from funcs import logThis, getName, getID
|
from funcs import logThis
|
||||||
|
|
||||||
AIScores = {
|
AIScores = {
|
||||||
"middle": 3,
|
"middle": 3,
|
||||||
@ -22,328 +21,322 @@ rowCount = 6
|
|||||||
columnCount = 7
|
columnCount = 7
|
||||||
easy = True
|
easy = True
|
||||||
|
|
||||||
# Starts the game
|
class FourInARow():
|
||||||
def fourInARowStart(channel, user, opponent):
|
def __init__(self,bot):
|
||||||
with open("resources/games/games.json", "r") as f:
|
self.bot = bot
|
||||||
data = json.load(f)
|
self.draw = DrawFourInARow(bot)
|
||||||
|
|
||||||
if channel not in data["4 in a row games"]:
|
# Starts the game
|
||||||
|
def fourInARowStart(self, channel, user, opponent):
|
||||||
|
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
|
||||||
|
|
||||||
if opponent in ["1","2","3","4","5"]:
|
if game == None:
|
||||||
difficulty = int(opponent)
|
|
||||||
diffText = " with difficulty "+opponent
|
|
||||||
opponent = "Gwendolyn"
|
|
||||||
elif opponent.lower() == "gwendolyn":
|
|
||||||
difficulty = 3
|
|
||||||
diffText = " with difficulty 3"
|
|
||||||
opponent = "Gwendolyn"
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
int(opponent)
|
|
||||||
return "That difficulty doesn't exist", False, False, False, False
|
|
||||||
except:
|
|
||||||
# Opponent is another player
|
|
||||||
opponent = getID(opponent)
|
|
||||||
if opponent != None:
|
|
||||||
difficulty = 5
|
|
||||||
diffText = ""
|
|
||||||
else:
|
|
||||||
return "I can't find that user", False, False, False, False
|
|
||||||
|
|
||||||
if user == opponent:
|
|
||||||
return "You can't play against yourself", False, False, False, False
|
|
||||||
|
|
||||||
board = [ [ 0 for i in range(columnCount) ] for j in range(rowCount) ]
|
if opponent in ["1","2","3","4","5"]:
|
||||||
players = [user,opponent]
|
difficulty = int(opponent)
|
||||||
random.shuffle(players)
|
diffText = " with difficulty "+opponent
|
||||||
|
opponent = "Gwendolyn"
|
||||||
data["4 in a row games"][channel] = {"board": board,"winner":0,"win direction":"",
|
elif opponent.lower() == "gwendolyn":
|
||||||
"win coordinates":[0,0],"players":players,"turn":0,"difficulty":difficulty}
|
difficulty = 3
|
||||||
|
diffText = " with difficulty 3"
|
||||||
with open("resources/games/games.json", "w") as f:
|
opponent = "Gwendolyn"
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
fourInARowDraw.drawImage(channel)
|
|
||||||
|
|
||||||
gwendoTurn = False
|
|
||||||
|
|
||||||
if players[0] == "Gwendolyn":
|
|
||||||
gwendoTurn = True
|
|
||||||
|
|
||||||
return "Started game against "+getName(opponent)+diffText+". It's "+getName(players[0])+"'s turn", True, False, False, gwendoTurn
|
|
||||||
else:
|
|
||||||
return "There's already a 4 in a row game going on in this channel", False, False, False, False
|
|
||||||
|
|
||||||
# Places a piece at the lowest available point in a specific column
|
|
||||||
def placePiece(channel : str,player : int,column : int):
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if channel in data["4 in a row games"]:
|
|
||||||
board = data["4 in a row games"][channel]["board"]
|
|
||||||
|
|
||||||
board = placeOnBoard(board,player,column)
|
|
||||||
|
|
||||||
|
|
||||||
if board != None:
|
|
||||||
data["4 in a row games"][channel]["board"] = board
|
|
||||||
turn = (data["4 in a row games"][channel]["turn"]+1)%2
|
|
||||||
data["4 in a row games"][channel]["turn"] = turn
|
|
||||||
|
|
||||||
with open("resources/games/games.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
logThis("Checking for win")
|
|
||||||
won, winDirection, winCoordinates = isWon(data["4 in a row games"][channel]["board"])
|
|
||||||
|
|
||||||
if won != 0:
|
|
||||||
gameWon = True
|
|
||||||
data["4 in a row games"][channel]["winner"] = won
|
|
||||||
data["4 in a row games"][channel]["win direction"] = winDirection
|
|
||||||
data["4 in a row games"][channel]["win coordinates"] = winCoordinates
|
|
||||||
|
|
||||||
message = getName(data["4 in a row games"][channel]["players"][won-1])+" placed a piece in column "+str(column+1)+" and won."
|
|
||||||
winAmount = int(data["4 in a row games"][channel]["difficulty"])**2+5
|
|
||||||
if data["4 in a row games"][channel]["players"][won-1] != "Gwendolyn":
|
|
||||||
message += " Adding "+str(winAmount)+" GwendoBucks to their account."
|
|
||||||
elif 0 not in board[0]:
|
|
||||||
gameWon = True
|
|
||||||
message = "It's a draw!"
|
|
||||||
else:
|
else:
|
||||||
gameWon = False
|
try:
|
||||||
message = getName(data["4 in a row games"][channel]["players"][player-1])+" placed a piece in column "+str(column+1)+". It's now "+getName(data["4 in a row games"][channel]["players"][turn])+"'s turn."
|
int(opponent)
|
||||||
|
return "That difficulty doesn't exist", False, False, False, False
|
||||||
|
except:
|
||||||
|
# Opponent is another player
|
||||||
|
opponent = self.bot.funcs.getID(opponent)
|
||||||
|
if opponent != None:
|
||||||
|
difficulty = 5
|
||||||
|
diffText = ""
|
||||||
|
else:
|
||||||
|
return "I can't find that user", False, False, False, False
|
||||||
|
|
||||||
with open("resources/games/games.json", "w") as f:
|
if user == opponent:
|
||||||
json.dump(data,f,indent=4)
|
return "You can't play against yourself", False, False, False, False
|
||||||
|
|
||||||
|
board = [ [ 0 for i in range(columnCount) ] for j in range(rowCount) ]
|
||||||
|
players = [user,opponent]
|
||||||
|
random.shuffle(players)
|
||||||
|
|
||||||
|
newGame = {"_id":channel,"board": board,"winner":0,"win direction":"",
|
||||||
|
"win coordinates":[0,0],"players":players,"turn":0,"difficulty":difficulty}
|
||||||
|
|
||||||
|
self.bot.database["4 in a row games"].insert_one(newGame)
|
||||||
|
|
||||||
|
self.draw.drawImage(channel)
|
||||||
|
|
||||||
gwendoTurn = False
|
gwendoTurn = False
|
||||||
|
|
||||||
if data["4 in a row games"][channel]["players"][turn] == "Gwendolyn":
|
if players[0] == "Gwendolyn":
|
||||||
logThis("It's Gwendolyn's turn")
|
|
||||||
gwendoTurn = True
|
gwendoTurn = True
|
||||||
|
|
||||||
fourInARowDraw.drawImage(channel)
|
return "Started game against "+self.bot.funcs.getName(opponent)+diffText+". It's "+self.bot.funcs.getName(players[0])+"'s turn", True, False, False, gwendoTurn
|
||||||
return message, True, True, gameWon, gwendoTurn
|
|
||||||
else:
|
else:
|
||||||
return "There isn't any room in that column", True, True, False, False
|
return "There's already a 4 in a row game going on in this channel", False, False, False, False
|
||||||
else:
|
|
||||||
return "There's no game in this channel", False, False, False, False
|
|
||||||
|
|
||||||
# Returns a board where a piece has been placed in the column
|
# Places a piece at the lowest available point in a specific column
|
||||||
def placeOnBoard(board,player,column):
|
def placePiece(self, channel : str,player : int,column : int):
|
||||||
placementx, placementy = -1, column
|
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
|
||||||
|
|
||||||
for x in range(len(board)):
|
if game != None:
|
||||||
if board[x][column] == 0:
|
board = game["board"]
|
||||||
placementx = x
|
|
||||||
|
|
||||||
board[placementx][placementy] = player
|
board = self.placeOnBoard(board,player,column)
|
||||||
|
|
||||||
if placementx == -1:
|
if board != None:
|
||||||
return None
|
self.bot.database["4 in a row games"].update_one({"_id":channel},{"$set":{"board":board}})
|
||||||
else:
|
turn = (game["turn"]+1)%2
|
||||||
return board
|
self.bot.database["4 in a row games"].update_one({"_id":channel},{"$set":{"turn":turn}})
|
||||||
|
|
||||||
# Parses command
|
logThis("Checking for win")
|
||||||
def parseFourInARow(command, channel, user):
|
won, winDirection, winCoordinates = self.isWon(board)
|
||||||
commands = command.split()
|
|
||||||
if command == "" or command == " ":
|
|
||||||
return "I didn't get that. Use \"!fourinarow start [opponent]\" to start a game. To play against the computer, use difficulty 1 through 5 as the [opponent].", False, False, False, False
|
|
||||||
elif commands[0] == "start":
|
|
||||||
# Starting a game
|
|
||||||
if len(commands) == 1: # if the commands is "!fourinarow start", the opponent is Gwendolyn
|
|
||||||
commands.append("3")
|
|
||||||
return fourInARowStart(channel,user,commands[1]) # commands[1] is the opponent
|
|
||||||
|
|
||||||
# Stopping the game
|
if won != 0:
|
||||||
elif commands[0] == "stop":
|
gameWon = True
|
||||||
with open("resources/games/games.json", "r") as f:
|
self.bot.database["4 in a row games"].update_one({"_id":channel},{"$set":{"winner":won}})
|
||||||
data = json.load(f)
|
self.bot.database["4 in a row games"].update_one({"_id":channel},{"$set":{"win direction":winDirection}})
|
||||||
|
self.bot.database["4 in a row games"].update_one({"_id":channel},
|
||||||
|
{"$set":{"win coordinates":winCoordinates}})
|
||||||
|
|
||||||
if user in data["4 in a row games"][channel]["players"]:
|
message = self.bot.funcs.getName(game["players"][won-1])+" placed a piece in column "+str(column+1)+" and won."
|
||||||
return "Ending game.", False, False, True, False
|
winAmount = int(game["difficulty"])**2+5
|
||||||
|
if game["players"][won-1] != "Gwendolyn":
|
||||||
|
message += " Adding "+str(winAmount)+" GwendoBucks to their account."
|
||||||
|
elif 0 not in board[0]:
|
||||||
|
gameWon = True
|
||||||
|
message = "It's a draw!"
|
||||||
|
else:
|
||||||
|
gameWon = False
|
||||||
|
message = self.bot.funcs.getName(game["players"][player-1])+" placed a piece in column "+str(column+1)+". It's now "+self.bot.funcs.getName(game["players"][turn])+"'s turn."
|
||||||
|
|
||||||
|
gwendoTurn = False
|
||||||
|
|
||||||
|
if game["players"][turn] == "Gwendolyn":
|
||||||
|
logThis("It's Gwendolyn's turn")
|
||||||
|
gwendoTurn = True
|
||||||
|
|
||||||
|
self.draw.drawImage(channel)
|
||||||
|
return message, True, True, gameWon, gwendoTurn
|
||||||
|
else:
|
||||||
|
return "There isn't any room in that column", True, True, False, False
|
||||||
else:
|
else:
|
||||||
return "You can't end a game where you're not a player.", False, False, False, False
|
return "There's no game in this channel", False, False, False, False
|
||||||
|
|
||||||
# Placing manually
|
# Returns a board where a piece has been placed in the column
|
||||||
elif commands[0] == "place":
|
def placeOnBoard(self,board,player,column):
|
||||||
try:
|
placementx, placementy = -1, column
|
||||||
return placePiece(channel,int(commands[1]),int(commands[2])-1)
|
|
||||||
except:
|
|
||||||
return "I didn't get that. To place a piece use \"!fourinarow place [player number] [column]\" or press the corresponding message-reaction beneath the board.", False, False, False, False
|
|
||||||
else:
|
|
||||||
return "I didn't get that. Use \"!fourinarow start [opponent]\" to start a game. To play against the computer, use difficulty 1 through 5 as the [opponent].", False, False, False, False
|
|
||||||
|
|
||||||
# Checks if someone has won the game and returns the winner
|
for x in range(len(board)):
|
||||||
def isWon(board):
|
if board[x][column] == 0:
|
||||||
won = 0
|
placementx = x
|
||||||
winDirection = ""
|
|
||||||
winCoordinates = [0,0]
|
|
||||||
|
|
||||||
for row in range(len(board)):
|
board[placementx][placementy] = player
|
||||||
for place in range(len(board[row])):
|
|
||||||
if won == 0:
|
|
||||||
piecePlayer = board[row][place]
|
|
||||||
if piecePlayer != 0:
|
|
||||||
# Checks horizontal
|
|
||||||
if place <= columnCount-4:
|
|
||||||
pieces = [board[row][place+1],board[row][place+2],board[row][place+3]]
|
|
||||||
else:
|
|
||||||
pieces = [0]
|
|
||||||
|
|
||||||
if all(x == piecePlayer for x in pieces):
|
if placementx == -1:
|
||||||
won = piecePlayer
|
return None
|
||||||
winDirection = "h"
|
else:
|
||||||
winCoordinates = [row,place]
|
return board
|
||||||
|
|
||||||
# Checks vertical
|
# Parses command
|
||||||
if row <= rowCount-4:
|
def parseFourInARow(self, command, channel, user):
|
||||||
pieces = [board[row+1][place],board[row+2][place],board[row+3][place]]
|
commands = command.split()
|
||||||
else:
|
if command == "" or command == " ":
|
||||||
pieces = [0]
|
return "I didn't get that. Use \"!fourinarow start [opponent]\" to start a game. To play against the computer, use difficulty 1 through 5 as the [opponent].", False, False, False, False
|
||||||
|
elif commands[0] == "start":
|
||||||
|
# Starting a game
|
||||||
|
if len(commands) == 1: # if the commands is "!fourinarow start", the opponent is Gwendolyn
|
||||||
|
commands.append("3")
|
||||||
|
return self.fourInARowStart(channel,user,commands[1]) # commands[1] is the opponent
|
||||||
|
|
||||||
if all(x == piecePlayer for x in pieces):
|
# Stopping the game
|
||||||
won = piecePlayer
|
elif commands[0] == "stop":
|
||||||
winDirection = "v"
|
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
|
||||||
winCoordinates = [row,place]
|
|
||||||
|
|
||||||
# Checks right diagonal
|
if user in game["players"]:
|
||||||
if row <= rowCount-4 and place <= columnCount-4:
|
return "Ending game.", False, False, True, False
|
||||||
pieces = [board[row+1][place+1],board[row+2][place+2],board[row+3][place+3]]
|
else:
|
||||||
else:
|
return "You can't end a game where you're not a player.", False, False, False, False
|
||||||
pieces = [0]
|
|
||||||
|
|
||||||
if all(x == piecePlayer for x in pieces):
|
# Placing manually
|
||||||
won = piecePlayer
|
elif commands[0] == "place":
|
||||||
winDirection = "r"
|
try:
|
||||||
winCoordinates = [row,place]
|
return self.placePiece(channel,int(commands[1]),int(commands[2])-1)
|
||||||
|
except:
|
||||||
|
return "I didn't get that. To place a piece use \"!fourinarow place [player number] [column]\" or press the corresponding message-reaction beneath the board.", False, False, False, False
|
||||||
|
else:
|
||||||
|
return "I didn't get that. Use \"!fourinarow start [opponent]\" to start a game. To play against the computer, use difficulty 1 through 5 as the [opponent].", False, False, False, False
|
||||||
|
|
||||||
# Checks left diagonal
|
# Checks if someone has won the game and returns the winner
|
||||||
if row <= rowCount-4 and place >= 3:
|
def isWon(self, board):
|
||||||
pieces = [board[row+1][place-1],board[row+2][place-2],board[row+3][place-3]]
|
won = 0
|
||||||
else:
|
winDirection = ""
|
||||||
pieces = [0]
|
winCoordinates = [0,0]
|
||||||
|
|
||||||
if all(x == piecePlayer for x in pieces):
|
for row in range(len(board)):
|
||||||
won = piecePlayer
|
for place in range(len(board[row])):
|
||||||
winDirection = "l"
|
if won == 0:
|
||||||
winCoordinates = [row,place]
|
piecePlayer = board[row][place]
|
||||||
|
if piecePlayer != 0:
|
||||||
|
# Checks horizontal
|
||||||
|
if place <= columnCount-4:
|
||||||
|
pieces = [board[row][place+1],board[row][place+2],board[row][place+3]]
|
||||||
|
else:
|
||||||
|
pieces = [0]
|
||||||
|
|
||||||
|
if all(x == piecePlayer for x in pieces):
|
||||||
|
won = piecePlayer
|
||||||
|
winDirection = "h"
|
||||||
|
winCoordinates = [row,place]
|
||||||
|
|
||||||
|
# Checks vertical
|
||||||
|
if row <= rowCount-4:
|
||||||
|
pieces = [board[row+1][place],board[row+2][place],board[row+3][place]]
|
||||||
|
else:
|
||||||
|
pieces = [0]
|
||||||
|
|
||||||
|
if all(x == piecePlayer for x in pieces):
|
||||||
|
won = piecePlayer
|
||||||
|
winDirection = "v"
|
||||||
|
winCoordinates = [row,place]
|
||||||
|
|
||||||
|
# Checks right diagonal
|
||||||
|
if row <= rowCount-4 and place <= columnCount-4:
|
||||||
|
pieces = [board[row+1][place+1],board[row+2][place+2],board[row+3][place+3]]
|
||||||
|
else:
|
||||||
|
pieces = [0]
|
||||||
|
|
||||||
|
if all(x == piecePlayer for x in pieces):
|
||||||
|
won = piecePlayer
|
||||||
|
winDirection = "r"
|
||||||
|
winCoordinates = [row,place]
|
||||||
|
|
||||||
|
# Checks left diagonal
|
||||||
|
if row <= rowCount-4 and place >= 3:
|
||||||
|
pieces = [board[row+1][place-1],board[row+2][place-2],board[row+3][place-3]]
|
||||||
|
else:
|
||||||
|
pieces = [0]
|
||||||
|
|
||||||
|
if all(x == piecePlayer for x in pieces):
|
||||||
|
won = piecePlayer
|
||||||
|
winDirection = "l"
|
||||||
|
winCoordinates = [row,place]
|
||||||
|
|
||||||
|
|
||||||
return won, winDirection, winCoordinates
|
return won, winDirection, winCoordinates
|
||||||
|
|
||||||
# Plays as the AI
|
# Plays as the AI
|
||||||
async def fourInARowAI(channel):
|
async def fourInARowAI(self, channel):
|
||||||
logThis("Figuring out best move")
|
logThis("Figuring out best move")
|
||||||
with open("resources/games/games.json", "r") as f:
|
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
board = data["4 in a row games"][channel]["board"]
|
board = game["board"]
|
||||||
player = data["4 in a row games"][channel]["players"].index("Gwendolyn")+1
|
player = game["players"].index("Gwendolyn")+1
|
||||||
difficulty = data["4 in a row games"][channel]["difficulty"]
|
difficulty = game["difficulty"]
|
||||||
|
|
||||||
scores = [-math.inf,-math.inf,-math.inf,-math.inf,-math.inf,-math.inf,-math.inf]
|
scores = [-math.inf,-math.inf,-math.inf,-math.inf,-math.inf,-math.inf,-math.inf]
|
||||||
for column in range(0,columnCount):
|
|
||||||
testBoard = copy.deepcopy(board)
|
|
||||||
testBoard = placeOnBoard(testBoard,player,column)
|
|
||||||
if testBoard != None:
|
|
||||||
scores[column] = await minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False)
|
|
||||||
logThis("Best score for column "+str(column)+" is "+str(scores[column]))
|
|
||||||
|
|
||||||
possibleScores = scores.copy()
|
|
||||||
|
|
||||||
while (min(possibleScores) <= (max(possibleScores) - max(possibleScores)/10)) and len(possibleScores) != 1:
|
|
||||||
possibleScores.remove(min(possibleScores))
|
|
||||||
|
|
||||||
highest_score = random.choice(possibleScores)
|
|
||||||
|
|
||||||
indices = [i for i, x in enumerate(scores) if x == highest_score]
|
|
||||||
placement = random.choice(indices)
|
|
||||||
return placePiece(channel,player,placement)
|
|
||||||
|
|
||||||
# Calculates points for a board
|
|
||||||
def AICalcPoints(board,player):
|
|
||||||
score = 0
|
|
||||||
otherPlayer = player%2+1
|
|
||||||
|
|
||||||
# Adds points for middle placement
|
|
||||||
# Checks horizontal
|
|
||||||
for row in range(rowCount):
|
|
||||||
if board[row][3] == player:
|
|
||||||
score += AIScores["middle"]
|
|
||||||
rowArray = [int(i) for i in list(board[row])]
|
|
||||||
for place in range(columnCount-3):
|
|
||||||
window = rowArray[place:place+4]
|
|
||||||
score += evaluateWindow(window,player,otherPlayer)
|
|
||||||
|
|
||||||
# Checks Vertical
|
|
||||||
for column in range(columnCount):
|
|
||||||
columnArray = [int(i[column]) for i in list(board)]
|
|
||||||
for place in range(rowCount-3):
|
|
||||||
window = columnArray[place:place+4]
|
|
||||||
score += evaluateWindow(window,player,otherPlayer)
|
|
||||||
|
|
||||||
# Checks right diagonal
|
|
||||||
for row in range(rowCount-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]]
|
|
||||||
score += evaluateWindow(window,player,otherPlayer)
|
|
||||||
|
|
||||||
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]]
|
|
||||||
score += evaluateWindow(window,player,otherPlayer)
|
|
||||||
|
|
||||||
|
|
||||||
## Checks if anyone has won
|
|
||||||
#won = isWon(board)[0]
|
|
||||||
|
|
||||||
## Add points if AI wins
|
|
||||||
#if won == player:
|
|
||||||
# score += AIScores["win"]
|
|
||||||
|
|
||||||
return score
|
|
||||||
|
|
||||||
|
|
||||||
def evaluateWindow(window,player,otherPlayer):
|
|
||||||
if window.count(player) == 4:
|
|
||||||
return AIScores["win"]
|
|
||||||
elif window.count(player) == 3 and window.count(0) == 1:
|
|
||||||
return AIScores["three in a row"]
|
|
||||||
elif window.count(player) == 2 and window.count(0) == 2:
|
|
||||||
return AIScores["two in a row"]
|
|
||||||
elif window.count(otherPlayer) == 4:
|
|
||||||
return AIScores["enemy win"]
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
async def minimax(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer):
|
|
||||||
#terminal = ((0 not in board[0]) or (isWon(board)[0] != 0))
|
|
||||||
terminal = 0 not in board[0]
|
|
||||||
points = AICalcPoints(board,originalPlayer)
|
|
||||||
# The depth is how many moves ahead the computer checks. This value is the difficulty.
|
|
||||||
if depth == 0 or terminal or (points > 5000 or points < -6000):
|
|
||||||
return points
|
|
||||||
if maximizingPlayer:
|
|
||||||
value = -math.inf
|
|
||||||
for column in range(0,columnCount):
|
for column in range(0,columnCount):
|
||||||
testBoard = copy.deepcopy(board)
|
testBoard = copy.deepcopy(board)
|
||||||
testBoard = placeOnBoard(testBoard,player,column)
|
testBoard = self.placeOnBoard(testBoard,player,column)
|
||||||
if testBoard != None:
|
if testBoard != None:
|
||||||
evaluation = await minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,False)
|
scores[column] = await self.minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False)
|
||||||
if evaluation < -9000: evaluation += AIScores["avoid losing"]
|
logThis("Best score for column "+str(column)+" is "+str(scores[column]))
|
||||||
value = max(value,evaluation)
|
|
||||||
alpha = max(alpha,evaluation)
|
possibleScores = scores.copy()
|
||||||
if beta <= alpha: break
|
|
||||||
return value
|
while (min(possibleScores) <= (max(possibleScores) - max(possibleScores)/10)) and len(possibleScores) != 1:
|
||||||
else:
|
possibleScores.remove(min(possibleScores))
|
||||||
value = math.inf
|
|
||||||
for column in range(0,columnCount):
|
highest_score = random.choice(possibleScores)
|
||||||
testBoard = copy.deepcopy(board)
|
|
||||||
testBoard = placeOnBoard(testBoard,player,column)
|
indices = [i for i, x in enumerate(scores) if x == highest_score]
|
||||||
if testBoard != None:
|
placement = random.choice(indices)
|
||||||
evaluation = await minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,True)
|
return self.placePiece(channel,player,placement)
|
||||||
if evaluation < -9000: evaluation += AIScores["avoid losing"]
|
|
||||||
value = min(value,evaluation)
|
# Calculates points for a board
|
||||||
beta = min(beta,evaluation)
|
def AICalcPoints(self,board,player):
|
||||||
if beta <= alpha: break
|
score = 0
|
||||||
return value
|
otherPlayer = player%2+1
|
||||||
|
|
||||||
|
# Adds points for middle placement
|
||||||
|
# Checks horizontal
|
||||||
|
for row in range(rowCount):
|
||||||
|
if board[row][3] == player:
|
||||||
|
score += AIScores["middle"]
|
||||||
|
rowArray = [int(i) for i in list(board[row])]
|
||||||
|
for place in range(columnCount-3):
|
||||||
|
window = rowArray[place:place+4]
|
||||||
|
score += self.evaluateWindow(window,player,otherPlayer)
|
||||||
|
|
||||||
|
# Checks Vertical
|
||||||
|
for column in range(columnCount):
|
||||||
|
columnArray = [int(i[column]) for i in list(board)]
|
||||||
|
for place in range(rowCount-3):
|
||||||
|
window = columnArray[place:place+4]
|
||||||
|
score += self.evaluateWindow(window,player,otherPlayer)
|
||||||
|
|
||||||
|
# Checks right diagonal
|
||||||
|
for row in range(rowCount-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]]
|
||||||
|
score += self.evaluateWindow(window,player,otherPlayer)
|
||||||
|
|
||||||
|
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]]
|
||||||
|
score += self.evaluateWindow(window,player,otherPlayer)
|
||||||
|
|
||||||
|
|
||||||
|
## Checks if anyone has won
|
||||||
|
#won = isWon(board)[0]
|
||||||
|
|
||||||
|
## Add points if AI wins
|
||||||
|
#if won == player:
|
||||||
|
# score += AIScores["win"]
|
||||||
|
|
||||||
|
return score
|
||||||
|
|
||||||
|
|
||||||
|
def evaluateWindow(self, window,player,otherPlayer):
|
||||||
|
if window.count(player) == 4:
|
||||||
|
return AIScores["win"]
|
||||||
|
elif window.count(player) == 3 and window.count(0) == 1:
|
||||||
|
return AIScores["three in a row"]
|
||||||
|
elif window.count(player) == 2 and window.count(0) == 2:
|
||||||
|
return AIScores["two in a row"]
|
||||||
|
elif window.count(otherPlayer) == 4:
|
||||||
|
return AIScores["enemy win"]
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
async def minimax(self, board, depth, player , originalPlayer, alpha, beta, maximizingPlayer):
|
||||||
|
#terminal = ((0 not in board[0]) or (isWon(board)[0] != 0))
|
||||||
|
terminal = 0 not in board[0]
|
||||||
|
points = self.AICalcPoints(board,originalPlayer)
|
||||||
|
# The depth is how many moves ahead the computer checks. This value is the difficulty.
|
||||||
|
if depth == 0 or terminal or (points > 5000 or points < -6000):
|
||||||
|
return points
|
||||||
|
if maximizingPlayer:
|
||||||
|
value = -math.inf
|
||||||
|
for column in range(0,columnCount):
|
||||||
|
testBoard = copy.deepcopy(board)
|
||||||
|
testBoard = self.placeOnBoard(testBoard,player,column)
|
||||||
|
if testBoard != None:
|
||||||
|
evaluation = await self.minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,False)
|
||||||
|
if evaluation < -9000: evaluation += AIScores["avoid losing"]
|
||||||
|
value = max(value,evaluation)
|
||||||
|
alpha = max(alpha,evaluation)
|
||||||
|
if beta <= alpha: break
|
||||||
|
return value
|
||||||
|
else:
|
||||||
|
value = math.inf
|
||||||
|
for column in range(0,columnCount):
|
||||||
|
testBoard = copy.deepcopy(board)
|
||||||
|
testBoard = self.placeOnBoard(testBoard,player,column)
|
||||||
|
if testBoard != None:
|
||||||
|
evaluation = await self.minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,True)
|
||||||
|
if evaluation < -9000: evaluation += AIScores["avoid losing"]
|
||||||
|
value = min(value,evaluation)
|
||||||
|
beta = min(beta,evaluation)
|
||||||
|
if beta <= alpha: break
|
||||||
|
return value
|
||||||
|
@ -1,154 +1,156 @@
|
|||||||
import json
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
from funcs import logThis, getName
|
from funcs import logThis
|
||||||
|
|
||||||
# Draws the whole thing
|
class DrawFourInARow():
|
||||||
def drawImage(channel):
|
def __init__(self,bot):
|
||||||
logThis("Drawing four in a row board")
|
self.bot = bot
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
board = data["4 in a row games"][channel]["board"]
|
# Draws the whole thing
|
||||||
|
def drawImage(self, channel):
|
||||||
|
logThis("Drawing four in a row board")
|
||||||
|
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
|
||||||
|
|
||||||
border = 40
|
board = game["board"]
|
||||||
gridBorder = 40
|
|
||||||
cornerSize = 300
|
|
||||||
boardOutlineSize = 10
|
|
||||||
pieceOutlineSize = 10
|
|
||||||
emptyOutlineSize = 0
|
|
||||||
bottomBorder = 110
|
|
||||||
exampleCircles = 100
|
|
||||||
w, h = 2800,2400
|
|
||||||
backgroundColor = (230,230,234,255)
|
|
||||||
boardOutlineColor = (0,0,0)
|
|
||||||
pieceOutlineColor = (244,244,248)
|
|
||||||
emptyOutlineColor = (0,0,0)
|
|
||||||
player1Color = (254,74,73)
|
|
||||||
player2Color = (254,215,102)
|
|
||||||
boardColor = (42,183,202)
|
|
||||||
placeSize = 300
|
|
||||||
white = (255,255,255,160)
|
|
||||||
winBarColor = (250,250,250,255)
|
|
||||||
|
|
||||||
fnt = ImageFont.truetype('resources/futura-bold.ttf', exampleCircles)
|
border = 40
|
||||||
|
gridBorder = 40
|
||||||
|
cornerSize = 300
|
||||||
|
boardOutlineSize = 10
|
||||||
|
pieceOutlineSize = 10
|
||||||
|
emptyOutlineSize = 0
|
||||||
|
bottomBorder = 110
|
||||||
|
exampleCircles = 100
|
||||||
|
w, h = 2800,2400
|
||||||
|
backgroundColor = (230,230,234,255)
|
||||||
|
boardOutlineColor = (0,0,0)
|
||||||
|
pieceOutlineColor = (244,244,248)
|
||||||
|
emptyOutlineColor = (0,0,0)
|
||||||
|
player1Color = (254,74,73)
|
||||||
|
player2Color = (254,215,102)
|
||||||
|
boardColor = (42,183,202)
|
||||||
|
placeSize = 300
|
||||||
|
white = (255,255,255,160)
|
||||||
|
winBarColor = (250,250,250,255)
|
||||||
|
|
||||||
boardSize = [w-(2*(border+gridBorder)),h-(2*(border+gridBorder))]
|
fnt = ImageFont.truetype('resources/futura-bold.ttf', exampleCircles)
|
||||||
placeGridSize = [math.floor(boardSize[0]/7),math.floor(boardSize[1]/6)]
|
|
||||||
pieceStartx = (border+gridBorder)+math.floor(placeGridSize[0]/2)-math.floor(placeSize/2)
|
|
||||||
pieceStarty = (border+gridBorder)+math.floor(placeGridSize[1]/2)-math.floor(placeSize/2)
|
|
||||||
|
|
||||||
if data["4 in a row games"][channel]["players"][0] == "Gwendolyn":
|
boardSize = [w-(2*(border+gridBorder)),h-(2*(border+gridBorder))]
|
||||||
player1 = "Gwendolyn"
|
placeGridSize = [math.floor(boardSize[0]/7),math.floor(boardSize[1]/6)]
|
||||||
else:
|
pieceStartx = (border+gridBorder)+math.floor(placeGridSize[0]/2)-math.floor(placeSize/2)
|
||||||
player1 = getName(data["4 in a row games"][channel]["players"][0])
|
pieceStarty = (border+gridBorder)+math.floor(placeGridSize[1]/2)-math.floor(placeSize/2)
|
||||||
|
|
||||||
if data["4 in a row games"][channel]["players"][1] == "Gwendolyn":
|
if game["players"][0] == "Gwendolyn":
|
||||||
player2 = "Gwendolyn"
|
player1 = "Gwendolyn"
|
||||||
else:
|
else:
|
||||||
player2 = getName(data["4 in a row games"][channel]["players"][1])
|
player1 = self.bot.funcs.getName(game["players"][0])
|
||||||
|
|
||||||
|
if game["players"][1] == "Gwendolyn":
|
||||||
|
player2 = "Gwendolyn"
|
||||||
|
else:
|
||||||
|
player2 = self.bot.funcs.getName(game["players"][1])
|
||||||
|
|
||||||
|
|
||||||
background = Image.new("RGB", (w,h+bottomBorder),backgroundColor)
|
background = Image.new("RGB", (w,h+bottomBorder),backgroundColor)
|
||||||
d = ImageDraw.Draw(background,"RGBA")
|
d = ImageDraw.Draw(background,"RGBA")
|
||||||
|
|
||||||
# This whole part was the easiest way to make a rectangle with rounded corners and an outline
|
# This whole part was the easiest way to make a rectangle with rounded corners and an outline
|
||||||
# - Corners:
|
# - Corners:
|
||||||
d.ellipse([(border,border),(border+cornerSize,border+cornerSize)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
d.ellipse([(border,border),(border+cornerSize,border+cornerSize)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
||||||
d.ellipse([(w-(border+cornerSize),h-(border+cornerSize)),(w-border,h-border)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
d.ellipse([(w-(border+cornerSize),h-(border+cornerSize)),(w-border,h-border)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
||||||
d.ellipse([(border,h-(border+cornerSize)),(border+cornerSize,h-border)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
d.ellipse([(border,h-(border+cornerSize)),(border+cornerSize,h-border)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
||||||
d.ellipse([(w-(border+cornerSize),border),(w-border,border+cornerSize)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
d.ellipse([(w-(border+cornerSize),border),(w-border,border+cornerSize)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
||||||
# - Rectangle:
|
# - Rectangle:
|
||||||
d.rectangle([(border+math.floor(cornerSize/2),border),(w-(border+math.floor(cornerSize/2)),h-border)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
d.rectangle([(border+math.floor(cornerSize/2),border),(w-(border+math.floor(cornerSize/2)),h-border)],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
||||||
d.rectangle([(border,border+math.floor(cornerSize/2)),(w-border,h-(border+math.floor(cornerSize/2)))],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
d.rectangle([(border,border+math.floor(cornerSize/2)),(w-border,h-(border+math.floor(cornerSize/2)))],fill=boardColor,outline=boardOutlineColor,width=boardOutlineSize)
|
||||||
# - Removing outline on the inside:
|
# - Removing outline on the inside:
|
||||||
d.rectangle([(border+math.floor(cornerSize/2),border+math.floor(cornerSize/2)),(w-(border+math.floor(cornerSize/2)),h-(border+math.floor(cornerSize/2)))],fill=boardColor)
|
d.rectangle([(border+math.floor(cornerSize/2),border+math.floor(cornerSize/2)),(w-(border+math.floor(cornerSize/2)),h-(border+math.floor(cornerSize/2)))],fill=boardColor)
|
||||||
d.rectangle([(border+math.floor(cornerSize/2),border+boardOutlineSize),(w-(border+math.floor(cornerSize/2)),h-(border+boardOutlineSize))],fill=boardColor)
|
d.rectangle([(border+math.floor(cornerSize/2),border+boardOutlineSize),(w-(border+math.floor(cornerSize/2)),h-(border+boardOutlineSize))],fill=boardColor)
|
||||||
d.rectangle([(border+boardOutlineSize,border+math.floor(cornerSize/2)),(w-(border+boardOutlineSize),h-(border+math.floor(cornerSize/2)))],fill=boardColor)
|
d.rectangle([(border+boardOutlineSize,border+math.floor(cornerSize/2)),(w-(border+boardOutlineSize),h-(border+math.floor(cornerSize/2)))],fill=boardColor)
|
||||||
|
|
||||||
for x, line in enumerate(board):
|
for x, line in enumerate(board):
|
||||||
for y, piece in enumerate(line):
|
for y, piece in enumerate(line):
|
||||||
|
|
||||||
if piece == 1:
|
if piece == 1:
|
||||||
pieceColor = player1Color
|
pieceColor = player1Color
|
||||||
outlineWidth = pieceOutlineSize
|
outlineWidth = pieceOutlineSize
|
||||||
outlineColor = pieceOutlineColor
|
outlineColor = pieceOutlineColor
|
||||||
elif piece == 2:
|
elif piece == 2:
|
||||||
pieceColor = player2Color
|
pieceColor = player2Color
|
||||||
outlineWidth = pieceOutlineSize
|
outlineWidth = pieceOutlineSize
|
||||||
outlineColor = pieceOutlineColor
|
outlineColor = pieceOutlineColor
|
||||||
else:
|
else:
|
||||||
pieceColor = backgroundColor
|
pieceColor = backgroundColor
|
||||||
outlineWidth = emptyOutlineSize
|
outlineWidth = emptyOutlineSize
|
||||||
outlineColor = emptyOutlineColor
|
outlineColor = emptyOutlineColor
|
||||||
|
|
||||||
startx = pieceStartx + placeGridSize[0]*y
|
startx = pieceStartx + placeGridSize[0]*y
|
||||||
starty = pieceStarty + placeGridSize[1]*x
|
starty = pieceStarty + placeGridSize[1]*x
|
||||||
|
|
||||||
d.ellipse([(startx,starty),(startx+placeSize,starty+placeSize)],fill=pieceColor,outline=outlineColor,width=outlineWidth)
|
d.ellipse([(startx,starty),(startx+placeSize,starty+placeSize)],fill=pieceColor,outline=outlineColor,width=outlineWidth)
|
||||||
|
|
||||||
if data["4 in a row games"][channel]["winner"] != 0:
|
if game["winner"] != 0:
|
||||||
coordinates = data["4 in a row games"][channel]["win coordinates"]
|
coordinates = game["win coordinates"]
|
||||||
startx = border + placeGridSize[0]*coordinates[1] + gridBorder
|
startx = border + placeGridSize[0]*coordinates[1] + gridBorder
|
||||||
starty = border + placeGridSize[1]*coordinates[0] + gridBorder
|
starty = border + placeGridSize[1]*coordinates[0] + gridBorder
|
||||||
a = (placeGridSize[0]*4-gridBorder-border)**2
|
a = (placeGridSize[0]*4-gridBorder-border)**2
|
||||||
b = (placeGridSize[1]*4-gridBorder-border)**2
|
b = (placeGridSize[1]*4-gridBorder-border)**2
|
||||||
diagonalLength = (math.sqrt(a+b))/placeGridSize[0]
|
diagonalLength = (math.sqrt(a+b))/placeGridSize[0]
|
||||||
diagonalAngle = math.degrees(math.atan(placeGridSize[1]/placeGridSize[0]))
|
diagonalAngle = math.degrees(math.atan(placeGridSize[1]/placeGridSize[0]))
|
||||||
|
|
||||||
if data["4 in a row games"][channel]["win direction"] == "h":
|
if game["win direction"] == "h":
|
||||||
winBar = Image.new("RGBA",(placeGridSize[0]*4,placeGridSize[1]),(0,0,0,0))
|
winBar = Image.new("RGBA",(placeGridSize[0]*4,placeGridSize[1]),(0,0,0,0))
|
||||||
winD = ImageDraw.Draw(winBar)
|
winD = ImageDraw.Draw(winBar)
|
||||||
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
|
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
|
||||||
winD.ellipse([((placeGridSize[0]*3),0),(placeGridSize[0]*4,placeGridSize[1])],fill=white)
|
winD.ellipse([((placeGridSize[0]*3),0),(placeGridSize[0]*4,placeGridSize[1])],fill=white)
|
||||||
winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*3.5),placeGridSize[1])],fill=white)
|
winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*3.5),placeGridSize[1])],fill=white)
|
||||||
|
|
||||||
elif data["4 in a row games"][channel]["win direction"] == "v":
|
elif game["win direction"] == "v":
|
||||||
winBar = Image.new("RGBA",(placeGridSize[0],placeGridSize[1]*4),(0,0,0,0))
|
winBar = Image.new("RGBA",(placeGridSize[0],placeGridSize[1]*4),(0,0,0,0))
|
||||||
winD = ImageDraw.Draw(winBar)
|
winD = ImageDraw.Draw(winBar)
|
||||||
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
|
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
|
||||||
winD.ellipse([(0,(placeGridSize[1]*3)),(placeGridSize[0],placeGridSize[1]*4)],fill=white)
|
winD.ellipse([(0,(placeGridSize[1]*3)),(placeGridSize[0],placeGridSize[1]*4)],fill=white)
|
||||||
winD.rectangle([0,(int(placeGridSize[1]*0.5)),(placeGridSize[0],int(placeGridSize[1]*3.5))],fill=white)
|
winD.rectangle([0,(int(placeGridSize[1]*0.5)),(placeGridSize[0],int(placeGridSize[1]*3.5))],fill=white)
|
||||||
|
|
||||||
elif data["4 in a row games"][channel]["win direction"] == "r":
|
elif game["win direction"] == "r":
|
||||||
winBar = Image.new("RGBA",(int(placeGridSize[0]*diagonalLength),placeGridSize[1]),(0,0,0,0))
|
winBar = Image.new("RGBA",(int(placeGridSize[0]*diagonalLength),placeGridSize[1]),(0,0,0,0))
|
||||||
winD = ImageDraw.Draw(winBar)
|
winD = ImageDraw.Draw(winBar)
|
||||||
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
|
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
|
||||||
winD.ellipse([((placeGridSize[0]*(diagonalLength-1)),0),(placeGridSize[0]*diagonalLength,placeGridSize[1])],fill=white)
|
winD.ellipse([((placeGridSize[0]*(diagonalLength-1)),0),(placeGridSize[0]*diagonalLength,placeGridSize[1])],fill=white)
|
||||||
winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*(diagonalLength-0.5)),placeGridSize[1])],fill=white)
|
winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*(diagonalLength-0.5)),placeGridSize[1])],fill=white)
|
||||||
winBar = winBar.rotate(-diagonalAngle,expand=1)
|
winBar = winBar.rotate(-diagonalAngle,expand=1)
|
||||||
startx -= 90
|
startx -= 90
|
||||||
starty -= 100
|
starty -= 100
|
||||||
|
|
||||||
elif data["4 in a row games"][channel]["win direction"] == "l":
|
elif game["win direction"] == "l":
|
||||||
winBar = Image.new("RGBA",(int(placeGridSize[0]*diagonalLength),placeGridSize[1]),(0,0,0,0))
|
winBar = Image.new("RGBA",(int(placeGridSize[0]*diagonalLength),placeGridSize[1]),(0,0,0,0))
|
||||||
winD = ImageDraw.Draw(winBar)
|
winD = ImageDraw.Draw(winBar)
|
||||||
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
|
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
|
||||||
winD.ellipse([((placeGridSize[0]*(diagonalLength-1)),0),(placeGridSize[0]*diagonalLength,placeGridSize[1])],fill=white)
|
winD.ellipse([((placeGridSize[0]*(diagonalLength-1)),0),(placeGridSize[0]*diagonalLength,placeGridSize[1])],fill=white)
|
||||||
winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*(diagonalLength-0.5)),placeGridSize[1])],fill=white)
|
winD.rectangle([(int(placeGridSize[0]*0.5),0),(int(placeGridSize[0]*(diagonalLength-0.5)),placeGridSize[1])],fill=white)
|
||||||
winBar = winBar.rotate(diagonalAngle,expand=1)
|
winBar = winBar.rotate(diagonalAngle,expand=1)
|
||||||
startx -= placeGridSize[0]*3 + 90
|
startx -= placeGridSize[0]*3 + 90
|
||||||
starty -= gridBorder + 60
|
starty -= gridBorder + 60
|
||||||
|
|
||||||
|
|
||||||
mask = winBar.copy()#.convert("L")
|
mask = winBar.copy()#.convert("L")
|
||||||
#mask.putalpha(128)
|
#mask.putalpha(128)
|
||||||
#mask.save("test.png")
|
#mask.save("test.png")
|
||||||
|
|
||||||
winBarImage = Image.new("RGBA",mask.size,color=winBarColor)
|
winBarImage = Image.new("RGBA",mask.size,color=winBarColor)
|
||||||
background.paste(winBarImage,(startx,starty),mask)
|
background.paste(winBarImage,(startx,starty),mask)
|
||||||
|
|
||||||
# Bottom
|
# Bottom
|
||||||
textPadding = 20
|
textPadding = 20
|
||||||
|
|
||||||
exampleHeight = h - border + int((bottomBorder+border)/2) - int(exampleCircles/2)
|
exampleHeight = h - border + int((bottomBorder+border)/2) - int(exampleCircles/2)
|
||||||
d.ellipse([(border,exampleHeight),(border+exampleCircles),(exampleHeight+exampleCircles)],fill=player1Color,outline=boardOutlineColor,width=3)
|
d.ellipse([(border,exampleHeight),(border+exampleCircles),(exampleHeight+exampleCircles)],fill=player1Color,outline=boardOutlineColor,width=3)
|
||||||
d.text((border+exampleCircles+textPadding,exampleHeight),player1,font=fnt,fill=(0,0,0))
|
d.text((border+exampleCircles+textPadding,exampleHeight),player1,font=fnt,fill=(0,0,0))
|
||||||
|
|
||||||
textWidth = fnt.getsize(player2)[0]
|
textWidth = fnt.getsize(player2)[0]
|
||||||
d.ellipse([(w-border-exampleCircles-textWidth-textPadding,exampleHeight),(w-border-textWidth-textPadding),(exampleHeight+exampleCircles)],fill=player2Color,outline=boardOutlineColor,width=3)
|
d.ellipse([(w-border-exampleCircles-textWidth-textPadding,exampleHeight),(w-border-textWidth-textPadding),(exampleHeight+exampleCircles)],fill=player2Color,outline=boardOutlineColor,width=3)
|
||||||
d.text((w-border-textWidth,exampleHeight),player2,font=fnt,fill=(0,0,0))
|
d.text((w-border-textWidth,exampleHeight),player2,font=fnt,fill=(0,0,0))
|
||||||
|
|
||||||
|
|
||||||
background.save("resources/games/4InARowBoards/board"+channel+".png")
|
background.save("resources/games/4InARowBoards/board"+channel+".png")
|
||||||
|
@ -1,223 +1,213 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import discord
|
import discord
|
||||||
import json
|
|
||||||
|
|
||||||
from funcs import logThis, deleteGame
|
from funcs import logThis
|
||||||
from .money import addMoney
|
|
||||||
from .fourInARow import parseFourInARow, fourInARowAI
|
|
||||||
from .hex import parseHex, hexAI
|
|
||||||
from .monopoly import parseMonopoly, monopolyContinue
|
|
||||||
from .hangman import parseHangman
|
|
||||||
|
|
||||||
# Deletes a message
|
class GameLoops():
|
||||||
async def deleteMessage(imageLocation,channel):
|
def __init__(self,bot):
|
||||||
try:
|
self.bot = bot
|
||||||
with open("resources/games/oldImages/"+imageLocation, "r") as f:
|
|
||||||
messages = f.read().splitlines()
|
|
||||||
|
|
||||||
for message in messages:
|
|
||||||
oldMessage = await channel.fetch_message(int(message))
|
|
||||||
logThis("Deleting old message")
|
|
||||||
await oldMessage.delete()
|
|
||||||
except:
|
|
||||||
oldMessage = ""
|
|
||||||
|
|
||||||
return oldMessage
|
|
||||||
|
|
||||||
# Runs Hex
|
|
||||||
async def runHex(channel,command,user):
|
|
||||||
try:
|
|
||||||
response, showImage, deleteImage, gameDone, gwendoTurn = parseHex(command,str(channel.id),user)
|
|
||||||
except:
|
|
||||||
logThis("Error parsing command (error code 1510)")
|
|
||||||
|
|
||||||
await channel.send(response)
|
|
||||||
logThis(response,str(channel.id))
|
|
||||||
if showImage:
|
|
||||||
if deleteImage:
|
|
||||||
try:
|
|
||||||
oldImage = await deleteMessage("hex"+str(channel.id),channel)
|
|
||||||
except:
|
|
||||||
logThis("Error deleting old image (error code 1501)")
|
|
||||||
oldImage = await channel.send(file = discord.File("resources/games/hexBoards/board"+str(channel.id)+".png"))
|
|
||||||
if not gameDone:
|
|
||||||
if gwendoTurn:
|
|
||||||
try:
|
|
||||||
response, showImage, deleteImage, gameDone, gwendoTurn = hexAI(str(channel.id))
|
|
||||||
except:
|
|
||||||
response, showImage, deleteImage, gameDone, gwendoTurn = "An AI error occured",False,False,False,False
|
|
||||||
logThis("AI error (error code 1520)")
|
|
||||||
await channel.send(response)
|
|
||||||
logThis(response,str(channel.id))
|
|
||||||
if showImage:
|
|
||||||
if deleteImage:
|
|
||||||
await oldImage.delete()
|
|
||||||
oldImage = await channel.send(file = discord.File("resources/games/hexBoards/board"+str(channel.id)+".png"))
|
|
||||||
|
|
||||||
else:
|
|
||||||
with open("resources/games/oldImages/hex"+str(channel.id), "w") as f:
|
|
||||||
f.write(str(oldImage.id))
|
|
||||||
|
|
||||||
if gameDone:
|
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
winner = data[str(channel.id)]["winner"]
|
|
||||||
if winner != 0 and data[channel]["players"][0] != data[channel]["players"][1]: # player1 != player2
|
|
||||||
winnings = data[str(channel.id)]["difficulty"]*10
|
|
||||||
addMoney(data[str(channel.id)]["players"][winner-1].lower(),winnings)
|
|
||||||
|
|
||||||
#deleteGame("hex games",str(channel.id))
|
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
del data[str(channel.id)]
|
|
||||||
with open("resources/games/hexGames.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
|
|
||||||
|
# Deletes a message
|
||||||
# Runs Four in a Row
|
async def deleteMessage(self, imageLocation,channel):
|
||||||
async def fiar(channel,command,user):
|
|
||||||
try:
|
|
||||||
response, showImage, deleteImage, gameDone, gwendoTurn = parseFourInARow(command,str(channel.id),user)
|
|
||||||
except:
|
|
||||||
logThis("Error parsing command (error code 1410)")
|
|
||||||
|
|
||||||
await channel.send(response)
|
|
||||||
logThis(response,str(channel.id))
|
|
||||||
if showImage:
|
|
||||||
if deleteImage:
|
|
||||||
try:
|
|
||||||
oldImage = await deleteMessage("fourInARow"+str(channel.id),channel)
|
|
||||||
except:
|
|
||||||
logThis("Error deleting message (error code 1401)")
|
|
||||||
oldImage = await channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(channel.id)+".png"))
|
|
||||||
if gameDone == False:
|
|
||||||
if gwendoTurn:
|
|
||||||
try:
|
|
||||||
response, showImage, deleteImage, gameDone, gwendoTurn = await fourInARowAI(str(channel.id))
|
|
||||||
except:
|
|
||||||
logThis("AI error (error code 1420)")
|
|
||||||
await channel.send(response)
|
|
||||||
logThis(response,str(channel.id))
|
|
||||||
if showImage:
|
|
||||||
if deleteImage:
|
|
||||||
await oldImage.delete()
|
|
||||||
oldImage = await channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(channel.id)+".png"))
|
|
||||||
if gameDone == False:
|
|
||||||
with open("resources/games/oldImages/fourInARow"+str(channel.id), "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:
|
|
||||||
logThis("Image deleted before I could react to all of them")
|
|
||||||
|
|
||||||
else:
|
|
||||||
with open("resources/games/oldImages/fourInARow"+str(channel.id), "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:
|
|
||||||
logThis("Image deleted before I could react to all of them")
|
|
||||||
|
|
||||||
if gameDone:
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open("resources/games/oldImages/fourInARow"+str(channel.id), "r") as f:
|
with open("resources/games/oldImages/"+imageLocation, "r") as f:
|
||||||
oldImage = await channel.fetch_message(int(f.read()))
|
messages = f.read().splitlines()
|
||||||
|
|
||||||
await oldImage.delete()
|
for message in messages:
|
||||||
|
oldMessage = await channel.fetch_message(int(message))
|
||||||
|
logThis("Deleting old message")
|
||||||
|
await oldMessage.delete()
|
||||||
except:
|
except:
|
||||||
logThis("The old image was already deleted")
|
oldMessage = ""
|
||||||
|
|
||||||
winner = data["4 in a row games"][str(channel.id)]["winner"]
|
return oldMessage
|
||||||
difficulty = int(data["4 in a row games"][str(channel.id)]["difficulty"])
|
|
||||||
reward = difficulty**2 + 5
|
|
||||||
if winner != 0:
|
|
||||||
if data["4 in a row games"][str(channel.id)]["players"][winner-1].lower() != "gwendolyn":
|
|
||||||
addMoney(data["4 in a row games"][str(channel.id)]["players"][winner-1].lower(),reward)
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f) #why is this here?
|
|
||||||
|
|
||||||
deleteGame("4 in a row games",str(channel.id))
|
# Runs Four in a Row
|
||||||
|
async def fiar(self, channel,command,user):
|
||||||
|
try:
|
||||||
|
response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.fourInARow.parseFourInARow(command,str(channel.id),user)
|
||||||
|
except:
|
||||||
|
logThis("Error parsing command (error code 1410)")
|
||||||
|
|
||||||
async def runMonopoly(channel, command, user):
|
|
||||||
try:
|
|
||||||
response, showImage, deleteImage, gameStarted, gameContinue = parseMonopoly(command,str(channel.id),user)
|
|
||||||
except:
|
|
||||||
logThis("Error parsing command (error code 1610)")
|
|
||||||
if response != "":
|
|
||||||
await channel.send(response)
|
await channel.send(response)
|
||||||
logThis(response,str(channel.id))
|
logThis(response,str(channel.id))
|
||||||
if showImage:
|
|
||||||
if deleteImage:
|
|
||||||
try:
|
|
||||||
oldImage = await deleteMessage("monopoly"+str(channel.id),channel)
|
|
||||||
except:
|
|
||||||
logThis("Error deleting message (error code 1601)")
|
|
||||||
oldImage = await channel.send(file = discord.File("resources/games/monopolyBoards/monopolyBoard"+str(channel.id)+".png"))
|
|
||||||
with open("resources/games/oldImages/monopoly"+str(channel.id), "w") as f:
|
|
||||||
f.write(str(oldImage.id))
|
|
||||||
|
|
||||||
if gameContinue:
|
|
||||||
if gameStarted:
|
|
||||||
await asyncio.sleep(60)
|
|
||||||
else:
|
|
||||||
await asyncio.sleep(3)
|
|
||||||
response, showImage, deleteImage, gameDone = monopolyContinue(str(channel.id))
|
|
||||||
em = discord.Embed(description=response,colour = 0x59f442)
|
|
||||||
await channel.send(embed=em)
|
|
||||||
if showImage:
|
if showImage:
|
||||||
if deleteImage:
|
if deleteImage:
|
||||||
try:
|
try:
|
||||||
oldImage = await deleteMessage("monopoly"+str(channel.id),channel)
|
oldImage = await self.deleteMessage("fourInARow"+str(channel.id),channel)
|
||||||
|
except:
|
||||||
|
logThis("Error deleting message (error code 1401)")
|
||||||
|
oldImage = await channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(channel.id)+".png"))
|
||||||
|
if gameDone == False:
|
||||||
|
if gwendoTurn:
|
||||||
|
try:
|
||||||
|
response, showImage, deleteImage, gameDone, gwendoTurn = await self.bot.fourInARow.fourInARowAI(str(channel.id))
|
||||||
|
except:
|
||||||
|
logThis("AI error (error code 1420)")
|
||||||
|
await channel.send(response)
|
||||||
|
logThis(response,str(channel.id))
|
||||||
|
if showImage:
|
||||||
|
if deleteImage:
|
||||||
|
await oldImage.delete()
|
||||||
|
oldImage = await channel.send(file = discord.File("resources/games/4InARowBoards/board"+str(channel.id)+".png"))
|
||||||
|
if gameDone == False:
|
||||||
|
with open("resources/games/oldImages/fourInARow"+str(channel.id), "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:
|
||||||
|
logThis("Image deleted before I could react to all of them")
|
||||||
|
|
||||||
|
else:
|
||||||
|
with open("resources/games/oldImages/fourInARow"+str(channel.id), "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:
|
||||||
|
logThis("Image deleted before I could react to all of them")
|
||||||
|
|
||||||
|
if gameDone:
|
||||||
|
game = self.bot.database["4 in a row games"].find_one({"_id":str(channel.id)})
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open("resources/games/oldImages/fourInARow"+str(channel.id), "r") as f:
|
||||||
|
oldImage = await channel.fetch_message(int(f.read()))
|
||||||
|
|
||||||
|
await oldImage.delete()
|
||||||
|
except:
|
||||||
|
logThis("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.funcs.deleteGame("4 in a row games",str(channel.id))
|
||||||
|
|
||||||
|
async def runMonopoly(self,channel, command, user):
|
||||||
|
try:
|
||||||
|
response, showImage, deleteImage, gameStarted, gameContinue = self.bot.monopoly.parseMonopoly(command,str(channel.id),user)
|
||||||
|
except:
|
||||||
|
logThis("Error parsing command (error code 1610)")
|
||||||
|
if response != "":
|
||||||
|
await channel.send(response)
|
||||||
|
logThis(response,str(channel.id))
|
||||||
|
if showImage:
|
||||||
|
if deleteImage:
|
||||||
|
try:
|
||||||
|
oldImage = await self.deleteMessage("monopoly"+str(channel.id),channel)
|
||||||
except:
|
except:
|
||||||
logThis("Error deleting message (error code 1601)")
|
logThis("Error deleting message (error code 1601)")
|
||||||
oldImage = await channel.send(file = discord.File("resources/games/monopolyBoards/monopolyBoard"+str(channel.id)+".png"))
|
oldImage = await channel.send(file = discord.File("resources/games/monopolyBoards/monopolyBoard"+str(channel.id)+".png"))
|
||||||
with open("resources/games/oldImages/monopoly"+str(channel.id), "w") as f:
|
with open("resources/games/oldImages/monopoly"+str(channel.id), "w") as f:
|
||||||
f.write(str(oldImage.id))
|
f.write(str(oldImage.id))
|
||||||
if gameDone == False:
|
|
||||||
try:
|
|
||||||
await oldImage.add_reaction("🎲")
|
|
||||||
except:
|
|
||||||
logThis("Image deleted before I could react to all of them")
|
|
||||||
|
|
||||||
async def runHangman(channel,user,apiKey = "",command = "start"):
|
if gameContinue:
|
||||||
try:
|
if gameStarted:
|
||||||
response, showImage, deleteImage, remainingLetters = parseHangman(str(channel.id),user,command,apiKey)
|
await asyncio.sleep(60)
|
||||||
except:
|
else:
|
||||||
logThis("Error parsing command (error code 1701)")
|
await asyncio.sleep(3)
|
||||||
if response != "":
|
response, showImage, deleteImage, gameDone = self.bot.monopoly.monopolyContinue(str(channel.id))
|
||||||
|
em = discord.Embed(description=response,colour = 0x59f442)
|
||||||
|
await channel.send(embed=em)
|
||||||
|
if deleteImage:
|
||||||
|
try:
|
||||||
|
oldImage = await self.deleteMessage("monopoly"+str(channel.id),channel)
|
||||||
|
except:
|
||||||
|
logThis("Error deleting message (error code 1601)")
|
||||||
|
|
||||||
|
if showImage:
|
||||||
|
oldImage = await channel.send(file = discord.File("resources/games/monopolyBoards/monopolyBoard"+str(channel.id)+".png"))
|
||||||
|
with open("resources/games/oldImages/monopoly"+str(channel.id), "w") as f:
|
||||||
|
f.write(str(oldImage.id))
|
||||||
|
if gameDone == False:
|
||||||
|
try:
|
||||||
|
await oldImage.add_reaction("🎲")
|
||||||
|
except:
|
||||||
|
logThis("Image deleted before I could react to all of them")
|
||||||
|
|
||||||
|
async def runHangman(self,channel,user,command = "start"):
|
||||||
|
try:
|
||||||
|
response, showImage, deleteImage, remainingLetters = self.bot.hangman.parseHangman(str(channel.id),user,command)
|
||||||
|
except:
|
||||||
|
logThis("Error parsing command (error code 1701)")
|
||||||
|
if response != "":
|
||||||
|
await channel.send(response)
|
||||||
|
logThis(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:
|
||||||
|
logThis("Image deleted before adding all reactions")
|
||||||
|
|
||||||
|
# Runs Hex
|
||||||
|
async def runHex(self,channel,command,user):
|
||||||
|
try:
|
||||||
|
response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.hex.parseHex(command,str(channel.id),user)
|
||||||
|
except:
|
||||||
|
logThis("Error parsing command (error code 1510)")
|
||||||
|
|
||||||
await channel.send(response)
|
await channel.send(response)
|
||||||
logThis(response,str(channel.id))
|
logThis(response,str(channel.id))
|
||||||
if showImage:
|
if showImage:
|
||||||
if deleteImage:
|
if deleteImage:
|
||||||
await deleteMessage("hangman"+str(channel.id),channel)
|
try:
|
||||||
oldImage = await channel.send(file = discord.File("resources/games/hangmanBoards/hangmanBoard"+str(channel.id)+".png"))
|
oldImage = await self.deleteMessage("hex"+str(channel.id),channel)
|
||||||
|
except:
|
||||||
|
logThis("Error deleting old image (error code 1501)")
|
||||||
|
oldImage = await channel.send(file = discord.File("resources/games/hexBoards/board"+str(channel.id)+".png"))
|
||||||
|
if not gameDone:
|
||||||
|
if gwendoTurn:
|
||||||
|
try:
|
||||||
|
response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.hex.hexAI(str(channel.id))
|
||||||
|
except:
|
||||||
|
response, showImage, deleteImage, gameDone, gwendoTurn = "An AI error occured",False,False,False,False
|
||||||
|
logThis("AI error (error code 1520)")
|
||||||
|
await channel.send(response)
|
||||||
|
logThis(response,str(channel.id))
|
||||||
|
if showImage:
|
||||||
|
if deleteImage:
|
||||||
|
await oldImage.delete()
|
||||||
|
oldImage = await channel.send(file = discord.File("resources/games/hexBoards/board"+str(channel.id)+".png"))
|
||||||
|
|
||||||
if len(remainingLetters) > 15:
|
else:
|
||||||
otherMessage = await channel.send("_ _")
|
with open("resources/games/oldImages/hex"+str(channel.id), "w") as f:
|
||||||
reactionMessages = {oldImage : remainingLetters[:15],otherMessage : remainingLetters[15:]}
|
f.write(str(oldImage.id))
|
||||||
else:
|
|
||||||
otherMessage = ""
|
|
||||||
reactionMessages = {oldImage : remainingLetters}
|
|
||||||
|
|
||||||
oldMessages = str(oldImage.id)
|
if gameDone:
|
||||||
if otherMessage != "":
|
game = self.bot.database["hexGames"].find_one({"_id":str(channel.id)})
|
||||||
oldMessages += "\n"+str(otherMessage.id)
|
print(game)
|
||||||
with open("resources/games/oldImages/hangman"+str(channel.id), "w") as f:
|
winner = game["winner"]
|
||||||
f.write(oldMessages)
|
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)
|
||||||
|
|
||||||
try:
|
self.bot.funcs.deleteGame("hex games",str(channel.id))
|
||||||
for message, letters in reactionMessages.items():
|
|
||||||
for letter in letters:
|
|
||||||
emoji = chr(ord(letter)+127397)
|
|
||||||
await message.add_reaction(emoji)
|
|
||||||
except:
|
|
||||||
logThis("Image deleted before adding all reactions")
|
|
||||||
|
21
funcs/games/games.py
Normal file
21
funcs/games/games.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from .invest import Invest
|
||||||
|
from .trivia import Trivia
|
||||||
|
from .blackjack import Blackjack
|
||||||
|
from .fourInARow import FourInARow
|
||||||
|
from .gameLoops import GameLoops
|
||||||
|
from .monopoly import Monopoly
|
||||||
|
from .hangman import Hangman
|
||||||
|
from .hex import HexGame
|
||||||
|
|
||||||
|
class Games():
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
bot.invest = Invest(bot)
|
||||||
|
bot.trivia = Trivia(bot)
|
||||||
|
bot.blackjack = Blackjack(bot)
|
||||||
|
bot.fourInARow = FourInARow(bot)
|
||||||
|
bot.gameLoops = GameLoops(bot)
|
||||||
|
bot.monopoly = Monopoly(bot)
|
||||||
|
bot.hangman = Hangman(bot)
|
||||||
|
bot.hex = HexGame(bot)
|
@ -1,114 +1,110 @@
|
|||||||
import json, urllib, datetime, string
|
import json, urllib, datetime, string
|
||||||
|
|
||||||
from . import hangmanDraw, money
|
from .hangmanDraw import DrawHangman
|
||||||
from funcs import getName, logThis
|
from funcs import logThis
|
||||||
|
|
||||||
apiUrl = "https://api.wordnik.com/v4/words.json/randomWords?hasDictionaryDef=true&minCorpusCount=5000&maxCorpusCount=-1&minDictionaryCount=1&maxDictionaryCount=-1&minLength=3&maxLength=11&limit=1&api_key="
|
apiUrl = "https://api.wordnik.com/v4/words.json/randomWords?hasDictionaryDef=true&minCorpusCount=5000&maxCorpusCount=-1&minDictionaryCount=1&maxDictionaryCount=-1&minLength=3&maxLength=11&limit=1&api_key="
|
||||||
|
|
||||||
def hangmanStart(channel,user,apiKey):
|
class Hangman():
|
||||||
with open("resources/games/hangmanGames.json", "r") as f:
|
def __init__(self,bot):
|
||||||
data = json.load(f)
|
self.bot = bot
|
||||||
|
self.draw = DrawHangman(bot)
|
||||||
|
|
||||||
if channel not in data:
|
def hangmanStart(self,channel,user):
|
||||||
with urllib.request.urlopen(apiUrl+apiKey) as p:
|
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
||||||
word = list(json.load(p)[0]["word"].upper())
|
|
||||||
logThis("Found the word \""+"".join(word)+"\"")
|
|
||||||
guessed = [False] * len(word)
|
|
||||||
gameID = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
|
||||||
data[channel] = {"player" : user,"guessed letters" : [],"word" : word,"game ID" : gameID,"misses" : 0,"guessed" : guessed}
|
|
||||||
|
|
||||||
remainingLetters = list(string.ascii_uppercase)
|
if game == None:
|
||||||
|
apiKey = self.bot.credentials.wordnikKey
|
||||||
|
with urllib.request.urlopen(apiUrl+apiKey) as p:
|
||||||
|
word = list(json.load(p)[0]["word"].upper())
|
||||||
|
logThis("Found the word \""+"".join(word)+"\"")
|
||||||
|
guessed = [False] * len(word)
|
||||||
|
gameID = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||||
|
newGame = {"_id":channel,"player" : user,"guessed letters" : [],"word" : word,"game ID" : gameID,"misses" : 0,"guessed" : guessed}
|
||||||
|
self.bot.database["hangman games"].insert_one(newGame)
|
||||||
|
|
||||||
with open("resources/games/hangmanGames.json", "w") as f:
|
remainingLetters = list(string.ascii_uppercase)
|
||||||
json.dump(data,f)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
hangmanDraw.drawImage(channel)
|
self.draw.drawImage(channel)
|
||||||
except:
|
except:
|
||||||
logThis("Error drawing image (error code 1710)")
|
logThis("Error drawing image (error code 1710)")
|
||||||
return f"{getName(user)} started game of hangman.", True, False, remainingLetters
|
return f"{self.bot.funcs.getName(user)} started game of hangman.", True, False, remainingLetters
|
||||||
else:
|
else:
|
||||||
return "There's already a Hangman game going on in the channel", False, False, []
|
return "There's already a Hangman game going on in the channel", False, False, []
|
||||||
|
|
||||||
def hangmanStop(channel):
|
def hangmanStop(self,channel):
|
||||||
with open("resources/games/hangmanGames.json", "r") as f:
|
self.bot.database["hangman games"].delete_one({"_id":channel})
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
del data[channel]
|
return "Game stopped.", False, False, []
|
||||||
with open("resources/games/hangmanGames.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
return "Game stopped.", False, False, []
|
def hangmanGuess(self,channel,user,guess):
|
||||||
|
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
||||||
|
|
||||||
def hangmanGuess(channel,user,guess):
|
if game != None:
|
||||||
with open("resources/games/hangmanGames.json", "r") as f:
|
if user == game["player"]:
|
||||||
data = json.load(f)
|
if len(guess) == 1:
|
||||||
|
if guess not in game["guessed letters"]:
|
||||||
|
correctGuess = 0
|
||||||
|
|
||||||
if channel in data:
|
for x, letter in enumerate(game["word"]):
|
||||||
if user == data[channel]["player"]:
|
if guess == letter:
|
||||||
if len(guess) == 1:
|
correctGuess += 1
|
||||||
if guess not in data[channel]["guessed letters"]:
|
self.bot.database["hangman games"].update_one({"_id":channel},{"$set":{"guessed."+str(x):True}})
|
||||||
correctGuess = 0
|
|
||||||
|
|
||||||
for x, letter in enumerate(data[channel]["word"]):
|
if correctGuess == 0:
|
||||||
if guess == letter:
|
self.bot.database["hangman games"].update_one({"_id":channel},{"$inc":{"misses":1}})
|
||||||
correctGuess += 1
|
|
||||||
data[channel]["guessed"][x] = True
|
|
||||||
|
|
||||||
if correctGuess == 0:
|
self.bot.database["hangman games"].update_one({"_id":channel},{"$push":{"guessed letters":guess}})
|
||||||
data[channel]["misses"] += 1
|
|
||||||
|
|
||||||
data[channel]["guessed letters"].append(guess)
|
remainingLetters = list(string.ascii_uppercase)
|
||||||
|
|
||||||
remainingLetters = list(string.ascii_uppercase)
|
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
||||||
|
|
||||||
for letter in data[channel]["guessed letters"]:
|
for letter in game["guessed letters"]:
|
||||||
remainingLetters.remove(letter)
|
remainingLetters.remove(letter)
|
||||||
|
|
||||||
if correctGuess == 1:
|
if correctGuess == 1:
|
||||||
message = f"Guessed {guess}. There was 1 {guess} in the word."
|
message = f"Guessed {guess}. There was 1 {guess} in the word."
|
||||||
|
else:
|
||||||
|
message = f"Guessed {guess}. There were {correctGuess} {guess}s in the word."
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw.drawImage(channel)
|
||||||
|
except:
|
||||||
|
logThis("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:
|
else:
|
||||||
message = f"Guessed {guess}. There were {correctGuess} {guess}s in the word."
|
return f"You've already guessed {guess}", False, False, []
|
||||||
|
|
||||||
with open("resources/games/hangmanGames.json", "w") as f:
|
|
||||||
json.dump(data,f)
|
|
||||||
|
|
||||||
try:
|
|
||||||
hangmanDraw.drawImage(channel)
|
|
||||||
except:
|
|
||||||
logThis("Error drawing image (error code 1710)")
|
|
||||||
|
|
||||||
if data[channel]["misses"] == 6:
|
|
||||||
hangmanStop(channel)
|
|
||||||
return message+" You've guessed wrong six times and have lost the game.", True, True, []
|
|
||||||
elif all(i == True for i in data[channel]["guessed"]):
|
|
||||||
hangmanStop(channel)
|
|
||||||
money.addMoney(user,15)
|
|
||||||
return message+" You've guessed the word! Congratulations! Adding 15 GwendoBucks to your account", True, True, []
|
|
||||||
else:
|
|
||||||
return message, True, True, remainingLetters
|
|
||||||
else:
|
else:
|
||||||
return f"You've already guessed {guess}", False, False, []
|
return "", False, False, []
|
||||||
else:
|
else:
|
||||||
return "", False, False, []
|
return "", False, False, []
|
||||||
else:
|
else:
|
||||||
return "", False, False, []
|
return "There's no Hangman game going on in this channel", False, False, []
|
||||||
else:
|
|
||||||
return "There's no Hangman game going on in this channel", False, False, []
|
|
||||||
|
|
||||||
def parseHangman(channel,user,command,apiKey):
|
def parseHangman(self,channel,user,command):
|
||||||
if command == "start":
|
if command == "start":
|
||||||
try:
|
try:
|
||||||
return hangmanStart(channel,user,apiKey)
|
return self.hangmanStart(channel,user)
|
||||||
except:
|
except:
|
||||||
logThis("Error starting game (error code 1730)")
|
logThis("Error starting game (error code 1730)")
|
||||||
elif command == "stop":
|
elif command == "stop":
|
||||||
return hangmanStop(channel)
|
return self.hangmanStop(channel)
|
||||||
elif command.startswith("guess "):
|
elif command.startswith("guess "):
|
||||||
guess = command[6:].upper()
|
guess = command[6:].upper()
|
||||||
try:
|
try:
|
||||||
return hangmanGuess(channel,user,guess)
|
return self.hangmanGuess(channel,user,guess)
|
||||||
except:
|
except:
|
||||||
logThis("Error in guessing (Error Code 1720)")
|
logThis("Error in guessing (Error Code 1720)")
|
||||||
else:
|
else:
|
||||||
return "I didn't understand that", False, False, []
|
return "I didn't understand that", False, False, []
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import math, random, json
|
import math, random
|
||||||
|
|
||||||
from PIL import ImageDraw, Image, ImageFont
|
from PIL import ImageDraw, Image, ImageFont
|
||||||
from funcs import logThis
|
from funcs import logThis
|
||||||
@ -28,222 +28,226 @@ smolfnt = ImageFont.truetype('resources/comic-sans-bold.ttf', textSize)
|
|||||||
|
|
||||||
backgroundColor = (255,255,255,255)
|
backgroundColor = (255,255,255,255)
|
||||||
|
|
||||||
def calcDeviance(preDev,preDevAcc,posChange,maxmin,maxAcceleration):
|
class DrawHangman():
|
||||||
devAcc = preDevAcc + random.uniform(-posChange,posChange)
|
def __init__(self,bot):
|
||||||
if devAcc > maxmin * maxAcceleration: devAcc = maxmin * maxAcceleration
|
self.bot = bot
|
||||||
elif devAcc < -maxmin * maxAcceleration: devAcc = -maxmin * maxAcceleration
|
|
||||||
|
|
||||||
dev = preDev + devAcc
|
def calcDeviance(self,preDev,preDevAcc,posChange,maxmin,maxAcceleration):
|
||||||
if dev > maxmin: dev = maxmin
|
devAcc = preDevAcc + random.uniform(-posChange,posChange)
|
||||||
elif dev < -maxmin: dev = -maxmin
|
if devAcc > maxmin * maxAcceleration: devAcc = maxmin * maxAcceleration
|
||||||
return dev, devAcc
|
elif devAcc < -maxmin * maxAcceleration: devAcc = -maxmin * maxAcceleration
|
||||||
|
|
||||||
def badCircle():
|
dev = preDev + devAcc
|
||||||
background = Image.new("RGBA",(circleSize+(lineWidth*3),circleSize+(lineWidth*3)),color=(0,0,0,0))
|
if dev > maxmin: dev = maxmin
|
||||||
|
elif dev < -maxmin: dev = -maxmin
|
||||||
|
return dev, devAcc
|
||||||
|
|
||||||
d = ImageDraw.Draw(background,"RGBA")
|
def badCircle(self):
|
||||||
middle = (circleSize+(lineWidth*3))/2
|
background = Image.new("RGBA",(circleSize+(lineWidth*3),circleSize+(lineWidth*3)),color=(0,0,0,0))
|
||||||
devx = 0
|
|
||||||
devy = 0
|
|
||||||
devAccx = 0
|
|
||||||
devAccy = 0
|
|
||||||
start = random.randint(-100,-80)
|
|
||||||
degreesAmount = circleDegrees + random.randint(-10,30)
|
|
||||||
|
|
||||||
for degree in range(degreesAmount):
|
d = ImageDraw.Draw(background,"RGBA")
|
||||||
devx, devAccx = calcDeviance(devx,devAccx,lineWidth/100,lineWidth,0.03)
|
middle = (circleSize+(lineWidth*3))/2
|
||||||
devy, devAccy = calcDeviance(devy,devAccy,lineWidth/100,lineWidth,0.03)
|
devx = 0
|
||||||
|
devy = 0
|
||||||
|
devAccx = 0
|
||||||
|
devAccy = 0
|
||||||
|
start = random.randint(-100,-80)
|
||||||
|
degreesAmount = circleDegrees + random.randint(-10,30)
|
||||||
|
|
||||||
x = middle + (math.cos(math.radians(degree+start)) * (circleSize/2)) - (lineWidth/2) + devx
|
for degree in range(degreesAmount):
|
||||||
y = middle + (math.sin(math.radians(degree+start)) * (circleSize/2)) - (lineWidth/2) + devy
|
devx, devAccx = self.calcDeviance(devx,devAccx,lineWidth/100,lineWidth,0.03)
|
||||||
|
devy, devAccy = self.calcDeviance(devy,devAccy,lineWidth/100,lineWidth,0.03)
|
||||||
|
|
||||||
d.ellipse([(x,y),(x+lineWidth,y+lineWidth)],fill=(0,0,0,255))
|
x = middle + (math.cos(math.radians(degree+start)) * (circleSize/2)) - (lineWidth/2) + devx
|
||||||
|
y = middle + (math.sin(math.radians(degree+start)) * (circleSize/2)) - (lineWidth/2) + devy
|
||||||
|
|
||||||
return background
|
d.ellipse([(x,y),(x+lineWidth,y+lineWidth)],fill=(0,0,0,255))
|
||||||
|
|
||||||
def badLine(length, rotated = False):
|
return background
|
||||||
if rotated:
|
|
||||||
w, h = length+lineWidth*3, lineWidth*3
|
|
||||||
else:
|
|
||||||
w, h = lineWidth*3,length+lineWidth*3
|
|
||||||
background = Image.new("RGBA",(w,h),color=(0,0,0,0))
|
|
||||||
|
|
||||||
d = ImageDraw.Draw(background,"RGBA")
|
|
||||||
devx = random.randint(-int(lineWidth/3),int(lineWidth/3))
|
|
||||||
devy = 0
|
|
||||||
devAccx = 0
|
|
||||||
devAccy = 0
|
|
||||||
|
|
||||||
for pixel in range(length):
|
|
||||||
devx, devAccx = calcDeviance(devx,devAccx,lineWidth/1000,lineWidth,0.004)
|
|
||||||
devy, devAccy = calcDeviance(devy,devAccy,lineWidth/1000,lineWidth,0.004)
|
|
||||||
|
|
||||||
|
def badLine(self, length, rotated = False):
|
||||||
if rotated:
|
if rotated:
|
||||||
x = lineWidth + pixel + devx
|
w, h = length+lineWidth*3, lineWidth*3
|
||||||
y = lineWidth + devy
|
|
||||||
else:
|
else:
|
||||||
x = lineWidth + devx
|
w, h = lineWidth*3,length+lineWidth*3
|
||||||
y = lineWidth + pixel + devy
|
background = Image.new("RGBA",(w,h),color=(0,0,0,0))
|
||||||
|
|
||||||
d.ellipse([(x,y),(x+lineWidth,y+lineWidth)],fill=(0,0,0,255))
|
d = ImageDraw.Draw(background,"RGBA")
|
||||||
|
devx = random.randint(-int(lineWidth/3),int(lineWidth/3))
|
||||||
|
devy = 0
|
||||||
|
devAccx = 0
|
||||||
|
devAccy = 0
|
||||||
|
|
||||||
return background
|
for pixel in range(length):
|
||||||
|
devx, devAccx = self.calcDeviance(devx,devAccx,lineWidth/1000,lineWidth,0.004)
|
||||||
|
devy, devAccy = self.calcDeviance(devy,devAccy,lineWidth/1000,lineWidth,0.004)
|
||||||
|
|
||||||
def drawMan(misses):
|
if rotated:
|
||||||
background = Image.new("RGBA",(manx,many),color=(0,0,0,0))
|
x = lineWidth + pixel + devx
|
||||||
|
y = lineWidth + devy
|
||||||
|
else:
|
||||||
|
x = lineWidth + devx
|
||||||
|
y = lineWidth + pixel + devy
|
||||||
|
|
||||||
if misses >= 1:
|
d.ellipse([(x,y),(x+lineWidth,y+lineWidth)],fill=(0,0,0,255))
|
||||||
head = badCircle()
|
|
||||||
background.paste(head,(int((manx-(circleSize+(lineWidth*3)))/2),0),head)
|
|
||||||
if misses >= 2:
|
|
||||||
body = badLine(bodySize)
|
|
||||||
background.paste(body,(int((manx-(lineWidth*3))/2),circleSize),body)
|
|
||||||
|
|
||||||
if misses >= 3:
|
return background
|
||||||
limbs = random.sample(["rl","ll","ra","la"],min(misses-2,4))
|
|
||||||
else: limbs = []
|
|
||||||
|
|
||||||
for limb in limbs:
|
def drawMan(self, misses):
|
||||||
if limb == "ra":
|
background = Image.new("RGBA",(manx,many),color=(0,0,0,0))
|
||||||
limbDrawing = badLine(limbSize,True)
|
|
||||||
rotation = random.randint(-45,45)
|
|
||||||
xpos = int((manx-(lineWidth*3))/2)
|
|
||||||
rotationCompensation = min(-int(math.sin(math.radians(rotation))*(limbSize+(lineWidth*3))),0)
|
|
||||||
ypos = circleSize+armPosition + rotationCompensation
|
|
||||||
limbDrawing = limbDrawing.rotate(rotation,expand=1)
|
|
||||||
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
|
|
||||||
elif limb == "la":
|
|
||||||
limbDrawing = badLine(limbSize,True)
|
|
||||||
rotation = random.randint(-45,45)
|
|
||||||
xpos = int((manx-(lineWidth*3))/2)-limbSize
|
|
||||||
rotationCompensation = min(int(math.sin(math.radians(rotation))*(limbSize+(lineWidth*3))),0)
|
|
||||||
ypos = circleSize+armPosition + rotationCompensation
|
|
||||||
limbDrawing = limbDrawing.rotate(rotation,expand=1)
|
|
||||||
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
|
|
||||||
elif limb == "rl":
|
|
||||||
limbDrawing = badLine(limbSize,True)
|
|
||||||
rotation = random.randint(-15,15)
|
|
||||||
xpos = int((manx-(lineWidth*3))/2)-lineWidth
|
|
||||||
ypos = circleSize+bodySize-lineWidth
|
|
||||||
limbDrawing = limbDrawing.rotate(rotation-45,expand=1)
|
|
||||||
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
|
|
||||||
elif limb == "ll":
|
|
||||||
limbDrawing = badLine(limbSize,True)
|
|
||||||
rotation = random.randint(-15,15)
|
|
||||||
limbDrawing = limbDrawing.rotate(rotation+45,expand=1)
|
|
||||||
xpos = int((manx-(lineWidth*3))/2)-limbDrawing.size[0]+lineWidth*3
|
|
||||||
ypos = circleSize+bodySize
|
|
||||||
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
|
|
||||||
|
|
||||||
return background
|
if misses >= 1:
|
||||||
|
head = self.badCircle()
|
||||||
|
background.paste(head,(int((manx-(circleSize+(lineWidth*3)))/2),0),head)
|
||||||
|
if misses >= 2:
|
||||||
|
body = self.badLine(bodySize)
|
||||||
|
background.paste(body,(int((manx-(lineWidth*3))/2),circleSize),body)
|
||||||
|
|
||||||
def badText(text, big, color=(0,0,0,255)):
|
if misses >= 3:
|
||||||
if big: font = fnt
|
limbs = random.sample(["rl","ll","ra","la"],min(misses-2,4))
|
||||||
else: font = smolfnt
|
else: limbs = []
|
||||||
w, h = font.getsize(text)
|
|
||||||
img = Image.new("RGBA",(w,h),color=(0,0,0,0))
|
|
||||||
d = ImageDraw.Draw(img,"RGBA")
|
|
||||||
|
|
||||||
d.text((0,0),text,font=font,fill=color)
|
for limb in limbs:
|
||||||
return img
|
if limb == "ra":
|
||||||
|
limbDrawing = self.badLine(limbSize,True)
|
||||||
|
rotation = random.randint(-45,45)
|
||||||
|
xpos = int((manx-(lineWidth*3))/2)
|
||||||
|
rotationCompensation = min(-int(math.sin(math.radians(rotation))*(limbSize+(lineWidth*3))),0)
|
||||||
|
ypos = circleSize+armPosition + rotationCompensation
|
||||||
|
limbDrawing = limbDrawing.rotate(rotation,expand=1)
|
||||||
|
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
|
||||||
|
elif limb == "la":
|
||||||
|
limbDrawing = self.badLine(limbSize,True)
|
||||||
|
rotation = random.randint(-45,45)
|
||||||
|
xpos = int((manx-(lineWidth*3))/2)-limbSize
|
||||||
|
rotationCompensation = min(int(math.sin(math.radians(rotation))*(limbSize+(lineWidth*3))),0)
|
||||||
|
ypos = circleSize+armPosition + rotationCompensation
|
||||||
|
limbDrawing = limbDrawing.rotate(rotation,expand=1)
|
||||||
|
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
|
||||||
|
elif limb == "rl":
|
||||||
|
limbDrawing = self.badLine(limbSize,True)
|
||||||
|
rotation = random.randint(-15,15)
|
||||||
|
xpos = int((manx-(lineWidth*3))/2)-lineWidth
|
||||||
|
ypos = circleSize+bodySize-lineWidth
|
||||||
|
limbDrawing = limbDrawing.rotate(rotation-45,expand=1)
|
||||||
|
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
|
||||||
|
elif limb == "ll":
|
||||||
|
limbDrawing = self.badLine(limbSize,True)
|
||||||
|
rotation = random.randint(-15,15)
|
||||||
|
limbDrawing = limbDrawing.rotate(rotation+45,expand=1)
|
||||||
|
xpos = int((manx-(lineWidth*3))/2)-limbDrawing.size[0]+lineWidth*3
|
||||||
|
ypos = circleSize+bodySize
|
||||||
|
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
|
||||||
|
|
||||||
def drawGallows():
|
return background
|
||||||
background = Image.new("RGBA",(gallowx,gallowy),color=(0,0,0,0))
|
|
||||||
|
|
||||||
bottomLine = badLine(int(gallowx*0.75),True)
|
def badText(self, text, big, color=(0,0,0,255)):
|
||||||
background.paste(bottomLine,(int(gallowx*0.125),gallowy-(lineWidth*4)),bottomLine)
|
if big: font = fnt
|
||||||
|
else: font = smolfnt
|
||||||
|
w, h = font.getsize(text)
|
||||||
|
img = Image.new("RGBA",(w,h),color=(0,0,0,0))
|
||||||
|
d = ImageDraw.Draw(img,"RGBA")
|
||||||
|
|
||||||
lineTwo = badLine(gallowy-lineWidth*6)
|
d.text((0,0),text,font=font,fill=color)
|
||||||
background.paste(lineTwo,(int(gallowx*(0.75*goldenRatio)),lineWidth*2),lineTwo)
|
return img
|
||||||
|
|
||||||
topLine = badLine(int(gallowy*0.30),True)
|
def drawGallows(self):
|
||||||
background.paste(topLine,(int(gallowx*(0.75*goldenRatio))-lineWidth,lineWidth*3),topLine)
|
background = Image.new("RGBA",(gallowx,gallowy),color=(0,0,0,0))
|
||||||
|
|
||||||
lastLine = badLine(int(gallowy*0.125))
|
bottomLine = self.badLine(int(gallowx*0.75),True)
|
||||||
background.paste(lastLine,((int(gallowx*(0.75*goldenRatio))+int(gallowy*0.30)-lineWidth),lineWidth*3),lastLine)
|
background.paste(bottomLine,(int(gallowx*0.125),gallowy-(lineWidth*4)),bottomLine)
|
||||||
return background
|
|
||||||
|
|
||||||
def drawLetterLines(word,guessed,misses):
|
lineTwo = self.badLine(gallowy-lineWidth*6)
|
||||||
letterLines = Image.new("RGBA",((letterLineLength+letterLineDistance)*len(word),letterLineLength+lineWidth*3),color=(0,0,0,0))
|
background.paste(lineTwo,(int(gallowx*(0.75*goldenRatio)),lineWidth*2),lineTwo)
|
||||||
for x, letter in enumerate(word):
|
|
||||||
line = badLine(letterLineLength,True)
|
|
||||||
letterLines.paste(line,(x*(letterLineLength+letterLineDistance),letterLineLength),line)
|
|
||||||
if guessed[x]:
|
|
||||||
letterDrawing = badText(letter,True)
|
|
||||||
letterWidth = fnt.getsize(letter)[0]
|
|
||||||
letterx = int(x*(letterLineLength+letterLineDistance)-(letterWidth/2)+(letterLineLength*0.5)+(lineWidth*2))
|
|
||||||
letterLines.paste(letterDrawing,(letterx,0),letterDrawing)
|
|
||||||
elif misses == 6:
|
|
||||||
letterDrawing = badText(letter,True,(242,66,54))
|
|
||||||
letterWidth = fnt.getsize(letter)[0]
|
|
||||||
letterx = int(x*(letterLineLength+letterLineDistance)-(letterWidth/2)+(letterLineLength*0.5)+(lineWidth*2))
|
|
||||||
letterLines.paste(letterDrawing,(letterx,0),letterDrawing)
|
|
||||||
|
|
||||||
return letterLines
|
topLine = self.badLine(int(gallowy*0.30),True)
|
||||||
|
background.paste(topLine,(int(gallowx*(0.75*goldenRatio))-lineWidth,lineWidth*3),topLine)
|
||||||
|
|
||||||
def shortestDist(positions,newPosition):
|
lastLine = self.badLine(int(gallowy*0.125))
|
||||||
shortestDist = math.inf
|
background.paste(lastLine,((int(gallowx*(0.75*goldenRatio))+int(gallowy*0.30)-lineWidth),lineWidth*3),lastLine)
|
||||||
x, y = newPosition
|
return background
|
||||||
for i, j in positions:
|
|
||||||
xdist = abs(i-x)
|
|
||||||
ydist = abs(j-y)
|
|
||||||
dist = math.sqrt(xdist**2+ydist**2)
|
|
||||||
if shortestDist > dist: shortestDist = dist
|
|
||||||
return shortestDist
|
|
||||||
|
|
||||||
def drawMisses(guesses,word):
|
def drawLetterLines(self, word,guessed,misses):
|
||||||
background = Image.new("RGBA",(600,400),color=(0,0,0,0))
|
letterLines = Image.new("RGBA",((letterLineLength+letterLineDistance)*len(word),letterLineLength+lineWidth*3),color=(0,0,0,0))
|
||||||
pos = []
|
for x, letter in enumerate(word):
|
||||||
for guess in guesses:
|
line = self.badLine(letterLineLength,True)
|
||||||
if guess not in word:
|
letterLines.paste(line,(x*(letterLineLength+letterLineDistance),letterLineLength),line)
|
||||||
placed = False
|
if guessed[x]:
|
||||||
while placed == False:
|
letterDrawing = self.badText(letter,True)
|
||||||
letter = badText(guess,True)
|
letterWidth = fnt.getsize(letter)[0]
|
||||||
w, h = fnt.getsize(guess)
|
letterx = int(x*(letterLineLength+letterLineDistance)-(letterWidth/2)+(letterLineLength*0.5)+(lineWidth*2))
|
||||||
x = random.randint(0,600-w)
|
letterLines.paste(letterDrawing,(letterx,0),letterDrawing)
|
||||||
y = random.randint(0,400-h)
|
elif misses == 6:
|
||||||
if shortestDist(pos,(x,y)) > 70:
|
letterDrawing = self.badText(letter,True,(242,66,54))
|
||||||
pos.append((x,y))
|
letterWidth = fnt.getsize(letter)[0]
|
||||||
background.paste(letter,(x,y),letter)
|
letterx = int(x*(letterLineLength+letterLineDistance)-(letterWidth/2)+(letterLineLength*0.5)+(lineWidth*2))
|
||||||
placed = True
|
letterLines.paste(letterDrawing,(letterx,0),letterDrawing)
|
||||||
return background
|
|
||||||
|
|
||||||
def drawImage(channel):
|
return letterLines
|
||||||
with open("resources/games/hangmanGames.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
random.seed(data[channel]["game ID"])
|
def shortestDist(self,positions,newPosition):
|
||||||
|
shortestDist = math.inf
|
||||||
|
x, y = newPosition
|
||||||
|
for i, j in positions:
|
||||||
|
xdist = abs(i-x)
|
||||||
|
ydist = abs(j-y)
|
||||||
|
dist = math.sqrt(xdist**2+ydist**2)
|
||||||
|
if shortestDist > dist: shortestDist = dist
|
||||||
|
return shortestDist
|
||||||
|
|
||||||
background = Image.open("resources/paper.jpg")
|
def drawMisses(self,guesses,word):
|
||||||
try:
|
background = Image.new("RGBA",(600,400),color=(0,0,0,0))
|
||||||
gallow = drawGallows()
|
pos = []
|
||||||
except:
|
for guess in guesses:
|
||||||
logThis("Error drawing gallows (error code 1711)")
|
if guess not in word:
|
||||||
|
placed = False
|
||||||
|
while placed == False:
|
||||||
|
letter = self.badText(guess,True)
|
||||||
|
w, h = fnt.getsize(guess)
|
||||||
|
x = random.randint(0,600-w)
|
||||||
|
y = random.randint(0,400-h)
|
||||||
|
if self.shortestDist(pos,(x,y)) > 70:
|
||||||
|
pos.append((x,y))
|
||||||
|
background.paste(letter,(x,y),letter)
|
||||||
|
placed = True
|
||||||
|
return background
|
||||||
|
|
||||||
try:
|
def drawImage(self,channel):
|
||||||
man = drawMan(data[channel]["misses"])
|
logThis("Drawing hangman image",channel)
|
||||||
except:
|
game = self.bot.database["hangman games"].find_one({"_id":channel})
|
||||||
logThis("Error drawing stick figure (error code 1712)")
|
|
||||||
|
|
||||||
random.seed(data[channel]["game ID"])
|
random.seed(game["game ID"])
|
||||||
try:
|
|
||||||
letterLines = drawLetterLines(data[channel]["word"],data[channel]["guessed"],data[channel]["misses"])
|
|
||||||
except:
|
|
||||||
logThis("error drawing letter lines (error code 1713)")
|
|
||||||
|
|
||||||
random.seed(data[channel]["game ID"])
|
background = Image.open("resources/paper.jpg")
|
||||||
try:
|
try:
|
||||||
misses = drawMisses(data[channel]["guessed letters"],data[channel]["word"])
|
gallow = self.drawGallows()
|
||||||
except:
|
except:
|
||||||
logThis("Error drawing misses (error code 1714)")
|
logThis("Error drawing gallows (error code 1711)")
|
||||||
|
|
||||||
background.paste(gallow,(100,100),gallow)
|
try:
|
||||||
background.paste(man,(300,210),man)
|
man = self.drawMan(game["misses"])
|
||||||
background.paste(letterLines,(120,840),letterLines)
|
except:
|
||||||
background.paste(misses,(600,150),misses)
|
logThis("Error drawing stick figure (error code 1712)")
|
||||||
|
|
||||||
missesText = badText("MISSES",False)
|
random.seed(game["game ID"])
|
||||||
missesTextWidth = missesText.size[0]
|
try:
|
||||||
background.paste(missesText,(850-int(missesTextWidth/2),50),missesText)
|
letterLines = self.drawLetterLines(game["word"],game["guessed"],game["misses"])
|
||||||
|
except:
|
||||||
|
logThis("error drawing letter lines (error code 1713)")
|
||||||
|
|
||||||
background.save("resources/games/hangmanBoards/hangmanBoard"+channel+".png")
|
random.seed(game["game ID"])
|
||||||
|
try:
|
||||||
|
misses = self.drawMisses(game["guessed letters"],game["word"])
|
||||||
|
except:
|
||||||
|
logThis("Error drawing misses (error code 1714)")
|
||||||
|
|
||||||
|
background.paste(gallow,(100,100),gallow)
|
||||||
|
background.paste(man,(300,210),man)
|
||||||
|
background.paste(letterLines,(120,840),letterLines)
|
||||||
|
background.paste(misses,(600,150),misses)
|
||||||
|
|
||||||
|
missesText = self.badText("MISSES",False)
|
||||||
|
missesTextWidth = missesText.size[0]
|
||||||
|
background.paste(missesText,(850-int(missesTextWidth/2),50),missesText)
|
||||||
|
|
||||||
|
background.save("resources/games/hangmanBoards/hangmanBoard"+channel+".png")
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import json
|
|
||||||
import random
|
import random
|
||||||
import copy
|
import copy
|
||||||
import math
|
import math
|
||||||
|
|
||||||
from . import hexDraw
|
from .hexDraw import DrawHex
|
||||||
from funcs import logThis, getName, getID
|
from funcs import logThis
|
||||||
|
|
||||||
BOARDWIDTH = 11
|
BOARDWIDTH = 11
|
||||||
ALL_POSITIONS = [(i,j) for i in range(11) for j in range(11)]
|
ALL_POSITIONS = [(i,j) for i in range(11) for j in range(11)]
|
||||||
@ -14,368 +13,364 @@ for position in ALL_POSITIONS:
|
|||||||
EMPTY_DIJKSTRA[position] = math.inf # an impossibly high number
|
EMPTY_DIJKSTRA[position] = math.inf # an impossibly high number
|
||||||
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)]
|
||||||
|
|
||||||
# Parses command
|
class HexGame():
|
||||||
def parseHex(command, channel, user):
|
def __init__(self,bot):
|
||||||
commands = command.lower().split()
|
self.bot = bot
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
self.draw = DrawHex(bot)
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if command == "" or command == " ":
|
|
||||||
return "I didn't get that. Use \"!hex start [opponent]\" to start a game.", False, False, False, False
|
|
||||||
|
|
||||||
elif commands[0] == "start":
|
|
||||||
# Starting a game
|
|
||||||
if len(commands) == 1: # if the commands is "!hex start", the opponent is Gwendolyn at difficulty 2
|
|
||||||
commands.append("2")
|
|
||||||
logThis("Starting a hex game with hexStart(). "+str(user)+" challenged "+commands[1])
|
|
||||||
return hexStart(channel,user,commands[1]) # commands[1] is the opponent
|
|
||||||
|
|
||||||
# If using a command with no game, return error
|
|
||||||
elif channel not in data:
|
|
||||||
return "There's no game in this channel", False, False, False, False
|
|
||||||
|
|
||||||
# Stopping the game
|
# Parses command
|
||||||
elif commands[0] == "stop":
|
def parseHex(self, command, channel, user):
|
||||||
if user in data[channel]["players"]:
|
commands = command.lower().split()
|
||||||
return "Ending game.", False, False, True, False
|
game = self.bot.database["hex games"].find_one({"_id":channel})
|
||||||
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 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 undoHex(channel, user)
|
|
||||||
|
|
||||||
# Surrender
|
|
||||||
elif commands[0] == "surrender":
|
|
||||||
players = data[channel]["players"]
|
|
||||||
if user in players:
|
|
||||||
opponent = (players.index(user) + 1) % 2
|
|
||||||
data[channel]["winner"] = opponent + 1
|
|
||||||
return "{} surrendered. That means {} won! Adding 30 Gwendobucks to their account.".format(getName(user),getName(players[opponent])), False, False, True, False
|
|
||||||
else:
|
|
||||||
return "You can't surrender when you're not a player.", False, False, False, False
|
|
||||||
|
|
||||||
# Swap
|
if command == "" or command == " ":
|
||||||
elif commands[0] == "swap":
|
return "I didn't get that. Use \"!hex start [opponent]\" to start a game.", False, False, False, False
|
||||||
if len(data[channel]["gameHistory"]) == 1: # Only after the first move
|
|
||||||
data[channel]["players"] = data[channel]["players"][::-1] # Swaps their player-number
|
|
||||||
with open("resources/games/hexGames.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
# Swaps the color of the hexes on the board drawing:
|
|
||||||
hexDraw.drawSwap(channel)
|
|
||||||
player2 = data[channel]["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
|
|
||||||
|
|
||||||
else:
|
elif commands[0] == "start":
|
||||||
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
|
# Starting a game
|
||||||
|
if len(commands) == 1: # if the commands is "!hex start", the opponent is Gwendolyn at difficulty 2
|
||||||
|
commands.append("2")
|
||||||
|
logThis("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
|
||||||
|
|
||||||
# Starts the game
|
# Stopping the game
|
||||||
def hexStart(channel, user, opponent):
|
elif commands[0] == "stop":
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
if user in game["players"]:
|
||||||
data = json.load(f)
|
return "Ending game.", False, False, True, False
|
||||||
|
|
||||||
if channel not in data:
|
|
||||||
if opponent in ["1","2","3","4","5"]:
|
|
||||||
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 = getID(opponent)
|
|
||||||
if opponent == None:
|
|
||||||
return "I can't find that user", False, False, False, False
|
|
||||||
else:
|
|
||||||
# Opponent is another player
|
|
||||||
difficulty = 3
|
|
||||||
diffText = ""
|
|
||||||
|
|
||||||
# board is 11x11
|
|
||||||
board = [ [ 0 for i in range(BOARDWIDTH) ] for j in range(BOARDWIDTH) ]
|
|
||||||
players = [user,opponent]
|
|
||||||
random.shuffle(players) # random starting player
|
|
||||||
gameHistory = []
|
|
||||||
|
|
||||||
data[channel] = {"board":board, "winner":0,
|
|
||||||
"players":players, "turn":1, "difficulty":difficulty, "gameHistory":gameHistory}
|
|
||||||
|
|
||||||
with open("resources/games/hexGames.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
# draw the board
|
|
||||||
hexDraw.drawBoard(channel)
|
|
||||||
|
|
||||||
gwendoTurn = True if players[0] == "Gwendolyn" else False
|
|
||||||
showImage = True
|
|
||||||
return "Started Hex game against "+getName(opponent)+ diffText+". It's "+getName(players[0])+"'s turn", showImage, False, False, gwendoTurn
|
|
||||||
else:
|
|
||||||
return "There's already a hex game going on in this channel", False, False, False, False
|
|
||||||
|
|
||||||
# Places a piece at the given location and checks things afterwards
|
|
||||||
def placeHex(channel : str,position : str, user):
|
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if channel in data:
|
|
||||||
players = data[channel]["players"]
|
|
||||||
if user in players:
|
|
||||||
turn = data[channel]["turn"]
|
|
||||||
if players[0] == players[1]:
|
|
||||||
player = turn
|
|
||||||
else:
|
else:
|
||||||
player = players.index(user)+1
|
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.funcs.getName(user),self.bot.funcs.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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
# Starts the game
|
||||||
|
def hexStart(self, channel, user, opponent):
|
||||||
|
game = self.bot.database["hex games"].find_one({"_id":channel})
|
||||||
|
|
||||||
|
if game == None:
|
||||||
|
if opponent in ["1","2","3","4","5"]:
|
||||||
|
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.funcs.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 player == turn:
|
# board is 11x11
|
||||||
board = data[channel]["board"]
|
board = [ [ 0 for i in range(BOARDWIDTH) ] for j in range(BOARDWIDTH) ]
|
||||||
|
players = [user,opponent]
|
||||||
|
random.shuffle(players) # random starting player
|
||||||
|
gameHistory = []
|
||||||
|
|
||||||
logThis("Placing a piece on the board with placeHex()")
|
newGame = {"_id":channel,"board":board, "winner":0,
|
||||||
# Places on board
|
"players":players, "turn":1, "difficulty":difficulty, "gameHistory":gameHistory}
|
||||||
board = placeOnHexBoard(board,player,position)
|
|
||||||
|
|
||||||
if isinstance(board, list):
|
|
||||||
# If the move is valid:
|
|
||||||
data[channel]["board"] = board
|
|
||||||
turn = 1 if turn == 2 else 2
|
|
||||||
data[channel]["turn"] = turn
|
|
||||||
|
|
||||||
|
|
||||||
# Checking for a win
|
self.bot.database["hex games"].insert_one(newGame)
|
||||||
logThis("Checking for win")
|
|
||||||
score, winner = evaluateBoard(data[channel]["board"])
|
|
||||||
|
|
||||||
if winner == 0: # Continue with the game.
|
# draw the board
|
||||||
gameWon = False
|
self.draw.drawBoard(channel)
|
||||||
message = getName(data[channel]["players"][player-1])+" placed at "+position.upper()+". It's now "+getName(data[channel]["players"][turn-1])+"'s turn."# The score is "+str(score)
|
|
||||||
|
|
||||||
else: # Congratulations!
|
|
||||||
gameWon = True
|
|
||||||
data[channel]["winner"] = winner
|
|
||||||
message = getName(data[channel]["players"][player-1])+" placed at "+position.upper()+" and won!"
|
|
||||||
if data[channel]["players"][winner-1] != "Gwendolyn":
|
|
||||||
winAmount = data[channel]["difficulty"]*10
|
|
||||||
message += " Adding "+str(winAmount)+" GwendoBucks to their account."
|
|
||||||
|
|
||||||
data[channel]["gameHistory"].append((int(position[1])-1, ord(position[0])-97))
|
|
||||||
|
|
||||||
# Is it now Gwendolyn's turn?
|
|
||||||
gwendoTurn = False
|
|
||||||
if data[channel]["players"][turn-1] == "Gwendolyn":
|
|
||||||
logThis("It's Gwendolyn's turn")
|
|
||||||
gwendoTurn = True
|
|
||||||
|
|
||||||
# Save the data
|
|
||||||
with open("resources/games/hexGames.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
# Update the board
|
|
||||||
hexDraw.drawHexPlacement(channel,player,position)
|
|
||||||
|
|
||||||
return message, True, True, gameWon, gwendoTurn
|
gwendoTurn = True if players[0] == "Gwendolyn" else False
|
||||||
|
showImage = True
|
||||||
|
return "Started Hex game against "+self.bot.funcs.getName(opponent)+ diffText+". It's "+self.bot.funcs.getName(players[0])+"'s turn", showImage, False, False, gwendoTurn
|
||||||
|
else:
|
||||||
|
return "There's already a hex game going on in this channel", False, False, False, False
|
||||||
|
|
||||||
|
# Places a piece at the given location and checks things afterwards
|
||||||
|
def placeHex(self, channel : str,position : str, user):
|
||||||
|
game = self.bot.database["hex games"].find_one({"_id":channel})
|
||||||
|
|
||||||
|
if game != None:
|
||||||
|
players = game["players"]
|
||||||
|
if user in players:
|
||||||
|
turn = game["turn"]
|
||||||
|
if players[0] == players[1]:
|
||||||
|
player = turn
|
||||||
else:
|
else:
|
||||||
# Invalid move. "board" is the error message
|
player = players.index(user)+1
|
||||||
message = board
|
|
||||||
|
if player == turn:
|
||||||
|
board = game["board"]
|
||||||
|
|
||||||
|
logThis("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
|
||||||
|
logThis("Checking for win")
|
||||||
|
winner = self.evaluateBoard(game["board"])[1]
|
||||||
|
|
||||||
|
if winner == 0: # Continue with the game.
|
||||||
|
gameWon = False
|
||||||
|
message = self.bot.funcs.getName(game["players"][player-1])+" placed at "+position.upper()+". It's now "+self.bot.funcs.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.funcs.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":
|
||||||
|
logThis("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.funcs.getName(game["players"][turn-1])+"'s turn."
|
||||||
return message, False, False, False, False
|
return message, False, False, False, False
|
||||||
else:
|
else:
|
||||||
# Move out of turn
|
message = "You can't place when you're not in the game. The game's players are: "+self.bot.funcs.getName(game["players"][0])+" and "+self.bot.funcs.getName(game["players"][1])+"."
|
||||||
message = "It isn't your turn, it is "+getName(data[channel]["players"][turn-1])+"'s turn."
|
|
||||||
return message, False, False, False, False
|
return message, False, False, False, False
|
||||||
else:
|
else:
|
||||||
message = "You can't place when you're not in the game. The game's players are: "+getName(data[channel]["players"][0])+" and "+getName(data[channel]["players"][1])+"."
|
return "There's no game in this channel", False, False, False, False
|
||||||
return message, False, False, False, False
|
|
||||||
else:
|
|
||||||
return "There's no game in this channel", False, False, False, False
|
|
||||||
|
|
||||||
|
|
||||||
# Returns a board where the placement has occured
|
# Returns a board where the placement has occured
|
||||||
def placeOnHexBoard(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:
|
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):
|
||||||
logThis("Position out of bounds (error code 1533)")
|
logThis("Position out of bounds (error code 1533)")
|
||||||
return "Error. That position is out of bounds."
|
return "Error. That position is out of bounds."
|
||||||
except:
|
except:
|
||||||
logThis("Invalid position (error code 1531)")
|
logThis("Invalid position (error code 1531)")
|
||||||
return "Error. The position should be a letter followed by a number, e.g. \"e2\"."
|
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:
|
||||||
logThis("Cannot place on existing piece (error code 1532)")
|
logThis("Cannot place on existing piece (error code 1532)")
|
||||||
return "Error. You must place on an empty space."
|
return "Error. You must place on an empty space."
|
||||||
|
|
||||||
|
|
||||||
# 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(channel, user):
|
def undoHex(self, channel, user):
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
game = self.bot.database["hex games"].find_one({"_id":channel})
|
||||||
data = json.load(f)
|
|
||||||
if user in data[channel]["players"]:
|
|
||||||
if len(data[channel]["gameHistory"]):
|
|
||||||
turn = data[channel]["turn"]
|
|
||||||
# You can only undo after your turn, which is the opponent's turn.
|
|
||||||
if user == data[channel]["players"][(turn % 2)]: # If it's not your turn
|
|
||||||
logThis("Undoing {}'s last move".format(getName(user)))
|
|
||||||
|
|
||||||
lastMove = data[channel]["gameHistory"].pop()
|
if user in game["players"]:
|
||||||
data[channel]["board"][lastMove[0]][lastMove[1]] = 0
|
if len(game["gameHistory"]):
|
||||||
data[channel]["turn"] = turn%2 + 1
|
turn = game["turn"]
|
||||||
# Save the data
|
# You can only undo after your turn, which is the opponent's turn.
|
||||||
with open("resources/games/hexGames.json", "w") as f:
|
if user == game["players"][(turn % 2)]: # If it's not your turn
|
||||||
json.dump(data,f,indent=4)
|
logThis("Undoing {}'s last move".format(self.bot.funcs.getName(user)))
|
||||||
|
|
||||||
# Update the board
|
lastMove = game["gameHistory"].pop()
|
||||||
hexDraw.drawHexPlacement(channel,0,"abcdefghijk"[lastMove[1]]+str(lastMove[0]+1)) # The zero makes the hex disappear
|
self.bot.database["hex games"].update_one({"_id":channel},
|
||||||
return "You undid your last move at {}".format(lastMove), True, True, False, False
|
{"$set":{"board."+lastMove[0]+"."+lastMove[1]:0}})
|
||||||
|
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:
|
else:
|
||||||
# Sassy
|
# Sassy
|
||||||
return "Nice try. You can't undo your opponent's move. ", False, False, False, False
|
return "Really? You undo right at the start of the game?", False, False, False, False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Sassy
|
return "You're not a player in the game", False, False, False, False
|
||||||
return "Really? You undo right at the start of the game?", False, False, False, False
|
|
||||||
|
|
||||||
else:
|
|
||||||
return "You're not a player in the game", False, False, False, False
|
|
||||||
|
|
||||||
|
|
||||||
# Plays as the AI
|
# Plays as the AI
|
||||||
def hexAI(channel):
|
def hexAI(self, channel):
|
||||||
logThis("Figuring out best move")
|
logThis("Figuring out best move")
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
game = self.bot.database["hex games"].find_one({"_id":channel})
|
||||||
data = json.load(f)
|
board = game["board"]
|
||||||
board = data[channel]["board"]
|
|
||||||
|
|
||||||
if len(data[channel]["gameHistory"]):
|
|
||||||
lastMove = data[channel]["gameHistory"][-1]
|
|
||||||
else:
|
|
||||||
lastMove = (5,5)
|
|
||||||
|
|
||||||
# These moves are the last move +- 2.
|
|
||||||
moves = [[(lastMove[0]+j-2,lastMove[1]+i-2) for i in range(5) if lastMove[1]+i-2 in range(11)] for j in range(5) if lastMove[0]+j-2 in range(11)]
|
|
||||||
moves = sum(moves,[])
|
|
||||||
movesCopy = moves.copy()
|
|
||||||
for move in movesCopy:
|
|
||||||
if board[move[0]][move[1]] != 0:
|
|
||||||
moves.remove(move)
|
|
||||||
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)
|
|
||||||
logThis("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
|
if len(game["gameHistory"]):
|
||||||
indices = [i for i, x in enumerate(judgements) if x == bestScore] # which moves got that score?
|
lastMove = game["gameHistory"][-1]
|
||||||
i = random.choice(indices)
|
|
||||||
chosenMove = (i // BOARDWIDTH , i % BOARDWIDTH)
|
|
||||||
"""
|
|
||||||
placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1)
|
|
||||||
logThis("ChosenMove is {} at {}".format(chosenMove,placement))
|
|
||||||
return placeHex(channel,placement, "Gwendolyn")
|
|
||||||
|
|
||||||
|
|
||||||
def evaluateBoard(board):
|
|
||||||
scores = {1:0, 2:0}
|
|
||||||
winner = 0
|
|
||||||
# Here, I use Dijkstra's algorithm to evaluate the board, as proposed by this article: https://towardsdatascience.com/hex-creating-intelligent-adversaries-part-2-heuristics-dijkstras-algorithm-597e4dcacf93
|
|
||||||
for player in [1,2]:
|
|
||||||
Distance = copy.deepcopy(EMPTY_DIJKSTRA)
|
|
||||||
# Initialize the starting hexes. For the blue player, this is the leftmost column. For the red player, this is the tom row.
|
|
||||||
for start in (ALL_POSITIONS[::11] if player == 2 else ALL_POSITIONS[:11]):
|
|
||||||
# An empty hex adds a of distance of 1. A hex of own color add distance 0. Opposite color adds infinite distance.
|
|
||||||
Distance[start] = 1 if (board[start[0]][start[1]] == 0) else 0 if (board[start[0]][start[1]] == player) else math.inf
|
|
||||||
visited = set() # Also called sptSet, short for "shortest path tree Set"
|
|
||||||
for _ in range(BOARDWIDTH**2): # We can at most check every 121 hexes
|
|
||||||
# Find the next un-visited hex, that has the lowest distance
|
|
||||||
remainingHexes = ALL_SET.difference(visited)
|
|
||||||
A = [Distance[k] for k in remainingHexes] # Find the distance to each un-visited hex
|
|
||||||
u = list(remainingHexes)[A.index(min(A))] # Chooses the one with the lowest distance
|
|
||||||
|
|
||||||
# Find neighbors of the hex u
|
|
||||||
for di in HEX_DIRECTIONS:
|
|
||||||
v = (u[0] + di[0] , u[1] + di[1]) # v is a neighbor of u
|
|
||||||
if v[0] in range(11) and v[1] in range(11) and v not in visited:
|
|
||||||
new_dist = Distance[u] + (1 if (board[v[0]][v[1]] == 0) else 0 if (board[v[0]][v[1]] == player) else math.inf)
|
|
||||||
Distance[v] = min(Distance[v], new_dist)
|
|
||||||
# After a hex has been visited, this is noted
|
|
||||||
visited.add(u)
|
|
||||||
#logThis("Distance from player {}'s start to {} is {}".format(player,u,Distance[u]))
|
|
||||||
if u[player-1] == 10: # if the right coordinate of v is 10, it means we're at the goal
|
|
||||||
scores[player] = Distance[u] # A player's score is the shortest distance to goal. Which equals the number of remaining moves they need to win if unblocked by the opponent.
|
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
logThis("For some reason, no path to the goal was found. ")
|
lastMove = (5,5)
|
||||||
if scores[player] == 0:
|
|
||||||
winner = player
|
|
||||||
break # We don't need to check the other player's score, if player1 won.
|
|
||||||
return scores[2]-scores[1], winner
|
|
||||||
|
|
||||||
|
# These moves are the last move +- 2.
|
||||||
|
moves = [[(lastMove[0]+j-2,lastMove[1]+i-2) for i in range(5) if lastMove[1]+i-2 in range(11)] for j in range(5) if lastMove[0]+j-2 in range(11)]
|
||||||
|
moves = sum(moves,[])
|
||||||
|
movesCopy = moves.copy()
|
||||||
|
for move in movesCopy:
|
||||||
|
if board[move[0]][move[1]] != 0:
|
||||||
|
moves.remove(move)
|
||||||
|
chosenMove = random.choice(moves)
|
||||||
|
|
||||||
def minimaxHex(board, depth, alpha, beta, maximizingPlayer):
|
"""
|
||||||
# The depth is how many moves ahead the computer checks. This value is the difficulty.
|
GwenColor = data[channel]["players"].index("Gwendolyn") + 1 # either 1 or 2 - red or blue
|
||||||
if depth == 0 or 0 not in sum(board,[]):
|
if len(data[channel]["gameHistory"]) == 0:
|
||||||
score = evaluateBoard(board)[0]
|
return placeHex(channel,"F6", "Gwendolyn") # If starting, start in the middle
|
||||||
return score
|
board = data[channel]["board"]
|
||||||
# if final depth is not reached, look another move ahead:
|
difficulty = data[channel]["difficulty"]
|
||||||
if maximizingPlayer: # red player predicts next move
|
|
||||||
maxEval = -math.inf
|
|
||||||
possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0]
|
possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0]
|
||||||
#logThis("Judging a red move at depth {}".format(depth))
|
judgements = [float('nan')]*len(possiblePlaces) # All possible moves are yet to be judged
|
||||||
|
|
||||||
|
current_score = evaluateBoard(board)[0]
|
||||||
for i in possiblePlaces:
|
for i in possiblePlaces:
|
||||||
testBoard = copy.deepcopy(board)
|
testBoard = copy.deepcopy(board)
|
||||||
testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 1 # because maximizingPlayer is Red which is number 1
|
testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = GwenColor
|
||||||
evaluation = minimaxHex(testBoard,depth-1,alpha,beta,False)
|
if evaluateBoard(testBoard)[0] != current_score: # only think about a move if it improves the score (it's impossible to get worse)
|
||||||
maxEval = max(maxEval, evaluation)
|
# Testing a move and evaluating it
|
||||||
alpha = max(alpha, evaluation)
|
judgements[i] = minimaxHex(testBoard,difficulty,-math.inf,math.inf,GwenColor==2)
|
||||||
if beta <= alpha:
|
logThis("Best score for place {} is {}".format((i // BOARDWIDTH,i % BOARDWIDTH),judgements[i]))
|
||||||
#logThis("Just pruned something!")
|
|
||||||
break
|
bestScore = max(judgements) if (GwenColor == 1) else min(judgements) # this line has an error
|
||||||
return maxEval
|
indices = [i for i, x in enumerate(judgements) if x == bestScore] # which moves got that score?
|
||||||
else: # blue player predicts next move
|
i = random.choice(indices)
|
||||||
minEval = math.inf
|
chosenMove = (i // BOARDWIDTH , i % BOARDWIDTH)
|
||||||
possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0]
|
"""
|
||||||
#logThis("Judging a blue move at depth {}".format(depth))
|
placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1)
|
||||||
for i in possiblePlaces:
|
logThis("ChosenMove is {} at {}".format(chosenMove,placement))
|
||||||
testBoard = copy.deepcopy(board)
|
return self.placeHex(channel,placement, "Gwendolyn")
|
||||||
testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 2 # because minimizingPlayer is Blue which is number 2
|
|
||||||
evaluation = minimaxHex(testBoard,depth-1,alpha,beta,True)
|
|
||||||
minEval = min(minEval, evaluation)
|
def evaluateBoard(self, board):
|
||||||
beta = min(beta, evaluation)
|
scores = {1:0, 2:0}
|
||||||
if beta <= alpha:
|
winner = 0
|
||||||
#logThis("Just pruned something!")
|
# Here, I use Dijkstra's algorithm to evaluate the board, as proposed by this article: https://towardsdatascience.com/hex-creating-intelligent-adversaries-part-2-heuristics-dijkstras-algorithm-597e4dcacf93
|
||||||
break
|
for player in [1,2]:
|
||||||
return minEval
|
Distance = copy.deepcopy(EMPTY_DIJKSTRA)
|
||||||
|
# Initialize the starting hexes. For the blue player, this is the leftmost column. For the red player, this is the tom row.
|
||||||
|
for start in (ALL_POSITIONS[::11] if player == 2 else ALL_POSITIONS[:11]):
|
||||||
|
# An empty hex adds a of distance of 1. A hex of own color add distance 0. Opposite color adds infinite distance.
|
||||||
|
Distance[start] = 1 if (board[start[0]][start[1]] == 0) else 0 if (board[start[0]][start[1]] == player) else math.inf
|
||||||
|
visited = set() # Also called sptSet, short for "shortest path tree Set"
|
||||||
|
for _ in range(BOARDWIDTH**2): # We can at most check every 121 hexes
|
||||||
|
# Find the next un-visited hex, that has the lowest distance
|
||||||
|
remainingHexes = ALL_SET.difference(visited)
|
||||||
|
A = [Distance[k] for k in remainingHexes] # Find the distance to each un-visited hex
|
||||||
|
u = list(remainingHexes)[A.index(min(A))] # Chooses the one with the lowest distance
|
||||||
|
|
||||||
|
# Find neighbors of the hex u
|
||||||
|
for di in HEX_DIRECTIONS:
|
||||||
|
v = (u[0] + di[0] , u[1] + di[1]) # v is a neighbor of u
|
||||||
|
if v[0] in range(11) and v[1] in range(11) and v not in visited:
|
||||||
|
new_dist = Distance[u] + (1 if (board[v[0]][v[1]] == 0) else 0 if (board[v[0]][v[1]] == player) else math.inf)
|
||||||
|
Distance[v] = min(Distance[v], new_dist)
|
||||||
|
# After a hex has been visited, this is noted
|
||||||
|
visited.add(u)
|
||||||
|
#logThis("Distance from player {}'s start to {} is {}".format(player,u,Distance[u]))
|
||||||
|
if u[player-1] == 10: # if the right coordinate of v is 10, it means we're at the goal
|
||||||
|
scores[player] = Distance[u] # A player's score is the shortest distance to goal. Which equals the number of remaining moves they need to win if unblocked by the opponent.
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
logThis("For some reason, no path to the goal was found. ")
|
||||||
|
if scores[player] == 0:
|
||||||
|
winner = player
|
||||||
|
break # We don't need to check the other player's score, if player1 won.
|
||||||
|
return scores[2]-scores[1], winner
|
||||||
|
|
||||||
|
|
||||||
|
def minimaxHex(self, board, depth, alpha, beta, maximizingPlayer):
|
||||||
|
# The depth is how many moves ahead the computer checks. This value is the difficulty.
|
||||||
|
if depth == 0 or 0 not in sum(board,[]):
|
||||||
|
score = self.evaluateBoard(board)[0]
|
||||||
|
return score
|
||||||
|
# if final depth is not reached, look another move ahead:
|
||||||
|
if maximizingPlayer: # red player predicts next move
|
||||||
|
maxEval = -math.inf
|
||||||
|
possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0]
|
||||||
|
#logThis("Judging a red move at depth {}".format(depth))
|
||||||
|
for i in possiblePlaces:
|
||||||
|
testBoard = copy.deepcopy(board)
|
||||||
|
testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 1 # because maximizingPlayer is Red which is number 1
|
||||||
|
evaluation = self.minimaxHex(testBoard,depth-1,alpha,beta,False)
|
||||||
|
maxEval = max(maxEval, evaluation)
|
||||||
|
alpha = max(alpha, evaluation)
|
||||||
|
if beta <= alpha:
|
||||||
|
#logThis("Just pruned something!")
|
||||||
|
break
|
||||||
|
return maxEval
|
||||||
|
else: # blue player predicts next move
|
||||||
|
minEval = math.inf
|
||||||
|
possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0]
|
||||||
|
#logThis("Judging a blue move at depth {}".format(depth))
|
||||||
|
for i in possiblePlaces:
|
||||||
|
testBoard = copy.deepcopy(board)
|
||||||
|
testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 2 # because minimizingPlayer is Blue which is number 2
|
||||||
|
evaluation = self.minimaxHex(testBoard,depth-1,alpha,beta,True)
|
||||||
|
minEval = min(minEval, evaluation)
|
||||||
|
beta = min(beta, evaluation)
|
||||||
|
if beta <= alpha:
|
||||||
|
#logThis("Just pruned something!")
|
||||||
|
break
|
||||||
|
return minEval
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import json
|
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
from funcs import logThis, getName
|
from funcs import logThis
|
||||||
|
|
||||||
# Defining all the variables
|
# Defining all the variables
|
||||||
CANVAS_WIDTH = 2400
|
CANVAS_WIDTH = 2400
|
||||||
@ -38,152 +37,151 @@ NAMEHEXPADDING = 90
|
|||||||
SMOL_WIDTH = HEXAGONWIDTH * 0.6
|
SMOL_WIDTH = HEXAGONWIDTH * 0.6
|
||||||
SMOL_SIDELENGTH = SIDELENGTH * 0.6
|
SMOL_SIDELENGTH = SIDELENGTH * 0.6
|
||||||
|
|
||||||
def drawBoard(channel):
|
class DrawHex():
|
||||||
logThis("Drawing empty Hex board")
|
def __init__(self,bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
# Creates the empty image
|
def drawBoard(self, channel):
|
||||||
im = Image.new('RGB', size=(CANVAS_WIDTH, CANVAS_HEIGHT),color = BACKGROUND_COLOR)
|
logThis("Drawing empty Hex board")
|
||||||
# 'd' is a shortcut to drawing on the image
|
|
||||||
d = ImageDraw.Draw(im,"RGBA")
|
|
||||||
|
|
||||||
# Drawing all the hexagons
|
# Creates the empty image
|
||||||
for column in BOARDCOORDINATES:
|
im = Image.new('RGB', size=(CANVAS_WIDTH, CANVAS_HEIGHT),color = BACKGROUND_COLOR)
|
||||||
for startingPoint in column:
|
# 'd' is a shortcut to drawing on the image
|
||||||
x = startingPoint[0]
|
d = ImageDraw.Draw(im,"RGBA")
|
||||||
y = startingPoint[1]
|
|
||||||
d.polygon([
|
|
||||||
(x, y),
|
|
||||||
(x+HEXAGONWIDTH/2, y-0.5*SIDELENGTH),
|
|
||||||
(x+HEXAGONWIDTH, y),
|
|
||||||
(x+HEXAGONWIDTH, y+SIDELENGTH),
|
|
||||||
(x+HEXAGONWIDTH/2, y+1.5*SIDELENGTH),
|
|
||||||
(x, y+SIDELENGTH),
|
|
||||||
],fill = BETWEEN_COLOR)
|
|
||||||
d.polygon([
|
|
||||||
(x+X_THICKNESS, y + Y_THICKNESS),
|
|
||||||
(x+HEXAGONWIDTH/2, y-0.5*SIDELENGTH + HEXTHICKNESS),
|
|
||||||
(x+HEXAGONWIDTH-X_THICKNESS, y + Y_THICKNESS),
|
|
||||||
(x+HEXAGONWIDTH-X_THICKNESS, y+SIDELENGTH - Y_THICKNESS),
|
|
||||||
(x+HEXAGONWIDTH/2, y+1.5*SIDELENGTH - HEXTHICKNESS),
|
|
||||||
(x+X_THICKNESS, y+SIDELENGTH - Y_THICKNESS),
|
|
||||||
],fill = BLANK_COLOR)
|
|
||||||
|
|
||||||
# Draw color on the outside of the board
|
# Drawing all the hexagons
|
||||||
# Top line, red
|
for column in BOARDCOORDINATES:
|
||||||
d.line(sum((sum([(point[0],point[1],point[0]+HEXAGONWIDTH/2,point[1]-HEXAGONHEIGHT+SIDELENGTH) for point in BOARDCOORDINATES[0]],()),(BOARDCOORDINATES[0][10][0]+HEXAGONWIDTH*3/4,BOARDCOORDINATES[0][10][1]-SIDELENGTH/4)),()),
|
for startingPoint in column:
|
||||||
fill = PIECECOLOR[1],width = LINETHICKNESS)
|
x = startingPoint[0]
|
||||||
# Bottom line, red
|
y = startingPoint[1]
|
||||||
d.line(sum(((BOARDCOORDINATES[10][0][0]+HEXAGONWIDTH/4,BOARDCOORDINATES[10][0][1]+SIDELENGTH*5/4),sum([(point[0]+HEXAGONWIDTH/2,point[1]+HEXAGONHEIGHT,point[0]+HEXAGONWIDTH,point[1]+SIDELENGTH) for point in BOARDCOORDINATES[10]],())),()),
|
|
||||||
fill = PIECECOLOR[1],width = LINETHICKNESS)
|
|
||||||
# Left line, blue
|
|
||||||
d.line(sum((sum([(row[0][0],row[0][1],row[0][0],row[0][1]+SIDELENGTH) for row in BOARDCOORDINATES],()),(BOARDCOORDINATES[10][0][0]+HEXAGONWIDTH/4,BOARDCOORDINATES[10][0][1]+SIDELENGTH*5/4)),()),
|
|
||||||
fill = PIECECOLOR[2],width = LINETHICKNESS)
|
|
||||||
# Right line, blue
|
|
||||||
d.line(sum(((BOARDCOORDINATES[0][10][0]+HEXAGONWIDTH*3/4,BOARDCOORDINATES[0][10][1]-SIDELENGTH/4),sum([(row[10][0]+HEXAGONWIDTH,row[10][1],row[10][0]+HEXAGONWIDTH,row[10][1]+SIDELENGTH) for row in BOARDCOORDINATES],())),()),
|
|
||||||
fill = PIECECOLOR[2],width = LINETHICKNESS)
|
|
||||||
|
|
||||||
# Writes "abc..", "123.." on the columns and rows
|
|
||||||
for i in range(11):
|
|
||||||
# Top letters
|
|
||||||
d.text( (X_OFFSET + HEXAGONWIDTH*i, Y_OFFSET-66) , "ABCDEFGHIJK"[i], font=fnt, fill=TEXTCOLOR)
|
|
||||||
# Bottom letters
|
|
||||||
d.text( (X_OFFSET + HEXAGONWIDTH*(i+11.5/2), Y_OFFSET - 15 + 11*HEXAGONHEIGHT) , "ABCDEFGHIJK"[i], font=fnt, fill=TEXTCOLOR)
|
|
||||||
# Left numbers
|
|
||||||
d.multiline_text( (X_OFFSET + HEXAGONWIDTH*i/2 - 72 -4*(i>8), Y_OFFSET + 18 + i*HEXAGONHEIGHT) , str(i+1), font=fnt, fill=TEXTCOLOR, align="right")
|
|
||||||
# Right numbers
|
|
||||||
d.text( (X_OFFSET + HEXAGONWIDTH*(i/2+11) + 30 , Y_OFFSET + 6 + i*HEXAGONHEIGHT) , str(i+1), font=fnt, fill=TEXTCOLOR)
|
|
||||||
|
|
||||||
# Write player names and color
|
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
for p in [1,2]:
|
|
||||||
playername = getName(data[channel]["players"][p-1])
|
|
||||||
# Draw name
|
|
||||||
x = X_NAME[p]
|
|
||||||
x -= NAME_fnt.getsize(playername)[0] if p==2 else 0 # player2's name is right-aligned
|
|
||||||
y = Y_NAME[p]
|
|
||||||
d.text((x,y),playername, font=NAME_fnt, fill = TEXTCOLOR)
|
|
||||||
# Draw a half-size Hexagon to indicate the player's color
|
|
||||||
x -= NAMEHEXPADDING # To the left of both names
|
|
||||||
d.polygon([
|
|
||||||
(x, y),
|
|
||||||
(x+SMOL_WIDTH/2, y-SMOL_SIDELENGTH/2),
|
|
||||||
(x+SMOL_WIDTH, y),
|
|
||||||
(x+SMOL_WIDTH, y+SMOL_SIDELENGTH),
|
|
||||||
(x+SMOL_WIDTH/2, y+SMOL_SIDELENGTH*3/2),
|
|
||||||
(x, y+SMOL_SIDELENGTH),
|
|
||||||
],fill = PIECECOLOR[p])
|
|
||||||
|
|
||||||
im.save("resources/games/hexBoards/board"+channel+".png")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def drawHexPlacement(channel,player,position):
|
|
||||||
FILEPATH = "resources/games/hexBoards/board"+channel+".png"
|
|
||||||
logThis("Drawing a newly placed hex. Filepath: "+FILEPATH)
|
|
||||||
|
|
||||||
# Translates position
|
|
||||||
# We don't need to error-check, because the position is already checked in placeOnHexBoard()
|
|
||||||
position = position.lower()
|
|
||||||
column = ord(position[0])-97 # ord() translates from letter to number
|
|
||||||
row = int(position[1:])-1
|
|
||||||
|
|
||||||
# Find the coordinates for the filled hex drawing
|
|
||||||
hexCoords = [
|
|
||||||
(BOARDCOORDINATES[row][column][0]+COLX_THICKNESS, BOARDCOORDINATES[row][column][1] + COLY_THICKNESS),
|
|
||||||
(BOARDCOORDINATES[row][column][0]+HEXAGONWIDTH/2, BOARDCOORDINATES[row][column][1]-0.5*SIDELENGTH + COLHEXTHICKNESS),
|
|
||||||
(BOARDCOORDINATES[row][column][0]+HEXAGONWIDTH-COLX_THICKNESS, BOARDCOORDINATES[row][column][1] + COLY_THICKNESS),
|
|
||||||
(BOARDCOORDINATES[row][column][0]+HEXAGONWIDTH-COLX_THICKNESS, BOARDCOORDINATES[row][column][1]+SIDELENGTH - COLY_THICKNESS),
|
|
||||||
(BOARDCOORDINATES[row][column][0]+HEXAGONWIDTH/2, BOARDCOORDINATES[row][column][1]+1.5*SIDELENGTH - COLHEXTHICKNESS),
|
|
||||||
(BOARDCOORDINATES[row][column][0]+COLX_THICKNESS, BOARDCOORDINATES[row][column][1]+SIDELENGTH - COLY_THICKNESS),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Opens the image
|
|
||||||
try:
|
|
||||||
with Image.open(FILEPATH) as im:
|
|
||||||
d = ImageDraw.Draw(im,"RGBA")
|
|
||||||
# Draws the hex piece
|
|
||||||
d.polygon(hexCoords,fill = PIECECOLOR[player], outline = BETWEEN_COLOR)
|
|
||||||
|
|
||||||
# Save
|
|
||||||
im.save(FILEPATH)
|
|
||||||
except:
|
|
||||||
logThis("Error drawing new hex on board (error code 1541")
|
|
||||||
|
|
||||||
def drawSwap(channel):
|
|
||||||
FILEPATH = "resources/games/hexBoards/board"+channel+".png"
|
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
# Opens the image
|
|
||||||
try:
|
|
||||||
with Image.open(FILEPATH) as im:
|
|
||||||
d = ImageDraw.Draw(im,"RGBA")
|
|
||||||
|
|
||||||
# Write player names and color
|
|
||||||
for p in [1,2]:
|
|
||||||
playername = getName(data[channel]["players"][p%2])
|
|
||||||
|
|
||||||
x = X_NAME[p]
|
|
||||||
x -= NAME_fnt.getsize(playername)[0] if p==2 else 0 # player2's name is right-aligned
|
|
||||||
y = Y_NAME[p]
|
|
||||||
|
|
||||||
# Draw a half-size Hexagon to indicate the player's color
|
|
||||||
x -= NAMEHEXPADDING # To the left of both names
|
|
||||||
d.polygon([
|
d.polygon([
|
||||||
(x, y),
|
(x, y),
|
||||||
(x+SMOL_WIDTH/2, y-SMOL_SIDELENGTH/2),
|
(x+HEXAGONWIDTH/2, y-0.5*SIDELENGTH),
|
||||||
(x+SMOL_WIDTH, y),
|
(x+HEXAGONWIDTH, y),
|
||||||
(x+SMOL_WIDTH, y+SMOL_SIDELENGTH),
|
(x+HEXAGONWIDTH, y+SIDELENGTH),
|
||||||
(x+SMOL_WIDTH/2, y+SMOL_SIDELENGTH*3/2),
|
(x+HEXAGONWIDTH/2, y+1.5*SIDELENGTH),
|
||||||
(x, y+SMOL_SIDELENGTH),
|
(x, y+SIDELENGTH),
|
||||||
],fill = PIECECOLOR[p % 2 + 1])
|
],fill = BETWEEN_COLOR)
|
||||||
|
d.polygon([
|
||||||
# Save
|
(x+X_THICKNESS, y + Y_THICKNESS),
|
||||||
im.save(FILEPATH)
|
(x+HEXAGONWIDTH/2, y-0.5*SIDELENGTH + HEXTHICKNESS),
|
||||||
except:
|
(x+HEXAGONWIDTH-X_THICKNESS, y + Y_THICKNESS),
|
||||||
logThis("Error drawing swap (error code 1542)")
|
(x+HEXAGONWIDTH-X_THICKNESS, y+SIDELENGTH - Y_THICKNESS),
|
||||||
|
(x+HEXAGONWIDTH/2, y+1.5*SIDELENGTH - HEXTHICKNESS),
|
||||||
|
(x+X_THICKNESS, y+SIDELENGTH - Y_THICKNESS),
|
||||||
|
],fill = BLANK_COLOR)
|
||||||
|
|
||||||
|
# Draw color on the outside of the board
|
||||||
|
# Top line, red
|
||||||
|
d.line(sum((sum([(point[0],point[1],point[0]+HEXAGONWIDTH/2,point[1]-HEXAGONHEIGHT+SIDELENGTH) for point in BOARDCOORDINATES[0]],()),(BOARDCOORDINATES[0][10][0]+HEXAGONWIDTH*3/4,BOARDCOORDINATES[0][10][1]-SIDELENGTH/4)),()),
|
||||||
|
fill = PIECECOLOR[1],width = LINETHICKNESS)
|
||||||
|
# Bottom line, red
|
||||||
|
d.line(sum(((BOARDCOORDINATES[10][0][0]+HEXAGONWIDTH/4,BOARDCOORDINATES[10][0][1]+SIDELENGTH*5/4),sum([(point[0]+HEXAGONWIDTH/2,point[1]+HEXAGONHEIGHT,point[0]+HEXAGONWIDTH,point[1]+SIDELENGTH) for point in BOARDCOORDINATES[10]],())),()),
|
||||||
|
fill = PIECECOLOR[1],width = LINETHICKNESS)
|
||||||
|
# Left line, blue
|
||||||
|
d.line(sum((sum([(row[0][0],row[0][1],row[0][0],row[0][1]+SIDELENGTH) for row in BOARDCOORDINATES],()),(BOARDCOORDINATES[10][0][0]+HEXAGONWIDTH/4,BOARDCOORDINATES[10][0][1]+SIDELENGTH*5/4)),()),
|
||||||
|
fill = PIECECOLOR[2],width = LINETHICKNESS)
|
||||||
|
# Right line, blue
|
||||||
|
d.line(sum(((BOARDCOORDINATES[0][10][0]+HEXAGONWIDTH*3/4,BOARDCOORDINATES[0][10][1]-SIDELENGTH/4),sum([(row[10][0]+HEXAGONWIDTH,row[10][1],row[10][0]+HEXAGONWIDTH,row[10][1]+SIDELENGTH) for row in BOARDCOORDINATES],())),()),
|
||||||
|
fill = PIECECOLOR[2],width = LINETHICKNESS)
|
||||||
|
|
||||||
|
# Writes "abc..", "123.." on the columns and rows
|
||||||
|
for i in range(11):
|
||||||
|
# Top letters
|
||||||
|
d.text( (X_OFFSET + HEXAGONWIDTH*i, Y_OFFSET-66) , "ABCDEFGHIJK"[i], font=fnt, fill=TEXTCOLOR)
|
||||||
|
# Bottom letters
|
||||||
|
d.text( (X_OFFSET + HEXAGONWIDTH*(i+11.5/2), Y_OFFSET - 15 + 11*HEXAGONHEIGHT) , "ABCDEFGHIJK"[i], font=fnt, fill=TEXTCOLOR)
|
||||||
|
# Left numbers
|
||||||
|
d.multiline_text( (X_OFFSET + HEXAGONWIDTH*i/2 - 72 -4*(i>8), Y_OFFSET + 18 + i*HEXAGONHEIGHT) , str(i+1), font=fnt, fill=TEXTCOLOR, align="right")
|
||||||
|
# Right numbers
|
||||||
|
d.text( (X_OFFSET + HEXAGONWIDTH*(i/2+11) + 30 , Y_OFFSET + 6 + i*HEXAGONHEIGHT) , str(i+1), font=fnt, fill=TEXTCOLOR)
|
||||||
|
|
||||||
|
# Write player names and color
|
||||||
|
game = self.bot.database["hex games"].find_one({"_id":channel})
|
||||||
|
|
||||||
|
for p in [1,2]:
|
||||||
|
playername = self.bot.funcs.getName(game["players"][p-1])
|
||||||
|
# Draw name
|
||||||
|
x = X_NAME[p]
|
||||||
|
x -= NAME_fnt.getsize(playername)[0] if p==2 else 0 # player2's name is right-aligned
|
||||||
|
y = Y_NAME[p]
|
||||||
|
d.text((x,y),playername, font=NAME_fnt, fill = TEXTCOLOR)
|
||||||
|
# Draw a half-size Hexagon to indicate the player's color
|
||||||
|
x -= NAMEHEXPADDING # To the left of both names
|
||||||
|
d.polygon([
|
||||||
|
(x, y),
|
||||||
|
(x+SMOL_WIDTH/2, y-SMOL_SIDELENGTH/2),
|
||||||
|
(x+SMOL_WIDTH, y),
|
||||||
|
(x+SMOL_WIDTH, y+SMOL_SIDELENGTH),
|
||||||
|
(x+SMOL_WIDTH/2, y+SMOL_SIDELENGTH*3/2),
|
||||||
|
(x, y+SMOL_SIDELENGTH),
|
||||||
|
],fill = PIECECOLOR[p])
|
||||||
|
|
||||||
|
im.save("resources/games/hexBoards/board"+channel+".png")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def drawHexPlacement(self, channel,player,position):
|
||||||
|
FILEPATH = "resources/games/hexBoards/board"+channel+".png"
|
||||||
|
logThis("Drawing a newly placed hex. Filepath: "+FILEPATH)
|
||||||
|
|
||||||
|
# Translates position
|
||||||
|
# We don't need to error-check, because the position is already checked in placeOnHexBoard()
|
||||||
|
position = position.lower()
|
||||||
|
column = ord(position[0])-97 # ord() translates from letter to number
|
||||||
|
row = int(position[1:])-1
|
||||||
|
|
||||||
|
# Find the coordinates for the filled hex drawing
|
||||||
|
hexCoords = [
|
||||||
|
(BOARDCOORDINATES[row][column][0]+COLX_THICKNESS, BOARDCOORDINATES[row][column][1] + COLY_THICKNESS),
|
||||||
|
(BOARDCOORDINATES[row][column][0]+HEXAGONWIDTH/2, BOARDCOORDINATES[row][column][1]-0.5*SIDELENGTH + COLHEXTHICKNESS),
|
||||||
|
(BOARDCOORDINATES[row][column][0]+HEXAGONWIDTH-COLX_THICKNESS, BOARDCOORDINATES[row][column][1] + COLY_THICKNESS),
|
||||||
|
(BOARDCOORDINATES[row][column][0]+HEXAGONWIDTH-COLX_THICKNESS, BOARDCOORDINATES[row][column][1]+SIDELENGTH - COLY_THICKNESS),
|
||||||
|
(BOARDCOORDINATES[row][column][0]+HEXAGONWIDTH/2, BOARDCOORDINATES[row][column][1]+1.5*SIDELENGTH - COLHEXTHICKNESS),
|
||||||
|
(BOARDCOORDINATES[row][column][0]+COLX_THICKNESS, BOARDCOORDINATES[row][column][1]+SIDELENGTH - COLY_THICKNESS),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Opens the image
|
||||||
|
try:
|
||||||
|
with Image.open(FILEPATH) as im:
|
||||||
|
d = ImageDraw.Draw(im,"RGBA")
|
||||||
|
# Draws the hex piece
|
||||||
|
d.polygon(hexCoords,fill = PIECECOLOR[player], outline = BETWEEN_COLOR)
|
||||||
|
|
||||||
|
# Save
|
||||||
|
im.save(FILEPATH)
|
||||||
|
except:
|
||||||
|
logThis("Error drawing new hex on board (error code 1541")
|
||||||
|
|
||||||
|
def drawSwap(self, channel):
|
||||||
|
FILEPATH = "resources/games/hexBoards/board"+channel+".png"
|
||||||
|
game = self.bot.database["hex games"].find_one({"_id":channel})
|
||||||
|
# Opens the image
|
||||||
|
try:
|
||||||
|
with Image.open(FILEPATH) as im:
|
||||||
|
d = ImageDraw.Draw(im,"RGBA")
|
||||||
|
|
||||||
|
# Write player names and color
|
||||||
|
for p in [1,2]:
|
||||||
|
playername = getName(game["players"][p%2])
|
||||||
|
|
||||||
|
x = X_NAME[p]
|
||||||
|
x -= NAME_fnt.getsize(playername)[0] if p==2 else 0 # player2's name is right-aligned
|
||||||
|
y = Y_NAME[p]
|
||||||
|
|
||||||
|
# Draw a half-size Hexagon to indicate the player's color
|
||||||
|
x -= NAMEHEXPADDING # To the left of both names
|
||||||
|
d.polygon([
|
||||||
|
(x, y),
|
||||||
|
(x+SMOL_WIDTH/2, y-SMOL_SIDELENGTH/2),
|
||||||
|
(x+SMOL_WIDTH, y),
|
||||||
|
(x+SMOL_WIDTH, y+SMOL_SIDELENGTH),
|
||||||
|
(x+SMOL_WIDTH/2, y+SMOL_SIDELENGTH*3/2),
|
||||||
|
(x, y+SMOL_SIDELENGTH),
|
||||||
|
],fill = PIECECOLOR[p % 2 + 1])
|
||||||
|
|
||||||
|
# Save
|
||||||
|
im.save(FILEPATH)
|
||||||
|
except:
|
||||||
|
logThis("Error drawing swap (error code 1542)")
|
||||||
|
@ -1,131 +1,137 @@
|
|||||||
import json
|
class Invest():
|
||||||
|
def __init__(self,bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
from funcs import getName
|
def getPrice(self, symbol : str):
|
||||||
from .money import checkBalance, addMoney
|
res = self.bot.finnhubClient.quote(symbol.upper())
|
||||||
|
if res == {}:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
return int(res["c"] * 100)
|
||||||
|
|
||||||
def getPrice(symbol : str,finnhubClient):
|
def getPortfolio(self, user : str):
|
||||||
res = finnhubClient.quote(symbol.upper())
|
userInvestments = self.bot.database["investments"].find_one({"_id":user})
|
||||||
if res == {}:
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
return int(res["c"] * 100)
|
|
||||||
|
|
||||||
def getPortfolio(user : str,finnhubClient):
|
if userInvestments in [None,{}]:
|
||||||
with open("resources/games/investments.json") as f:
|
return f"{self.bot.funcs.getName(user)} does not have a stock portfolio."
|
||||||
data = json.load(f)
|
else:
|
||||||
|
portfolio = f"**Stock portfolio for {self.bot.funcs.getName(user)}**"
|
||||||
|
|
||||||
if user not in data or data[user] == {}:
|
for key, value in list(userInvestments["investments"].items()):
|
||||||
return f"{getName(user)} does not have a stock portfolio."
|
purchaseValue = value["purchased for"]
|
||||||
else:
|
currentValue = int((self.getPrice(key) / value["value at purchase"]) * value["purchased"])
|
||||||
portfolio = f"**Stock portfolio for {getName(user)}**"
|
if purchaseValue == "?":
|
||||||
|
portfolio += f"\n**{key}**: ___{str(currentValue)} GwendoBucks___"
|
||||||
|
else:
|
||||||
|
portfolio += f"\n**{key}**: ___{str(currentValue)} GwendoBucks___ (purchased for {str(purchaseValue)})"
|
||||||
|
|
||||||
for key, value in list(data[user].items()):
|
return portfolio
|
||||||
purchaseValue = value["purchased for"]
|
|
||||||
currentValue = int((getPrice(key,finnhubClient) / value["value at purchase"]) * value["purchased"])
|
|
||||||
if purchaseValue == "?":
|
|
||||||
portfolio += f"\n**{key}**: ___{str(currentValue)} GwendoBucks___"
|
|
||||||
else:
|
|
||||||
portfolio += f"\n**{key}**: ___{str(currentValue)} GwendoBucks___ (purchased for {str(purchaseValue)})"
|
|
||||||
|
|
||||||
return portfolio
|
def buyStock(self, user : str, stock : str, buyAmount : int):
|
||||||
|
if buyAmount >= 100:
|
||||||
|
if self.bot.money.checkBalance(user) >= buyAmount:
|
||||||
|
stockPrice = self.getPrice(stock)
|
||||||
|
if stockPrice > 0:
|
||||||
|
userInvestments = self.bot.database["investments"].find_one({"_id":user})
|
||||||
|
|
||||||
def buyStock(user : str, stock : str, buyAmount : int,finnhubClient):
|
self.bot.money.addMoney(user,-1*buyAmount)
|
||||||
if buyAmount >= 100:
|
stock = stock.upper()
|
||||||
if checkBalance(user) >= buyAmount:
|
|
||||||
stockPrice = getPrice(stock,finnhubClient)
|
|
||||||
if stockPrice > 0:
|
|
||||||
with open("resources/games/investments.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
addMoney(user,-1*buyAmount)
|
if userInvestments != None:
|
||||||
stock = stock.upper()
|
userInvestments = userInvestments["investments"]
|
||||||
|
if stock in userInvestments:
|
||||||
|
value = userInvestments[stock]
|
||||||
|
newAmount = int((stockPrice / value["value at purchase"]) * value["purchased"]) + buyAmount
|
||||||
|
|
||||||
if user in data:
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
if stock in data[user]:
|
{"$set":{"investments."+stock+".value at purchase" : stockPrice}})
|
||||||
value = data[user][stock]
|
|
||||||
newAmount = int((stockPrice / value["value at purchase"]) * value["purchased"]) + buyAmount
|
|
||||||
|
|
||||||
data[user][stock]["value at purchase"] = stockPrice
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
data[user][stock]["purchased"] = newAmount
|
{"$set":{"investments."+stock+".purchased" : newAmount}})
|
||||||
if value["purchased for"] != "?":
|
|
||||||
data[user][stock]["purchased for"] += buyAmount
|
if value["purchased for"] != "?":
|
||||||
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
|
{"$set":{"investments."+stock+".purchased for" : buyAmount}})
|
||||||
|
else:
|
||||||
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
|
{"$set":{"investments."+stock : {"purchased" : buyAmount, "value at purchase" : stockPrice,
|
||||||
|
"purchased for" : buyAmount}}})
|
||||||
else:
|
else:
|
||||||
data[user][stock] = {"purchased" : buyAmount, "value at purchase" : stockPrice, "purchased for" : buyAmount}
|
newUser = {"_id":user,"investments":{stock : {"purchased" : buyAmount, "value at purchase" : stockPrice, "purchased for" : buyAmount}}}
|
||||||
|
self.bot.database["investments"].insert_one(newUser)
|
||||||
|
|
||||||
|
return f"{self.bot.funcs.getName(user)} bought {buyAmount} GwendoBucks worth of {stock} stock"
|
||||||
else:
|
else:
|
||||||
data[user] = {stock : {"purchased" : buyAmount, "value at purchase" : stockPrice, "purchased for" : buyAmount}}
|
return f"{stock} is not traded on the american market."
|
||||||
|
|
||||||
with open("resources/games/investments.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
return f"{getName(user)} bought {buyAmount} GwendoBucks worth of {stock} stock"
|
|
||||||
else:
|
else:
|
||||||
return f"{stock} is not traded on the american market."
|
return "You don't have enough money for that"
|
||||||
else:
|
else:
|
||||||
return "You don't have enough money for that"
|
return "You cannot buy stocks for less than 100 GwendoBucks"
|
||||||
else:
|
|
||||||
return "You cannot buy stocks for less than 100 GwendoBucks"
|
|
||||||
|
|
||||||
def sellStock(user : str, stock : str, sellAmount : int,finnhubClient):
|
def sellStock(self, user : str, stock : str, sellAmount : int):
|
||||||
if sellAmount > 0:
|
if sellAmount > 0:
|
||||||
with open("resources/games/investments.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
stock = stock.upper()
|
userInvestments = self.bot.database["investments"].find_one({"_id":user})["investments"]
|
||||||
|
|
||||||
if user in data and stock in data[user]:
|
stock = stock.upper()
|
||||||
value = data[user][stock]
|
|
||||||
stockPrice = getPrice(stock,finnhubClient)
|
|
||||||
data[user][stock]["purchased"] = int((stockPrice / value["value at purchase"]) * value["purchased"])
|
|
||||||
data[user][stock]["value at purchase"] = stockPrice
|
|
||||||
if value["purchased"] >= sellAmount:
|
|
||||||
|
|
||||||
addMoney(user,sellAmount)
|
if userInvestments != None and stock in userInvestments:
|
||||||
if sellAmount < value["purchased"]:
|
value = userInvestments[stock]
|
||||||
data[user][stock]["purchased"] -= sellAmount
|
stockPrice = self.getPrice(stock)
|
||||||
data[user][stock]["purchased for"] = "?"
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
|
{"$set":{"investments."+stock+".purchased" :
|
||||||
|
int((stockPrice / value["value at purchase"]) * value["purchased"])}})
|
||||||
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
|
{"$set":{"investments."+stock+".value at purchase" : stockPrice}})
|
||||||
|
if value["purchased"] >= sellAmount:
|
||||||
|
self.bot.money.addMoney(user,sellAmount)
|
||||||
|
if sellAmount < value["purchased"]:
|
||||||
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
|
{"$inc":{"investments."+stock+".purchased" : -sellAmount}})
|
||||||
|
|
||||||
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
|
{"$set":{"investments."+stock+".purchased for" : "?"}})
|
||||||
|
else:
|
||||||
|
self.bot.database["investments"].update_one({"_id":user},
|
||||||
|
{"$unset":{"investments."+stock:""}})
|
||||||
|
|
||||||
|
return f"{self.bot.funcs.getName(user)} sold {sellAmount} GwendoBucks worth of {stock} stock"
|
||||||
else:
|
else:
|
||||||
del data[user][stock]
|
return f"You don't have enough {stock} stocks to do that"
|
||||||
|
|
||||||
with open("resources/games/investments.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
return f"{getName(user)} sold {sellAmount} GwendoBucks worth of {stock} stock"
|
|
||||||
else:
|
else:
|
||||||
return f"You don't have enough {stock} stocks to do that"
|
return f"You don't have any {stock} stock"
|
||||||
else:
|
else:
|
||||||
return f"You don't have any {stock} stock"
|
return "no"
|
||||||
else:
|
|
||||||
return "no"
|
|
||||||
|
|
||||||
def parseInvest(content: str, user : str,finnhubClient):
|
def parseInvest(self, content: str, user : str):
|
||||||
if content.startswith("check"):
|
if content.startswith("check"):
|
||||||
commands = content.split(" ")
|
commands = content.split(" ")
|
||||||
if len(commands) == 1:
|
if len(commands) == 1:
|
||||||
return getPortfolio(user,finnhubClient)
|
return self.getPortfolio(user)
|
||||||
else:
|
|
||||||
price = getPrice(commands[1],finnhubClient)
|
|
||||||
if price == 0:
|
|
||||||
return f"{commands[1].upper()} is not traded on the american market."
|
|
||||||
else:
|
else:
|
||||||
price = f"{price:,}".replace(",",".")
|
price = self.getPrice(commands[1])
|
||||||
return f"The current {commands[1].upper()} stock is valued at **{price}** GwendoBucks"
|
if price == 0:
|
||||||
|
return f"{commands[1].upper()} is not traded on the american market."
|
||||||
|
else:
|
||||||
|
price = f"{price:,}".replace(",",".")
|
||||||
|
return f"The current {commands[1].upper()} stock is valued at **{price}** GwendoBucks"
|
||||||
|
|
||||||
elif content.startswith("buy"):
|
elif content.startswith("buy"):
|
||||||
commands = content.split(" ")
|
commands = content.split(" ")
|
||||||
if len(commands) == 3:
|
if len(commands) == 3:
|
||||||
try:
|
#try:
|
||||||
return buyStock(user,commands[1],int(commands[2]),finnhubClient)
|
return self.buyStock(user,commands[1],int(commands[2]))
|
||||||
except:
|
#except:
|
||||||
return "The command must be given as \"!invest buy [stock] [amount of GwendoBucks to purchase with]\""
|
# 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."
|
return "You must give both a stock name and an amount of gwendobucks you wish to spend."
|
||||||
|
|
||||||
elif content.startswith("sell"):
|
elif content.startswith("sell"):
|
||||||
commands = content.split(" ")
|
commands = content.split(" ")
|
||||||
if len(commands) == 3:
|
if len(commands) == 3:
|
||||||
try:
|
try:
|
||||||
return sellStock(user,commands[1],int(commands[2]),finnhubClient)
|
return 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]\""
|
return "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."
|
return "You must give both a stock name and an amount of GwendoBucks you wish to sell stocks for."
|
||||||
|
@ -1,56 +1,56 @@
|
|||||||
import json
|
import json
|
||||||
|
import pymongo
|
||||||
|
|
||||||
from funcs import logThis, getID, getName
|
from funcs import logThis
|
||||||
|
|
||||||
# Returns the account balance for a user
|
class Money():
|
||||||
def checkBalance(user):
|
|
||||||
user = user.lower()
|
|
||||||
logThis("checking "+user+"'s account balance")
|
|
||||||
with open("resources/users.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if user in data:
|
def __init__(self, bot):
|
||||||
return data[user]["money"]
|
self.bot = bot
|
||||||
else: return 0
|
self.database = bot.database
|
||||||
|
|
||||||
# Adds money to the account of a user
|
# Returns the account balance for a user
|
||||||
def addMoney(user,amount):
|
def checkBalance(self, user):
|
||||||
logThis("adding "+str(amount)+" to "+user+"'s account")
|
logThis("checking "+user+"'s account balance")
|
||||||
with open("resources/users.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if user in data:
|
userData = self.database["users"].find_one({"_id":user})
|
||||||
points = data[user]["money"]
|
|
||||||
data[user]["money"] = points + amount
|
|
||||||
else:
|
|
||||||
data[user]["money"] = amount
|
|
||||||
|
|
||||||
with open("resources/users.json", "w") as f:
|
if userData != None:
|
||||||
json.dump(data,f,indent=4)
|
return userData["money"]
|
||||||
|
else: return 0
|
||||||
|
|
||||||
# Transfers money from one user to another
|
# Adds money to the account of a user
|
||||||
def giveMoney(user,targetUser,amount):
|
def addMoney(self,user,amount):
|
||||||
with open("resources/users.json", "r") as f:
|
logThis("adding "+str(amount)+" to "+user+"'s account")
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
targetUser = getID(targetUser)
|
userData = self.database["users"].find_one({"_id":user})
|
||||||
|
|
||||||
if amount > 0:
|
if userData != None:
|
||||||
if targetUser != None:
|
self.database["users"].update_one({"_id":user},{"$inc":{"money":amount}})
|
||||||
if user in data:
|
|
||||||
if data[user]["money"] >= amount:
|
|
||||||
addMoney(user,-1 * amount)
|
|
||||||
addMoney(targetUser,amount)
|
|
||||||
return "Transferred "+str(amount)+" GwendoBucks to "+getName(targetUser)
|
|
||||||
else:
|
|
||||||
logThis("They didn't have enough GwendoBucks (error code 1223b)")
|
|
||||||
return "You don't have that many GwendoBucks (error code 1223b)"
|
|
||||||
else:
|
|
||||||
logThis("They didn't have enough GwendoBucks (error code 1223a)")
|
|
||||||
return "You don't have that many GwendoBucks (error code 1223a)"
|
|
||||||
else:
|
else:
|
||||||
logThis("They weren't in the system")
|
self.database["users"].insert_one({"_id":user,"user name":self.bot.funcs.getName(user),"money":amount})
|
||||||
return "The target doesn't exist"
|
|
||||||
else:
|
# Transfers money from one user to another
|
||||||
logThis("They tried to steal")
|
def giveMoney(self,user,targetUser,amount):
|
||||||
return "Yeah, no. You can't do that"
|
userData = self.database["users"].find_one({"_id":user})
|
||||||
|
targetUser = self.bot.funcs.getID(targetUser)
|
||||||
|
|
||||||
|
if amount > 0:
|
||||||
|
if targetUser != None:
|
||||||
|
if userData != None:
|
||||||
|
if userData["money"] >= amount:
|
||||||
|
self.addMoney(user,-1 * amount)
|
||||||
|
self.addMoney(targetUser,amount)
|
||||||
|
return "Transferred "+str(amount)+" GwendoBucks to "+self.bot.funcs.getName(targetUser)
|
||||||
|
else:
|
||||||
|
logThis("They didn't have enough GwendoBucks (error code 1223b)")
|
||||||
|
return "You don't have that many GwendoBucks (error code 1223b)"
|
||||||
|
else:
|
||||||
|
logThis("They didn't have enough GwendoBucks (error code 1223a)")
|
||||||
|
return "You don't have that many GwendoBucks (error code 1223a)"
|
||||||
|
else:
|
||||||
|
logThis("They weren't in the system")
|
||||||
|
return "The target doesn't exist"
|
||||||
|
else:
|
||||||
|
logThis("They tried to steal")
|
||||||
|
return "Yeah, no. You can't do that"
|
||||||
|
@ -1,141 +1,138 @@
|
|||||||
import json, random
|
import random
|
||||||
|
|
||||||
from funcs import getName, logThis
|
from funcs import logThis
|
||||||
from . import monopolyDraw
|
from .monopolyDraw import DrawMonopoly
|
||||||
|
|
||||||
rulesAndTerms = {
|
rulesAndTerms = {
|
||||||
"pass go money" : 200,
|
"pass go money" : 200,
|
||||||
"money term" : "GP"
|
"money term" : "GP"
|
||||||
}
|
}
|
||||||
|
|
||||||
def monopolyStart(channel):
|
class Monopoly():
|
||||||
logThis("Starting a monopoly game")
|
def __init__(self, bot):
|
||||||
with open("resources/games/monopolyGames.json", "r") as f:
|
self.bot = bot
|
||||||
data = json.load(f)
|
self.draw = DrawMonopoly(bot)
|
||||||
|
|
||||||
if channel not in data:
|
def monopolyStart(self, channel):
|
||||||
buildings = [0] * 40
|
logThis("Starting a monopoly game")
|
||||||
|
game = self.bot.database["monopoly games"].find_one({"_id":channel})
|
||||||
|
|
||||||
data[channel] = {"players" : {}, "player list" : [],"turn" : 0, "buildings" : buildings, "last roll" : [0,0], "started" : False}
|
if game == None:
|
||||||
|
buildings = [0] * 40
|
||||||
|
|
||||||
with open("resources/games/monopolyGames.json", "w") as f:
|
newGame = {"_id":channel,"players" : {}, "player list" : [],"turn" : 0, "buildings" : buildings, "last roll" : [0,0], "started" : False}
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
try:
|
|
||||||
monopolyDraw.drawImage(channel)
|
|
||||||
except:
|
|
||||||
logThis("Error drawing board (error code 1640)")
|
|
||||||
|
|
||||||
return "Started a monopoly game. Use \"!monopoly join\" to join within the next minute.", True, False, True, True
|
|
||||||
else:
|
|
||||||
return "There's already a monopoly game going on.", False, False, False, False
|
|
||||||
|
|
||||||
def monopolyJoin(channel,user):
|
self.bot.database["monopoly games"].insert_one(newGame)
|
||||||
with open("resources/games/monopolyGames.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if channel in data:
|
try:
|
||||||
if not data[channel]["started"]:
|
self.draw.drawImage(channel)
|
||||||
if user not in data[channel]["players"]:
|
except:
|
||||||
if len(data[channel]["players"]) < 6:
|
logThis("Error drawing board (error code 1640)")
|
||||||
|
|
||||||
data[channel]["players"][user] = {"position" : 0, "properties" : [], "money" : 1500, "doubles" : 0}
|
return "Started a monopoly game. Use \"!monopoly join\" to join within the next minute.", True, False, True, True
|
||||||
|
else:
|
||||||
|
return "There's already a monopoly game going on.", False, False, False, False
|
||||||
|
|
||||||
with open("resources/games/monopolyGames.json", "w") as f:
|
def monopolyJoin(self,channel,user):
|
||||||
json.dump(data,f,indent=4)
|
game = self.bot.database["monopoly games"].find_one({"_id":channel})
|
||||||
|
|
||||||
return getName(user)+" has joined the game.", False, False, False, False
|
if game != None:
|
||||||
|
if not game["started"]:
|
||||||
|
if user not in game["players"]:
|
||||||
|
if len(game["players"]) < 6:
|
||||||
|
|
||||||
|
newPlayer = {"position" : 0, "properties" : [], "money" : 1500, "doubles" : 0}
|
||||||
|
|
||||||
|
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"players."+user:newPlayer}})
|
||||||
|
|
||||||
|
return self.bot.funcs.getName(user)+" has joined the game.", False, False, False, False
|
||||||
|
else:
|
||||||
|
return "There are already 6 players in the game.", False, False, False, False
|
||||||
else:
|
else:
|
||||||
return "There are already 6 players in the game.", False, False, False, False
|
return "You're already in the game!", False, False, False, False
|
||||||
else:
|
else:
|
||||||
return "You're already in the game!", False, False, False, False
|
return "It's too late to join.", False, False, False, False
|
||||||
else:
|
else:
|
||||||
return "It's too late to join.", False, False, False, False
|
return "There's no game going on.", False, False, False, False
|
||||||
else:
|
|
||||||
return "There's no game going on.", False, False, False, False
|
|
||||||
|
|
||||||
def parseMonopoly(command, channel, user):
|
def parseMonopoly(self, command, channel, user):
|
||||||
logThis("Parsing "+command)
|
logThis("Parsing "+command)
|
||||||
commands = command.split()
|
commands = command.split()
|
||||||
if command in [" ", ""] or commands[0] == "start":
|
if command in [" ", ""] or commands[0] == "start":
|
||||||
try:
|
try:
|
||||||
return monopolyStart(channel)
|
return self.monopolyStart(channel)
|
||||||
except:
|
except:
|
||||||
logThis("Error starting game (error code 1620)")
|
logThis("Error starting game (error code 1620)")
|
||||||
elif commands[0] == "join":
|
elif commands[0] == "join":
|
||||||
try:
|
try:
|
||||||
return monopolyJoin(channel,user)
|
return self.monopolyJoin(channel,user)
|
||||||
except:
|
except:
|
||||||
logThis("Error joining game (error code 1630)")
|
logThis("Error joining game (error code 1630)")
|
||||||
elif commands[0] == "roll":
|
elif commands[0] == "roll":
|
||||||
try:
|
try:
|
||||||
return monopolyRoll(channel,user)
|
return self.monopolyRoll(channel,user)
|
||||||
except:
|
except:
|
||||||
logThis("Error rolling (error code 1650)")
|
logThis("Error rolling (error code 1650)")
|
||||||
else:
|
|
||||||
return "I didn't understand that (error code 1602)", False, False, False, False
|
|
||||||
|
|
||||||
def monopolyContinue(channel):
|
|
||||||
with open("resources/games/monopolyGames.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if channel in data:
|
|
||||||
if data[channel]["started"] == False:
|
|
||||||
data[channel]["started"] = True
|
|
||||||
playerList = list(data[channel]["players"].keys())
|
|
||||||
random.shuffle(playerList)
|
|
||||||
data[channel]["player list"] = playerList
|
|
||||||
turn = 0
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if data[channel]["last roll"][0] == data[channel]["last roll"][1]:
|
return "I didn't understand that (error code 1602)", False, False, False, False
|
||||||
turn = data[channel]["turn"]
|
|
||||||
|
def monopolyContinue(self, channel):
|
||||||
|
game = self.bot.database["monopoly games"].find_one({"_id":channel})
|
||||||
|
|
||||||
|
if game != None:
|
||||||
|
if game["started"] == False:
|
||||||
|
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"started":True}})
|
||||||
|
playerList = list(game["players"].keys())
|
||||||
|
random.shuffle(playerList)
|
||||||
|
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"player list":playerList}})
|
||||||
|
turn = 0
|
||||||
|
|
||||||
else:
|
else:
|
||||||
turn = (data[channel]["turn"] + 1)%len(data[channel]["player list"])
|
if game["last roll"][0] == game["last roll"][1]:
|
||||||
data[channel]["turn"] = turn
|
turn = game["turn"]
|
||||||
playerList = list(data[channel]["players"].keys())
|
else:
|
||||||
|
turn = (game["turn"] + 1)%len(game["player list"])
|
||||||
with open("resources/games/monopolyGames.json", "w") as f:
|
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"turn":turn}})
|
||||||
json.dump(data,f,indent=4)
|
playerList = list(game["players"].keys())
|
||||||
|
|
||||||
try:
|
|
||||||
monopolyDraw.drawImage(channel)
|
|
||||||
except:
|
|
||||||
logThis("Error drawing board (error code 1640)")
|
|
||||||
|
|
||||||
message = "It's "+getName(playerList[turn])+"'s turn. Use the 🎲 reaction to roll. You can also use \"!monopoly trade\" at any time."
|
try:
|
||||||
return message, True, True, False
|
self.draw.drawImage(channel)
|
||||||
|
except:
|
||||||
|
logThis("Error drawing board (error code 1640)")
|
||||||
|
|
||||||
def monopolyRoll(channel,user):
|
if playerList == []:
|
||||||
with open("resources/games/monopolyGames.json", "r") as f:
|
return "No one joined. Ending game.", False, True, True
|
||||||
data = json.load(f)
|
else:
|
||||||
|
message = "It's "+self.bot.funcs.getName(playerList[turn])+"'s turn. Use the 🎲 reaction to roll. You can also use \"!monopoly trade\" at any time."
|
||||||
turn = data[channel]["turn"]
|
return message, True, True, False
|
||||||
currentPlayer = data[channel]["player list"][turn]
|
|
||||||
|
|
||||||
if user == currentPlayer:
|
def monopolyRoll(self, channel,user):
|
||||||
rolls = [random.randint(1,6),random.randint(1,6)]
|
game = self.bot.database["monopoly games"].find_one({"_id":channel})
|
||||||
message = getName(user)+" rolled a "+str(rolls[0])+" and a "+str(rolls[1])+"."
|
|
||||||
if rolls[0] == rolls[1]:
|
|
||||||
message += " Doubbles!"
|
|
||||||
|
|
||||||
roll = rolls[0] + rolls[1]
|
turn = game["turn"]
|
||||||
oldPosition = data[channel]["players"][user]["position"]
|
currentPlayer = game["player list"][turn]
|
||||||
newPosition = (oldPosition + roll)%40
|
|
||||||
if newPosition < oldPosition:
|
|
||||||
data[channel]["players"][user]["money"] += rulesAndTerms["pass go money"]
|
|
||||||
message += "\nYou passed go and got "+str(rulesAndTerms["pass go money"])+" "+rulesAndTerms["money term"]+"."
|
|
||||||
|
|
||||||
data[channel]["players"][user]["position"] = newPosition
|
if user == currentPlayer:
|
||||||
data[channel]["last roll"] = rolls
|
rolls = [random.randint(1,6),random.randint(1,6)]
|
||||||
|
message = self.bot.funcs.getName(user)+" rolled a "+str(rolls[0])+" and a "+str(rolls[1])+"."
|
||||||
|
if rolls[0] == rolls[1]:
|
||||||
|
message += " Doubbles!"
|
||||||
|
|
||||||
with open("resources/games/monopolyGames.json", "w") as f:
|
roll = rolls[0] + rolls[1]
|
||||||
json.dump(data,f,indent=4)
|
oldPosition = game["players"][user]["position"]
|
||||||
|
newPosition = (oldPosition + roll)%40
|
||||||
try:
|
if newPosition < oldPosition:
|
||||||
monopolyDraw.drawImage(channel)
|
self.bot.database["monopoly games"].update_one({"_id":channel},
|
||||||
except:
|
{"$inc":{"players."+user+".money":rulesAndTerms["pass go money"]}})
|
||||||
logThis("Error drawing board (error code 1640)")
|
message += "\nYou passed go and got "+str(rulesAndTerms["pass go money"])+" "+rulesAndTerms["money term"]+"."
|
||||||
|
|
||||||
return message, True, True, False, True
|
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"players."+user+".position":newPosition}})
|
||||||
else: return "", False, False, False, False
|
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"last roll":rolls}})
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw.drawImage(channel)
|
||||||
|
except:
|
||||||
|
logThis("Error drawing board (error code 1640)")
|
||||||
|
|
||||||
|
return message, True, True, False, True
|
||||||
|
else: return "", False, False, False, False
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import math, json
|
import math
|
||||||
|
|
||||||
from funcs import logThis
|
from funcs import logThis
|
||||||
|
|
||||||
@ -10,48 +10,48 @@ smallSpace = math.floor((w - 2*largeSpace)/9)
|
|||||||
avatarSize = 50
|
avatarSize = 50
|
||||||
avatarHalf = math.floor(avatarSize/2)
|
avatarHalf = math.floor(avatarSize/2)
|
||||||
|
|
||||||
def drawImage(channel):
|
class DrawMonopoly():
|
||||||
logThis("Drawing monopoly board for "+channel)
|
def __init__(self,bot):
|
||||||
with open("resources/games/monopolyGames.json", "r") as f:
|
self.bot = bot
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
board = Image.open("resources/games/monopolyBoard.png")
|
def drawImage(self, channel):
|
||||||
d = ImageDraw.Draw(board,"RGBA")
|
logThis("Drawing monopoly board for "+channel)
|
||||||
|
game = self.bot.database["monopoly games"].find_one({"_id":channel})
|
||||||
|
|
||||||
for key, value in list(data[channel]["players"].items()):
|
board = Image.open("resources/games/monopolyBoard.png")
|
||||||
logThis("Drawing "+key)
|
d = ImageDraw.Draw(board,"RGBA")
|
||||||
try:
|
|
||||||
x, y = getPosition(value["position"])
|
|
||||||
except:
|
|
||||||
logThis("Error getting position (error code 1641)")
|
|
||||||
print(str(x)+", "+str(y))
|
|
||||||
d.ellipse([(x-avatarHalf,y-avatarHalf),(x+avatarHalf,y+avatarHalf)],fill=(255,0,0))
|
|
||||||
|
|
||||||
board.save("resources/games/monopolyBoards/monopolyBoard"+channel+".png")
|
for key, value in list(game["players"].items()):
|
||||||
|
logThis("Drawing "+key)
|
||||||
|
try:
|
||||||
|
x, y = self.getPosition(value["position"])
|
||||||
|
except:
|
||||||
|
logThis("Error getting position (error code 1641)")
|
||||||
|
d.ellipse([(x-avatarHalf,y-avatarHalf),(x+avatarHalf,y+avatarHalf)],fill=(255,0,0))
|
||||||
|
|
||||||
|
board.save("resources/games/monopolyBoards/monopolyBoard"+channel+".png")
|
||||||
|
|
||||||
|
|
||||||
def getPosition(positionNumber):
|
def getPosition(self, positionNumber):
|
||||||
print(positionNumber)
|
x, y = 0, 0
|
||||||
|
if positionNumber == 0 or positionNumber >= 30:
|
||||||
|
x = math.floor(largeSpace/2)
|
||||||
|
elif positionNumber > 0 and positionNumber < 10:
|
||||||
|
x = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*positionNumber)
|
||||||
|
elif positionNumber >= 10 and positionNumber <= 20:
|
||||||
|
x = w - math.floor(largeSpace/2)
|
||||||
|
elif positionNumber > 20 and positionNumber < 30:
|
||||||
|
x = w - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 20))
|
||||||
|
|
||||||
x, y = 0, 0
|
if positionNumber >= 0 and positionNumber <= 10:
|
||||||
if positionNumber == 0 or positionNumber >= 30:
|
y = math.floor(largeSpace/2)
|
||||||
x = math.floor(largeSpace/2)
|
elif positionNumber > 10 and positionNumber < 20:
|
||||||
elif positionNumber > 0 and positionNumber < 10:
|
y = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*(positionNumber-10))
|
||||||
x = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*positionNumber)
|
elif positionNumber >= 20 and positionNumber <= 30:
|
||||||
elif positionNumber >= 10 and positionNumber <= 20:
|
y = h - math.floor(largeSpace/2)
|
||||||
x = w - math.floor(largeSpace/2)
|
elif positionNumber > 30:
|
||||||
elif positionNumber > 20 and positionNumber < 30:
|
y = h - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 30))
|
||||||
x = w - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 20))
|
|
||||||
|
|
||||||
if positionNumber >= 0 and positionNumber <= 20:
|
return x, y
|
||||||
y = math.floor(largeSpace/2)
|
|
||||||
elif positionNumber > 10 and positionNumber < 20:
|
|
||||||
y = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*(positionNumber-10))
|
|
||||||
elif positionNumber >= 20 and positionNumber <= 30:
|
|
||||||
y = h - math.floor(largeSpace/2)
|
|
||||||
elif positionNumber > 30:
|
|
||||||
y = h - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 30))
|
|
||||||
|
|
||||||
return x, y
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,88 +5,84 @@ import random
|
|||||||
from . import money
|
from . import money
|
||||||
from funcs import logThis
|
from funcs import logThis
|
||||||
|
|
||||||
# Starts a game of trivia. Downloads a question with answers, shuffles the wrong answers with the
|
class Trivia():
|
||||||
# correct answer and returns the questions and answers. Also saves the question in the games.json file.
|
def __init__(self, bot):
|
||||||
def triviaStart(channel : str):
|
self.bot = bot
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
triviaFile = json.load(f)
|
|
||||||
|
|
||||||
logThis("Trying to find a trivia question for "+channel)
|
|
||||||
|
|
||||||
if channel not in triviaFile["trivia questions"]:
|
# Starts a game of trivia. Downloads a question with answers, shuffles the wrong answers with the
|
||||||
with urllib.request.urlopen("https://opentdb.com/api.php?amount=10&type=multiple") as response:
|
# correct answer and returns the questions and answers. Also saves the question in the games.json file.
|
||||||
data = json.loads(response.read())
|
def triviaStart(self, channel : str):
|
||||||
|
question = self.bot.database["trivia questions"].find_one({"_id":channel})
|
||||||
logThis("Found the question \""+data["results"][0]["question"]+"\"")
|
|
||||||
answers = data["results"][0]["incorrect_answers"]
|
|
||||||
answers.append(data["results"][0]["correct_answer"])
|
|
||||||
random.shuffle(answers)
|
|
||||||
correctAnswer = answers.index(data["results"][0]["correct_answer"]) + 97
|
|
||||||
|
|
||||||
triviaFile["trivia questions"][channel] = {"answer" : str(chr(correctAnswer)),"players" : {}}
|
|
||||||
with open("resources/games/games.json", "w") as f:
|
|
||||||
json.dump(triviaFile,f,indent=4)
|
|
||||||
|
|
||||||
replacements = {"'": "\'",
|
logThis("Trying to find a trivia question for "+channel)
|
||||||
""": "\"",
|
|
||||||
"“": "\"",
|
if question == None:
|
||||||
"”": "\"",
|
with urllib.request.urlopen("https://opentdb.com/api.php?amount=10&type=multiple") as response:
|
||||||
"é": "é"}
|
data = json.loads(response.read())
|
||||||
question = data["results"][0]["question"]
|
|
||||||
|
logThis("Found the question \""+data["results"][0]["question"]+"\"")
|
||||||
|
answers = data["results"][0]["incorrect_answers"]
|
||||||
|
answers.append(data["results"][0]["correct_answer"])
|
||||||
|
random.shuffle(answers)
|
||||||
|
correctAnswer = answers.index(data["results"][0]["correct_answer"]) + 97
|
||||||
|
|
||||||
|
self.bot.database["trivia questions"].insert_one({"_id":channel,"answer" : str(chr(correctAnswer)),"players" : {}})
|
||||||
|
|
||||||
|
replacements = {"'": "\'",
|
||||||
|
""": "\"",
|
||||||
|
"“": "\"",
|
||||||
|
"”": "\"",
|
||||||
|
"é": "é"}
|
||||||
|
question = data["results"][0]["question"]
|
||||||
|
|
||||||
for key, value in replacements.items():
|
|
||||||
question = question.replace(key,value)
|
|
||||||
|
|
||||||
for answer in answers:
|
|
||||||
for key, value in replacements.items():
|
for key, value in replacements.items():
|
||||||
answer = answer.replace(key,value)
|
question = question.replace(key,value)
|
||||||
|
|
||||||
return question, answers, correctAnswer
|
for answer in answers:
|
||||||
else:
|
for key, value in replacements.items():
|
||||||
logThis("There was already a trivia question for that channel (error code 1106)")
|
answer = answer.replace(key,value)
|
||||||
return "There's already a trivia question going on. Try again in like, a minute (error code 1106)", "", ""
|
|
||||||
|
|
||||||
# Lets players answer a trivia question
|
return question, answers, correctAnswer
|
||||||
def triviaAnswer(user : str, channel : str, command : str):
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if command in ["a","b","c","d"]:
|
|
||||||
if channel in data["trivia questions"]:
|
|
||||||
if user not in data["trivia questions"][channel]["players"]:
|
|
||||||
logThis(user+" answered the question in "+channel)
|
|
||||||
|
|
||||||
data["trivia questions"][channel]["players"][user] = command
|
|
||||||
|
|
||||||
with open("resources/games/games.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
return "Locked in "+user+"'s answer"
|
|
||||||
else:
|
|
||||||
logThis(user+" has already answered this question (error code 1105)")
|
|
||||||
return user+" has already answered this question (error code 1105)"
|
|
||||||
else:
|
else:
|
||||||
logThis("There's no question right now (error code 1104)")
|
logThis("There was already a trivia question for that channel (error code 1106)")
|
||||||
return "There's no question right now (error code 1104)"
|
return "There's already a trivia question going on. Try again in like, a minute (error code 1106)", "", ""
|
||||||
else:
|
|
||||||
logThis("I didn't quite understand that (error code 1103)")
|
# Lets players answer a trivia question
|
||||||
return "I didn't quite understand that (error code 1103)"
|
def triviaAnswer(self, user : str, channel : str, command : str):
|
||||||
|
question = self.bot.database["trivia questions"].find_one({"_id":channel})
|
||||||
|
|
||||||
|
if command in ["a","b","c","d"]:
|
||||||
|
if question != None:
|
||||||
|
if user not in question["players"]:
|
||||||
|
logThis(user+" answered the question in "+channel)
|
||||||
|
|
||||||
|
self.bot.database["trivia questions"].update_one({"_id":channel},{"$set":{"players."+user : command}})
|
||||||
|
|
||||||
|
return "Locked in "+user+"'s answer"
|
||||||
|
else:
|
||||||
|
logThis(user+" has already answered this question (error code 1105)")
|
||||||
|
return user+" has already answered this question (error code 1105)"
|
||||||
|
else:
|
||||||
|
logThis("There's no question right now (error code 1104)")
|
||||||
|
return "There's no question right now (error code 1104)"
|
||||||
|
else:
|
||||||
|
logThis("I didn't quite understand that (error code 1103)")
|
||||||
|
return "I didn't quite understand that (error code 1103)"
|
||||||
|
|
||||||
|
|
||||||
# Adds 1 GwendoBuck to each player that got the question right and deletes question from games.json.
|
# Adds 1 GwendoBuck to each player that got the question right and deletes question from games.json.
|
||||||
def triviaCountPoints(channel : str):
|
def triviaCountPoints(self, channel : str):
|
||||||
with open("resources/games/games.json", "r") as f:
|
question = self.bot.database["trivia questions"].find_one({"_id":channel})
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
logThis("Counting points for question in "+channel)
|
logThis("Counting points for question in "+channel)
|
||||||
|
|
||||||
if channel in data["trivia questions"]:
|
if question != None:
|
||||||
for player, answer in data["trivia questions"][channel]["players"].items():
|
for player, answer in question["players"].items():
|
||||||
if answer == data["trivia questions"][channel]["answer"]:
|
if answer == question["answer"]:
|
||||||
money.addMoney(player,1)
|
self.bot.money.addMoney(player,1)
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
logThis("Couldn't find the question (error code 1102)")
|
|
||||||
|
|
||||||
return None
|
else:
|
||||||
|
logThis("Couldn't find the question (error code 1102)")
|
||||||
|
|
||||||
|
return None
|
||||||
|
@ -7,7 +7,6 @@ import time # Used for logging
|
|||||||
import logging # Used for... you know... logging
|
import logging # Used for... you know... logging
|
||||||
import wikia # Used by findWikiPage
|
import wikia # Used by findWikiPage
|
||||||
import os # Used by makeFiles
|
import os # Used by makeFiles
|
||||||
import git # Used by stopServer()
|
|
||||||
import pymongo # Used by transferUsers
|
import pymongo # Used by transferUsers
|
||||||
|
|
||||||
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
||||||
@ -207,86 +206,6 @@ def emojiToCommand(emoji):
|
|||||||
return "roll"
|
return "roll"
|
||||||
else: return ""
|
else: return ""
|
||||||
|
|
||||||
def fiarReactionTest(channel,message,user):
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
with open("resources/games/oldImages/fourInARow"+str(channel.id), "r") as f:
|
|
||||||
oldImage = int(f.read())
|
|
||||||
|
|
||||||
if message.id == oldImage:
|
|
||||||
logThis("They reacted to the fourinarow game")
|
|
||||||
turn = data["4 in a row games"][str(channel.id)]["turn"]
|
|
||||||
if user == data["4 in a row games"][str(channel.id)]["players"][turn]:
|
|
||||||
return True, turn+1
|
|
||||||
else:
|
|
||||||
logThis("It wasn't their turn")
|
|
||||||
return False, 0
|
|
||||||
else:
|
|
||||||
return False, 0
|
|
||||||
|
|
||||||
def monopolyReactionTest(channel,message):
|
|
||||||
try:
|
|
||||||
with open("resources/games/oldImages/monopoly"+str(channel.id), "r") as f:
|
|
||||||
oldImage = int(f.read())
|
|
||||||
except:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if message.id == oldImage:
|
|
||||||
logThis("They reacted to the monopoly game")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def hangmanReactionTest(channel,message):
|
|
||||||
try:
|
|
||||||
with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f:
|
|
||||||
oldMessages = f.read().splitlines()
|
|
||||||
except:
|
|
||||||
return False
|
|
||||||
gameMessage = False
|
|
||||||
|
|
||||||
for oldMessage in oldMessages:
|
|
||||||
oldMessageID = int(oldMessage)
|
|
||||||
if message.id == oldMessageID:
|
|
||||||
logThis("They reacted to the hangman game")
|
|
||||||
gameMessage = True
|
|
||||||
|
|
||||||
return gameMessage
|
|
||||||
|
|
||||||
def stopServer():
|
|
||||||
with open("resources/games/games.json","r") as f:
|
|
||||||
games = json.load(f)
|
|
||||||
|
|
||||||
games["trivia questions"] = {}
|
|
||||||
games["blackjack games"] = {}
|
|
||||||
games["4 in a row games"] = {}
|
|
||||||
|
|
||||||
with open("resources/games/games.json","w") as f:
|
|
||||||
json.dump(games,f,indent=4)
|
|
||||||
|
|
||||||
emptyDict = {}
|
|
||||||
|
|
||||||
with open("resources/games/monopolyGames.json", "w") as f:
|
|
||||||
json.dump(emptyDict,f,indent=4)
|
|
||||||
|
|
||||||
with open("resources/games/hexGames.json", "w") as f:
|
|
||||||
json.dump(emptyDict,f,indent=4)
|
|
||||||
|
|
||||||
with open("resources/games/hangmanGames.json", "w") as f:
|
|
||||||
json.dump(emptyDict,f,indent=4)
|
|
||||||
|
|
||||||
g = git.cmd.Git("")
|
|
||||||
g.pull()
|
|
||||||
|
|
||||||
def deleteGame(gameType,channel):
|
|
||||||
with open("resources/games/games.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
del data[gameType][channel]
|
|
||||||
with open("resources/games/games.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
def addToDict(userID,userName):
|
def addToDict(userID,userName):
|
||||||
with open("resources/users.json", "r") as f:
|
with open("resources/users.json", "r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
@ -315,35 +234,6 @@ def addToDict(userID,userName):
|
|||||||
with open("resources/users.json", "w") as f:
|
with open("resources/users.json", "w") as f:
|
||||||
json.dump(data,f,indent=4)
|
json.dump(data,f,indent=4)
|
||||||
|
|
||||||
def getName(userID):
|
|
||||||
try:
|
|
||||||
with open("resources/users.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if userID in data:
|
|
||||||
return data[userID]["user name"]
|
|
||||||
else:
|
|
||||||
logThis("Couldn't find user "+userID)
|
|
||||||
return userID
|
|
||||||
except:
|
|
||||||
logThis("Error getting name")
|
|
||||||
|
|
||||||
def getID(userName):
|
|
||||||
try:
|
|
||||||
with open("resources/users.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
userID = None
|
|
||||||
|
|
||||||
for key, value in data.items():
|
|
||||||
if userName.lower() == value["user name"].lower():
|
|
||||||
userID = key
|
|
||||||
break
|
|
||||||
|
|
||||||
return userID
|
|
||||||
except:
|
|
||||||
logThis("Error getting ID")
|
|
||||||
|
|
||||||
def transferUsers(database):
|
def transferUsers(database):
|
||||||
collist = database.list_collection_names()
|
collist = database.list_collection_names()
|
||||||
if "users" not in collist and os.path.exists("resources/users.json"):
|
if "users" not in collist and os.path.exists("resources/users.json"):
|
||||||
@ -354,7 +244,20 @@ def transferUsers(database):
|
|||||||
userList = []
|
userList = []
|
||||||
|
|
||||||
for key, value in list(data.items()):
|
for key, value in list(data.items()):
|
||||||
user = {"_id":int(key[1:]),"user name":value["user name"],"money":value["money"]}
|
user = {"_id":key,"user name":value["user name"],"money":value["money"]}
|
||||||
userList.append(user)
|
userList.append(user)
|
||||||
|
|
||||||
database["users"].insert_many(userList)
|
database["users"].insert_many(userList)
|
||||||
|
|
||||||
|
if "investments" not in collist and os.path.exists("resources/games/investments.json"):
|
||||||
|
logThis("Transfering investments")
|
||||||
|
with open("resources/games/investments.json", "r") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
userList = []
|
||||||
|
|
||||||
|
for key, value in list(data.items()):
|
||||||
|
user = {"_id":key,"investments":value}
|
||||||
|
userList.append(user)
|
||||||
|
|
||||||
|
database["investments"].insert_many(userList)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Functions related to the Star Wars TTRPG."""
|
"""Functions related to the Star Wars TTRPG."""
|
||||||
|
|
||||||
__all__ = ["parseChar", "parseRoll", "critRoll", "parseDestiny"]
|
__all__ = ["SwChar", "SwRoll", "SwDestiny"]
|
||||||
|
|
||||||
from .swchar import parseChar
|
from .swchar import SwChar
|
||||||
from .swroll import parseRoll, critRoll
|
from .swroll import SwRoll
|
||||||
from .swdestiny import parseDestiny
|
from .swdestiny import SwDestiny
|
@ -1,142 +1,201 @@
|
|||||||
import json
|
import json
|
||||||
import string
|
import string
|
||||||
|
|
||||||
from funcs import logThis, getName
|
from funcs import logThis
|
||||||
|
|
||||||
def getCharName(user : str):
|
class SwChar():
|
||||||
logThis("Getting name for "+getName(user)+"'s character")
|
def __init__(self, bot):
|
||||||
with open("resources/starWars/swcharacters.json", "r") as f:
|
self.bot = bot
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if user in data:
|
|
||||||
logThis("Name is "+data[user]["Name"])
|
|
||||||
return data[user]["Name"]
|
|
||||||
else:
|
|
||||||
logThis("Just using "+getName(user))
|
|
||||||
return getName(user)
|
|
||||||
|
|
||||||
def setUpDict(cmd : dict):
|
def getCharName(self, user : str):
|
||||||
logThis("Setting up a dictionary in a nice way")
|
logThis("Getting name for "+self.bot.funcs.getName(user)+"'s character")
|
||||||
if bool(cmd):
|
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
|
||||||
keys = list(cmd)
|
|
||||||
values = list(cmd.values())
|
if user != None:
|
||||||
result = ""
|
logThis("Name is "+userCharacter["Name"])
|
||||||
if type(values[0]) is dict:
|
return userCharacter["Name"]
|
||||||
return ", ".join(values)
|
|
||||||
else:
|
else:
|
||||||
for x in range(len(keys)):
|
logThis("Just using "+self.bot.funcs.getName(user))
|
||||||
if type(keys[x]) is list:
|
return self.bot.funcs.getName(user)
|
||||||
if x%3 != 2:
|
|
||||||
result += "**" + keys[x] + "**" + ": " + ", ".join(values[x]) + " "
|
|
||||||
else:
|
|
||||||
result += "**" + keys[x] + "**" + ": " + ", ".join(values[x]) + "\n"
|
|
||||||
else:
|
|
||||||
if x%3 != 2:
|
|
||||||
result += "**" + keys[x] + "**" + ": " + str(values[x]) + " "
|
|
||||||
else:
|
|
||||||
result += "**" + keys[x] + "**" + ": " + str(values[x]) + "\n"
|
|
||||||
logThis("Returning a dictionary, but well formatted")
|
|
||||||
return result
|
|
||||||
else:
|
|
||||||
logThis("Couldn't find anything")
|
|
||||||
return "There doesn't seem to be anything here..."
|
|
||||||
|
|
||||||
def lookUp(data : dict, key : str, cmd : str = ""):
|
def setUpDict(self, cmd : dict):
|
||||||
if cmd == " ":
|
logThis("Setting up a dictionary in a nice way")
|
||||||
cmd = ""
|
if bool(cmd):
|
||||||
elif cmd != "":
|
keys = list(cmd)
|
||||||
while cmd[0] == " ":
|
values = list(cmd.values())
|
||||||
cmd = cmd[1:]
|
result = ""
|
||||||
if cmd == "":
|
if type(values[0]) is dict:
|
||||||
break
|
return ", ".join(values)
|
||||||
|
|
||||||
logThis("Looking up "+key)
|
|
||||||
if key in data:
|
|
||||||
logThis(key+" exists")
|
|
||||||
if cmd == "":
|
|
||||||
if type(data[key]) is dict and key != "Weapons":
|
|
||||||
return setUpDict(data[key])
|
|
||||||
elif key == "Weapons":
|
|
||||||
logThis("Does this even get used? I'm too scared to delete it")
|
|
||||||
if bool(data[key]):
|
|
||||||
logThis("Found "+(", ".join(list(data[key]))))
|
|
||||||
return ", ".join(list(data[key]))
|
|
||||||
else:
|
|
||||||
logThis("There is nothing here")
|
|
||||||
return "There doesn't seem to be anything here..."
|
|
||||||
else:
|
else:
|
||||||
if str(data[key]) != "":
|
for x in range(len(keys)):
|
||||||
logThis("Returning "+str(data[key]))
|
if type(keys[x]) is list:
|
||||||
return data[key]
|
if x%3 != 2:
|
||||||
else:
|
result += "**" + keys[x] + "**" + ": " + ", ".join(values[x]) + " "
|
||||||
logThis("There was nothing there")
|
else:
|
||||||
return "There doesn't seem to be anything here"
|
result += "**" + keys[x] + "**" + ": " + ", ".join(values[x]) + "\n"
|
||||||
elif cmd[0] == '+':
|
else:
|
||||||
logThis("Trying to add to "+key)
|
if x%3 != 2:
|
||||||
try:
|
result += "**" + keys[x] + "**" + ": " + str(values[x]) + " "
|
||||||
cmd = cmd[1:]
|
else:
|
||||||
while cmd[0] == ' ':
|
result += "**" + keys[x] + "**" + ": " + str(values[x]) + "\n"
|
||||||
cmd = cmd[1:]
|
logThis("Returning a dictionary, but well formatted")
|
||||||
except:
|
return result
|
||||||
logThis("Yeah, that fucked up")
|
else:
|
||||||
return "Can't do that"
|
logThis("Couldn't find anything")
|
||||||
|
return "There doesn't seem to be anything here..."
|
||||||
|
|
||||||
if type(data[key]) is int:
|
def lookUp(self, data : dict, key : str, cmd : str = ""):
|
||||||
|
if cmd == " ":
|
||||||
|
cmd = ""
|
||||||
|
elif cmd != "":
|
||||||
|
while cmd[0] == " ":
|
||||||
|
cmd = cmd[1:]
|
||||||
|
if cmd == "":
|
||||||
|
break
|
||||||
|
|
||||||
|
logThis("Looking up "+key)
|
||||||
|
if key in data:
|
||||||
|
logThis(key+" exists")
|
||||||
|
if cmd == "":
|
||||||
|
if type(data[key]) is dict and key != "Weapons":
|
||||||
|
return self.setUpDict(data[key])
|
||||||
|
elif key == "Weapons":
|
||||||
|
logThis("Does this even get used? I'm too scared to delete it")
|
||||||
|
if bool(data[key]):
|
||||||
|
logThis("Found "+(", ".join(list(data[key]))))
|
||||||
|
return ", ".join(list(data[key]))
|
||||||
|
else:
|
||||||
|
logThis("There is nothing here")
|
||||||
|
return "There doesn't seem to be anything here..."
|
||||||
|
else:
|
||||||
|
if str(data[key]) != "":
|
||||||
|
logThis("Returning "+str(data[key]))
|
||||||
|
return data[key]
|
||||||
|
else:
|
||||||
|
logThis("There was nothing there")
|
||||||
|
return "There doesn't seem to be anything here"
|
||||||
|
elif cmd[0] == '+':
|
||||||
|
logThis("Trying to add to "+key)
|
||||||
try:
|
try:
|
||||||
newValue = data[key] + int(cmd)
|
cmd = cmd[1:]
|
||||||
data[key] = newValue
|
while cmd[0] == ' ':
|
||||||
logThis("Added "+cmd+" to "+key)
|
cmd = cmd[1:]
|
||||||
return data
|
|
||||||
except:
|
except:
|
||||||
logThis("Couldn't add "+cmd+" to "+key)
|
logThis("Yeah, that fucked up")
|
||||||
return "Can't add that"
|
return "Can't do that"
|
||||||
elif type(data[key]) is list:
|
|
||||||
|
if type(data[key]) is int:
|
||||||
try:
|
try:
|
||||||
data[key].append(cmd)
|
newValue = data[key] + int(cmd)
|
||||||
|
data[key] = newValue
|
||||||
logThis("Added "+cmd+" to "+key)
|
logThis("Added "+cmd+" to "+key)
|
||||||
return data
|
return data
|
||||||
except:
|
except:
|
||||||
logThis("Couldn't add "+cmd+" to "+key)
|
logThis("Couldn't add "+cmd+" to "+key)
|
||||||
return "Can't add that"
|
return "Can't add that"
|
||||||
else:
|
elif type(data[key]) is list:
|
||||||
logThis("Yeah, I can't add that to "+key)
|
try:
|
||||||
return "Can't add that"
|
data[key].append(cmd)
|
||||||
|
logThis("Added "+cmd+" to "+key)
|
||||||
|
return data
|
||||||
|
except:
|
||||||
|
logThis("Couldn't add "+cmd+" to "+key)
|
||||||
|
return "Can't add that"
|
||||||
|
else:
|
||||||
|
logThis("Yeah, I can't add that to "+key)
|
||||||
|
return "Can't add that"
|
||||||
|
|
||||||
elif cmd[0] == '-':
|
elif cmd[0] == '-':
|
||||||
logThis("Trying to remove/subtract from "+key)
|
logThis("Trying to remove/subtract from "+key)
|
||||||
try:
|
|
||||||
cmd = cmd[1:]
|
|
||||||
while cmd[0] == ' ':
|
|
||||||
cmd = cmd[1:]
|
|
||||||
except:
|
|
||||||
logThis("Yeah, that fucked up")
|
|
||||||
return "Can't do that"
|
|
||||||
|
|
||||||
if type(data[key]) is int:
|
|
||||||
try:
|
try:
|
||||||
newValue = data[key] - int(cmd)
|
cmd = cmd[1:]
|
||||||
data[key] = newValue
|
while cmd[0] == ' ':
|
||||||
logThis("Subtracted "+cmd+" from "+key)
|
cmd = cmd[1:]
|
||||||
return data
|
|
||||||
except:
|
except:
|
||||||
logThis("Couldn't subtract "+cmd+" from "+key)
|
logThis("Yeah, that fucked up")
|
||||||
return "Can't remove that"
|
return "Can't do that"
|
||||||
elif type(data[key]) is list:
|
|
||||||
|
if type(data[key]) is int:
|
||||||
try:
|
try:
|
||||||
data[key].remove(cmd)
|
newValue = data[key] - int(cmd)
|
||||||
logThis("Removed "+cmd+" from "+key)
|
data[key] = newValue
|
||||||
|
logThis("Subtracted "+cmd+" from "+key)
|
||||||
return data
|
return data
|
||||||
except:
|
except:
|
||||||
logThis("Couldn't remove "+cmd+" from "+key)
|
logThis("Couldn't subtract "+cmd+" from "+key)
|
||||||
return "Can't remove that"
|
return "Can't remove that"
|
||||||
|
elif type(data[key]) is list:
|
||||||
|
try:
|
||||||
|
data[key].remove(cmd)
|
||||||
|
logThis("Removed "+cmd+" from "+key)
|
||||||
|
return data
|
||||||
|
except:
|
||||||
|
logThis("Couldn't remove "+cmd+" from "+key)
|
||||||
|
return "Can't remove that"
|
||||||
|
else:
|
||||||
|
logThis("Yeah, I can't remove/subtract that from "+key)
|
||||||
|
return "Can't remove that"
|
||||||
else:
|
else:
|
||||||
logThis("Yeah, I can't remove/subtract that from "+key)
|
while cmd[0] == ' ':
|
||||||
return "Can't remove that"
|
cmd = cmd[1:]
|
||||||
else:
|
|
||||||
while cmd[0] == ' ':
|
|
||||||
cmd = cmd[1:]
|
|
||||||
|
|
||||||
if type(data[key]) is dict:
|
if type(data[key]) is dict:
|
||||||
|
newKey = cmd.split(" ")[0]
|
||||||
|
cmd = cmd[len(newKey):]
|
||||||
|
if cmd != "":
|
||||||
|
while cmd[0] == " ":
|
||||||
|
cmd = cmd[1:]
|
||||||
|
if cmd == "":
|
||||||
|
break
|
||||||
|
logThis("Looking up "+newKey+" in "+key)
|
||||||
|
lookUpResult = self.lookUp(data[key],newKey,cmd)
|
||||||
|
if type(lookUpResult) is dict:
|
||||||
|
data[key] = lookUpResult
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
return lookUpResult
|
||||||
|
elif type(data[key]) != list:
|
||||||
|
logThis("Trying to change "+key+" to "+cmd)
|
||||||
|
try:
|
||||||
|
cmd = type(data[key])(cmd)
|
||||||
|
data[key] = cmd
|
||||||
|
logThis("Did that")
|
||||||
|
return data
|
||||||
|
except:
|
||||||
|
logThis("No. That did not work")
|
||||||
|
return "Wrong data type"
|
||||||
|
else:
|
||||||
|
logThis("Yeah, that didn't work")
|
||||||
|
return "Wrong data type"
|
||||||
|
else:
|
||||||
|
logThis("Couldn't find "+key)
|
||||||
|
logThis("Testing to see if it's a multi-word key")
|
||||||
|
cmd = key + " " + cmd
|
||||||
|
words = cmd.split(" ")
|
||||||
|
search = ""
|
||||||
|
i = 0
|
||||||
|
while search not in data:
|
||||||
|
try:
|
||||||
|
search += " " + words[i]
|
||||||
|
i += 1
|
||||||
|
except:
|
||||||
|
logThis("It wasn't. "+search+" doesn't exist")
|
||||||
|
return search + " doesn't exist"
|
||||||
|
if search[0] == " ":
|
||||||
|
search = search[1:]
|
||||||
|
logThis("Yeah! Did that! The key was "+search)
|
||||||
|
|
||||||
|
cmd = cmd[len(search):]
|
||||||
|
if cmd != "":
|
||||||
|
while cmd[0] == " ":
|
||||||
|
cmd = cmd[1:]
|
||||||
|
if cmd == "":
|
||||||
|
break
|
||||||
|
|
||||||
|
if cmd == "":
|
||||||
|
logThis("Returning "+search)
|
||||||
|
return self.setUpDict(data[search])
|
||||||
|
else:
|
||||||
newKey = cmd.split(" ")[0]
|
newKey = cmd.split(" ")[0]
|
||||||
cmd = cmd[len(newKey):]
|
cmd = cmd[len(newKey):]
|
||||||
if cmd != "":
|
if cmd != "":
|
||||||
@ -144,394 +203,321 @@ def lookUp(data : dict, key : str, cmd : str = ""):
|
|||||||
cmd = cmd[1:]
|
cmd = cmd[1:]
|
||||||
if cmd == "":
|
if cmd == "":
|
||||||
break
|
break
|
||||||
logThis("Looking up "+newKey+" in "+key)
|
lookUpResult = self.lookUp(data[search],newKey,cmd)
|
||||||
lookUpResult = lookUp(data[key],newKey,cmd)
|
|
||||||
if type(lookUpResult) is dict:
|
if type(lookUpResult) is dict:
|
||||||
data[key] = lookUpResult
|
data[search] = lookUpResult
|
||||||
return data
|
return data
|
||||||
else:
|
else:
|
||||||
return lookUpResult
|
return lookUpResult
|
||||||
elif type(data[key]) != list:
|
|
||||||
logThis("Trying to change "+key+" to "+cmd)
|
|
||||||
try:
|
|
||||||
cmd = type(data[key])(cmd)
|
|
||||||
data[key] = cmd
|
|
||||||
logThis("Did that")
|
|
||||||
return data
|
|
||||||
except:
|
|
||||||
logThis("No. That did not work")
|
|
||||||
return "Wrong data type"
|
|
||||||
else:
|
|
||||||
logThis("Yeah, that didn't work")
|
|
||||||
return "Wrong data type"
|
|
||||||
else:
|
|
||||||
logThis("Couldn't find "+key)
|
|
||||||
logThis("Testing to see if it's a multi-word key")
|
|
||||||
cmd = key + " " + cmd
|
|
||||||
words = cmd.split(" ")
|
|
||||||
search = ""
|
|
||||||
i = 0
|
|
||||||
while search not in data:
|
|
||||||
try:
|
|
||||||
search += " " + words[i]
|
|
||||||
i += 1
|
|
||||||
except:
|
|
||||||
logThis("It wasn't. "+search+" doesn't exist")
|
|
||||||
return search + " doesn't exist"
|
|
||||||
if search[0] == " ":
|
|
||||||
search = search[1:]
|
|
||||||
logThis("Yeah! Did that! The key was "+search)
|
|
||||||
|
|
||||||
cmd = cmd[len(search):]
|
def characterSheet(self,character : dict):
|
||||||
if cmd != "":
|
logThis("Setting up a character sheet for "+character["Name"])
|
||||||
|
divider = "--------------------\n"
|
||||||
|
name = character["Name"]
|
||||||
|
textf = ""
|
||||||
|
if character["Force-rating"] != 0:
|
||||||
|
textf = "\n**Force Rating**: "+str(character["Force-rating"])
|
||||||
|
|
||||||
|
text1 = "**Species**: "+character["Species"]+"\n**Career**: "+character["Career"]+"\n**Specialization Trees**: "+", ".join(character["Specialization-trees"])+textf+"\n**Soak**: "+str(character["Soak"])
|
||||||
|
text2 = "\n\n**Wounds**: "+str(character["Wounds"])+"/"+str(character["Wound-threshold"])+"\n**Strain**: "+str(character["Strain"])+"/"+str(character["Strain-threshold"])
|
||||||
|
text3 = self.setUpDict(character["Characteristics"])
|
||||||
|
text4 = self.setUpDict(character["Skills"])
|
||||||
|
text5 = ""
|
||||||
|
text6 = ""
|
||||||
|
text7 = ""
|
||||||
|
text8 = ""
|
||||||
|
|
||||||
|
if bool(character["Talents"]):
|
||||||
|
text5 = "**Talents**: "+", ".join(list(character["Talents"]))+"\n\n"
|
||||||
|
|
||||||
|
if bool(character["Force-powers"]):
|
||||||
|
text6 = "**Force Powers**: "+", ".join(list(character["Force-powers"]))+"\n\n"
|
||||||
|
|
||||||
|
text7 = "**Equipment**: "+", ".join(character["Equipment"])+"\n**Credits**: "+str(character["Credits"])+"\n**Weapons**: "+", ".join(list(character["Weapons"]))+"\n"+divider
|
||||||
|
|
||||||
|
if bool(character["Obligations"]):
|
||||||
|
text8 = "**Obligations**: "+",".join(list(character["Obligations"]))
|
||||||
|
|
||||||
|
return name, text1+text2+"\n\n"+text3+divider+text4+"\n"+divider+text5+text6+text7+text8
|
||||||
|
|
||||||
|
def charData(self,user : str,cmd : str):
|
||||||
|
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
|
||||||
|
|
||||||
|
key = string.capwords(cmd.split(" ")[0])
|
||||||
|
cmd = cmd[len(key):]
|
||||||
|
if cmd == " ":
|
||||||
|
cmd = ""
|
||||||
|
elif cmd != "":
|
||||||
while cmd[0] == " ":
|
while cmd[0] == " ":
|
||||||
cmd = cmd[1:]
|
cmd = cmd[1:]
|
||||||
if cmd == "":
|
if cmd == "":
|
||||||
break
|
break
|
||||||
|
|
||||||
if cmd == "":
|
logThis("Looking for "+self.bot.funcs.getName(user)+"'s character")
|
||||||
logThis("Returning "+search)
|
if userCharacter != None:
|
||||||
return setUpDict(data[search])
|
logThis("Foundt it! Looking for "+key+" in the data")
|
||||||
else:
|
if key in userCharacter:
|
||||||
newKey = cmd.split(" ")[0]
|
logThis("Found it!")
|
||||||
cmd = cmd[len(newKey):]
|
if type(userCharacter[key]) is dict:
|
||||||
if cmd != "":
|
logThis("It's a dictionary!")
|
||||||
while cmd[0] == " ":
|
|
||||||
cmd = cmd[1:]
|
|
||||||
if cmd == "":
|
if cmd == "":
|
||||||
break
|
logThis("Retrieving data")
|
||||||
lookUpResult = lookUp(data[search],newKey,cmd)
|
if key == "Weapons":
|
||||||
if type(lookUpResult) is dict:
|
if bool(userCharacter[key]):
|
||||||
data[search] = lookUpResult
|
logThis("Returning a list of weapons")
|
||||||
return data
|
return ", ".join(list(userCharacter[key]))
|
||||||
else:
|
else:
|
||||||
return lookUpResult
|
logThis("The character doesn't have any weapons. Which is probably for the best. Like, who just walks around with weapons? (error code 941)")
|
||||||
|
return "There doesn't seem to be anything there... (error code 941)"
|
||||||
def characterSheet(character : dict):
|
|
||||||
logThis("Setting up a character sheet for "+character["Name"])
|
|
||||||
divider = "--------------------\n"
|
|
||||||
name = character["Name"]
|
|
||||||
textf = ""
|
|
||||||
if character["Force-rating"] != 0:
|
|
||||||
textf = "\n**Force Rating**: "+str(character["Force-rating"])
|
|
||||||
|
|
||||||
text1 = "**Species**: "+character["Species"]+"\n**Career**: "+character["Career"]+"\n**Specialization Trees**: "+", ".join(character["Specialization-trees"])+textf+"\n**Soak**: "+str(character["Soak"])
|
|
||||||
text2 = "\n\n**Wounds**: "+str(character["Wounds"])+"/"+str(character["Wound-threshold"])+"\n**Strain**: "+str(character["Strain"])+"/"+str(character["Strain-threshold"])
|
|
||||||
text3 = setUpDict(character["Characteristics"])
|
|
||||||
text4 = setUpDict(character["Skills"])
|
|
||||||
text5 = ""
|
|
||||||
text6 = ""
|
|
||||||
text7 = ""
|
|
||||||
text8 = ""
|
|
||||||
|
|
||||||
if bool(character["Talents"]):
|
|
||||||
text5 = "**Talents**: "+", ".join(list(character["Talents"]))+"\n\n"
|
|
||||||
|
|
||||||
if bool(character["Force-powers"]):
|
|
||||||
text6 = "**Force Powers**: "+", ".join(list(character["Force-powers"]))+"\n\n"
|
|
||||||
|
|
||||||
text7 = "**Equipment**: "+", ".join(character["Equipment"])+"\n**Credits**: "+str(character["Credits"])+"\n**Weapons**: "+", ".join(list(character["Weapons"]))+"\n"+divider
|
|
||||||
|
|
||||||
if bool(character["Obligations"]):
|
|
||||||
text8 = "**Obligations**: "+",".join(list(character["Obligations"]))
|
|
||||||
|
|
||||||
return name, text1+text2+"\n\n"+text3+divider+text4+"\n"+divider+text5+text6+text7+text8
|
|
||||||
|
|
||||||
def charData(user : str,cmd : str):
|
|
||||||
with open("resources/starWars/swcharacters.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
key = string.capwords(cmd.split(" ")[0])
|
|
||||||
cmd = cmd[len(key):]
|
|
||||||
if cmd == " ":
|
|
||||||
cmd = ""
|
|
||||||
elif cmd != "":
|
|
||||||
while cmd[0] == " ":
|
|
||||||
cmd = cmd[1:]
|
|
||||||
if cmd == "":
|
|
||||||
break
|
|
||||||
|
|
||||||
logThis("Looking for "+getName(user)+"'s character")
|
|
||||||
if user in data:
|
|
||||||
logThis("Foundt it! Looking for "+key+" in the data")
|
|
||||||
if key in data[user]:
|
|
||||||
logThis("Found it!")
|
|
||||||
if type(data[user][key]) is dict:
|
|
||||||
logThis("It's a dictionary!")
|
|
||||||
if cmd == "":
|
|
||||||
logThis("Retrieving data")
|
|
||||||
if key == "Weapons":
|
|
||||||
if bool(data[user][key]):
|
|
||||||
logThis("Returning a list of weapons")
|
|
||||||
return ", ".join(list(data[user][key]))
|
|
||||||
else:
|
else:
|
||||||
logThis("The character doesn't have any weapons. Which is probably for the best. Like, who just walks around with weapons? (error code 941)")
|
return self.setUpDict(userCharacter[key])
|
||||||
return "There doesn't seem to be anything there... (error code 941)"
|
elif cmd[0] == "+":
|
||||||
else:
|
logThis("Gonna add something!!!")
|
||||||
return setUpDict(data[user][key])
|
|
||||||
elif cmd[0] == "+":
|
|
||||||
logThis("Gonna add something!!!")
|
|
||||||
try:
|
|
||||||
cmd = cmd[1:]
|
|
||||||
while cmd[0] == ' ':
|
|
||||||
cmd = cmd[1:]
|
|
||||||
except:
|
|
||||||
logThis("Nope. That didn't happen (error code 942)")
|
|
||||||
return "Can't do that (error code 942)"
|
|
||||||
|
|
||||||
if (key == "Talents" or key == "Force-powers") and "," in cmd:
|
|
||||||
cmd = cmd.split(",")
|
|
||||||
while cmd[1][0] == " ":
|
|
||||||
cmd[1] = cmd[1][1:]
|
|
||||||
logThis("Adding "+cmd[0]+" to "+key)
|
|
||||||
data[user][key][cmd[0]] = cmd[1]
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return cmd[0]+" added to "+key+" for " + data[user]["Name"]
|
|
||||||
|
|
||||||
elif key == "Obligations" and "," in cmd:
|
|
||||||
cmd = cmd.split(",")
|
|
||||||
while cmd[1][0] == " ":
|
|
||||||
cmd[1] = cmd[1][1:]
|
|
||||||
logThis("Adding "+cmd[0]+" to "+key)
|
|
||||||
try:
|
try:
|
||||||
data[user][key][cmd[0]] = int(cmd[1])
|
cmd = cmd[1:]
|
||||||
|
while cmd[0] == ' ':
|
||||||
|
cmd = cmd[1:]
|
||||||
except:
|
except:
|
||||||
logThis("Fucked that up (error code 949)")
|
logThis("Nope. That didn't happen (error code 942)")
|
||||||
return "Wrong data type (error code 949)"
|
return "Can't do that (error code 942)"
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return cmd[0]+" added to "+key+" for " + data[user]["Name"]
|
|
||||||
|
|
||||||
elif key == "Weapons":
|
|
||||||
with open("resources/starWars/swtemplates.json", "r") as f:
|
|
||||||
templates = json.load(f)
|
|
||||||
newWeapon = templates["Weapon"]
|
|
||||||
logThis("Adding "+cmd+" to "+key)
|
|
||||||
data[user][key][cmd] = newWeapon
|
|
||||||
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
if (key == "Talents" or key == "Force-powers") and "," in cmd:
|
||||||
json.dump(data,f,indent = 4)
|
cmd = cmd.split(",")
|
||||||
return cmd+" added to weapons for " + data[user]["Name"]
|
while cmd[1][0] == " ":
|
||||||
|
cmd[1] = cmd[1][1:]
|
||||||
else:
|
logThis("Adding "+cmd[0]+" to "+key)
|
||||||
logThis("That's not happening (error code 947d)")
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
return "Can't add that (error code 947d)"
|
{"$set": {key+"."+cmd[0] : cmd[1]}})
|
||||||
|
return cmd[0]+" added to "+key+" for " + userCharacter["Name"]
|
||||||
|
|
||||||
elif cmd[0] == "-":
|
elif key == "Obligations" and "," in cmd:
|
||||||
logThis("Gonna subtract/remove something")
|
cmd = cmd.split(",")
|
||||||
try:
|
while cmd[1][0] == " ":
|
||||||
cmd = cmd[1:]
|
cmd[1] = cmd[1][1:]
|
||||||
while cmd[0] == ' ':
|
logThis("Adding "+cmd[0]+" to "+key)
|
||||||
cmd = cmd[1:]
|
|
||||||
except:
|
|
||||||
logThis("AAAAAAAAAAAA (error code 948)")
|
|
||||||
return "Can't do that (error code 948)"
|
|
||||||
|
|
||||||
if key == "Talents" or key == "Force-powers" or key == "Weapons" or key == "Obligations":
|
|
||||||
logThis("Trying to remove "+cmd+" from "+key)
|
|
||||||
if cmd in data[user][key]:
|
|
||||||
del data[user][key][cmd]
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
logThis("I did that")
|
|
||||||
return cmd+" removed from "+key+" from "+data[user]["Name"]
|
|
||||||
else:
|
|
||||||
logThis("Welp. I fucked that up (error code 946e)")
|
|
||||||
return "Can't remove that (error code 946e)"
|
|
||||||
else:
|
|
||||||
logThis("Urgh! (error code 946d)")
|
|
||||||
return "Can't remove that (error code 946d)"
|
|
||||||
|
|
||||||
else:
|
|
||||||
logThis("Looking up "+cmd+" in "+key)
|
|
||||||
if key == "Talents" or key == "Force-powers":
|
|
||||||
newKey = cmd
|
|
||||||
newcmd = ""
|
|
||||||
else:
|
|
||||||
newKey = string.capwords(cmd.split(" ")[0])
|
|
||||||
newcmd = cmd[len(newKey):]
|
|
||||||
|
|
||||||
lookUpResult = lookUp(data[user][key],newKey,newcmd)
|
|
||||||
|
|
||||||
if type(lookUpResult) is dict:
|
|
||||||
data[user][key] = lookUpResult
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return "Changed " + data[user]["Name"] + "'s " + key
|
|
||||||
else:
|
|
||||||
return lookUpResult
|
|
||||||
else:
|
|
||||||
if cmd == "":
|
|
||||||
logThis("Retrieving data")
|
|
||||||
if type(data[user][key]) is list:
|
|
||||||
return key+":\n"+", ".join(data[user][key])
|
|
||||||
else:
|
|
||||||
return data[user][key]
|
|
||||||
elif cmd[0] == '+':
|
|
||||||
logThis("Adding")
|
|
||||||
try:
|
|
||||||
cmd = cmd[1:]
|
|
||||||
while cmd[0] == ' ':
|
|
||||||
cmd = cmd[1:]
|
|
||||||
except:
|
|
||||||
logThis("Error message (error code 948)")
|
|
||||||
return "Can't do that (error code 948)"
|
|
||||||
|
|
||||||
if type(data[user][key]) is int:
|
|
||||||
try:
|
|
||||||
logThis("Adding "+cmd+" to "+key)
|
|
||||||
beforeData = data[user][key]
|
|
||||||
data[user][key] = beforeData+ int(cmd)
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return "Added " + cmd + " to " + data[user]["Name"] + "'s " + key
|
|
||||||
except:
|
|
||||||
logThis("BITCH SANDWICH (error code 947c)")
|
|
||||||
return "Can't add that (error code 947c)"
|
|
||||||
elif type(data[user][key]) is list:
|
|
||||||
try:
|
|
||||||
logThis("Adding "+cmd+" to "+key)
|
|
||||||
data[user][key].append(cmd)
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return "Added " + cmd + " to " + data[user]["Name"] + "'s " + key
|
|
||||||
except:
|
|
||||||
logThis("tstststststs (error code 947b)")
|
|
||||||
return "Can't add that (error code 947b)"
|
|
||||||
else:
|
|
||||||
logThis("Help (error code 947a)")
|
|
||||||
return "Can't add that (error code 947a)"
|
|
||||||
elif cmd[0] == '-':
|
|
||||||
logThis("Removing/subtracting")
|
|
||||||
try:
|
|
||||||
cmd = cmd[1:]
|
|
||||||
while cmd[0] == ' ':
|
|
||||||
cmd = cmd[1:]
|
|
||||||
except:
|
|
||||||
logThis("lalalala (error code 948)")
|
|
||||||
return "Can't do that (error code 948)"
|
|
||||||
|
|
||||||
if type(data[user][key]) is int:
|
|
||||||
try:
|
|
||||||
logThis("Subtracting "+cmd+" from "+key)
|
|
||||||
beforeData = data[user][key]
|
|
||||||
data[user][key] = beforeData - int(cmd)
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return "Subtracted " + cmd + " from " + data[user]["Name"] + "'s " + key
|
|
||||||
except:
|
|
||||||
logThis("Tried it. Didn't want to (error code 946c)")
|
|
||||||
return "Can't remove that (error code 946c)"
|
|
||||||
elif type(data[user][key]) is list:
|
|
||||||
try:
|
|
||||||
logThis("removing "+cmd+" from "+key)
|
|
||||||
beforeData = data[user][key]
|
|
||||||
try:
|
try:
|
||||||
data[user][key].remove(cmd)
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$set": {key+"."+cmd[0] : int(cmd[1])}})
|
||||||
except:
|
except:
|
||||||
logThis("They can only remove stuff that's actually in the list")
|
logThis("Fucked that up (error code 949)")
|
||||||
return "Not in list (error code 944b)"
|
return "Wrong data type (error code 949)"
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
return cmd[0]+" added to "+key+" for " + userCharacter["Name"]
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return "Removed " + cmd + " from " + data[user]["Name"] + "'s " + key
|
elif key == "Weapons":
|
||||||
except:
|
with open("resources/starWars/swtemplates.json", "r") as f:
|
||||||
logThis("nah (error code 946b)")
|
templates = json.load(f)
|
||||||
return "Can't remove that (error code 946b)"
|
newWeapon = templates["Weapon"]
|
||||||
else:
|
logThis("Adding "+cmd+" to "+key)
|
||||||
logThis("nyope (error code 946a)")
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
return "Can't remove that (error code 946a)"
|
{"$set": {key+"."+cmd : newWeapon}})
|
||||||
else:
|
|
||||||
logThis("Changing "+key+" to "+cmd)
|
return cmd+" added to weapons for " + userCharacter["Name"]
|
||||||
if type(data[user][key]) is int:
|
|
||||||
|
else:
|
||||||
|
logThis("That's not happening (error code 947d)")
|
||||||
|
return "Can't add that (error code 947d)"
|
||||||
|
|
||||||
|
elif cmd[0] == "-":
|
||||||
|
logThis("Gonna subtract/remove something")
|
||||||
try:
|
try:
|
||||||
data[user][key] = int(cmd)
|
cmd = cmd[1:]
|
||||||
|
while cmd[0] == ' ':
|
||||||
|
cmd = cmd[1:]
|
||||||
except:
|
except:
|
||||||
logThis("I don't wanna tho (error code 945b)")
|
logThis("AAAAAAAAAAAA (error code 948)")
|
||||||
return "Can't do that (error code 945b)"
|
return "Can't do that (error code 948)"
|
||||||
elif type(data[user][key]) is str:
|
|
||||||
data[user][key] = cmd
|
if key == "Talents" or key == "Force-powers" or key == "Weapons" or key == "Obligations":
|
||||||
|
logThis("Trying to remove "+cmd+" from "+key)
|
||||||
|
if cmd in userCharacter[key]:
|
||||||
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$unset": {cmd}})
|
||||||
|
logThis("I did that")
|
||||||
|
return cmd+" removed from "+key+" from "+userCharacter["Name"]
|
||||||
|
else:
|
||||||
|
logThis("Welp. I fucked that up (error code 946e)")
|
||||||
|
return "Can't remove that (error code 946e)"
|
||||||
|
else:
|
||||||
|
logThis("Urgh! (error code 946d)")
|
||||||
|
return "Can't remove that (error code 946d)"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logThis("I don't wanna tho (error code 945a)")
|
logThis("Looking up "+cmd+" in "+key)
|
||||||
return "Can't do that (error code 945a)"
|
if key == "Talents" or key == "Force-powers":
|
||||||
|
newKey = cmd
|
||||||
|
newcmd = ""
|
||||||
|
else:
|
||||||
|
newKey = string.capwords(cmd.split(" ")[0])
|
||||||
|
newcmd = cmd[len(newKey):]
|
||||||
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
lookUpResult = self.lookUp(userCharacter[key],newKey,newcmd)
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return "Changed " + data[user]["Name"] + "'s " + key +" to " + cmd
|
if type(lookUpResult) is dict:
|
||||||
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$set": {key : lookUpResult}})
|
||||||
|
return "Changed " + userCharacter["Name"] + "'s " + key
|
||||||
|
else:
|
||||||
|
return lookUpResult
|
||||||
|
else:
|
||||||
|
if cmd == "":
|
||||||
|
logThis("Retrieving data")
|
||||||
|
if type(userCharacter[key]) is list:
|
||||||
|
return key+":\n"+", ".join(userCharacter[key])
|
||||||
|
else:
|
||||||
|
return userCharacter[key]
|
||||||
|
elif cmd[0] == '+':
|
||||||
|
logThis("Adding")
|
||||||
|
try:
|
||||||
|
cmd = cmd[1:]
|
||||||
|
while cmd[0] == ' ':
|
||||||
|
cmd = cmd[1:]
|
||||||
|
except:
|
||||||
|
logThis("Error message (error code 948)")
|
||||||
|
return "Can't do that (error code 948)"
|
||||||
|
|
||||||
|
if type(userCharacter[key]) is int:
|
||||||
|
try:
|
||||||
|
logThis("Adding "+cmd+" to "+key)
|
||||||
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$inc": {key : int(cmd)}})
|
||||||
|
return "Added " + cmd + " to " + userCharacter["Name"] + "'s " + key
|
||||||
|
except:
|
||||||
|
logThis("BITCH SANDWICH (error code 947c)")
|
||||||
|
return "Can't add that (error code 947c)"
|
||||||
|
elif type(userCharacter[key]) is list:
|
||||||
|
try:
|
||||||
|
logThis("Adding "+cmd+" to "+key)
|
||||||
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$push": {key : cmd}})
|
||||||
|
return "Added " + cmd + " to " + userCharacter["Name"] + "'s " + key
|
||||||
|
except:
|
||||||
|
logThis("tstststststs (error code 947b)")
|
||||||
|
return "Can't add that (error code 947b)"
|
||||||
|
else:
|
||||||
|
logThis("Help (error code 947a)")
|
||||||
|
return "Can't add that (error code 947a)"
|
||||||
|
elif cmd[0] == '-':
|
||||||
|
logThis("Removing/subtracting")
|
||||||
|
try:
|
||||||
|
cmd = cmd[1:]
|
||||||
|
while cmd[0] == ' ':
|
||||||
|
cmd = cmd[1:]
|
||||||
|
except:
|
||||||
|
logThis("lalalala (error code 948)")
|
||||||
|
return "Can't do that (error code 948)"
|
||||||
|
|
||||||
|
if type(userCharacter[key]) is int:
|
||||||
|
try:
|
||||||
|
logThis("Subtracting "+cmd+" from "+key)
|
||||||
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$inc": {key : -int(cmd)}})
|
||||||
|
return "Subtracted " + cmd + " from " + userCharacter["Name"] + "'s " + key
|
||||||
|
except:
|
||||||
|
logThis("Tried it. Didn't want to (error code 946c)")
|
||||||
|
return "Can't remove that (error code 946c)"
|
||||||
|
elif type(userCharacter[key]) is list:
|
||||||
|
try:
|
||||||
|
logThis("removing "+cmd+" from "+key)
|
||||||
|
try:
|
||||||
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$pull": {key : cmd}})
|
||||||
|
except:
|
||||||
|
logThis("They can only remove stuff that's actually in the list")
|
||||||
|
return "Not in list (error code 944b)"
|
||||||
|
return "Removed " + cmd + " from " + userCharacter["Name"] + "'s " + key
|
||||||
|
except:
|
||||||
|
logThis("nah (error code 946b)")
|
||||||
|
return "Can't remove that (error code 946b)"
|
||||||
|
else:
|
||||||
|
logThis("nyope (error code 946a)")
|
||||||
|
return "Can't remove that (error code 946a)"
|
||||||
|
else:
|
||||||
|
logThis("Changing "+key+" to "+cmd)
|
||||||
|
if type(userCharacter[key]) is int:
|
||||||
|
try:
|
||||||
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$set": {key : int(cmd)}})
|
||||||
|
except:
|
||||||
|
logThis("I don't wanna tho (error code 945b)")
|
||||||
|
return "Can't do that (error code 945b)"
|
||||||
|
elif type(userCharacter[key]) is str:
|
||||||
|
self.bot.database["swcharacters"].update_one({"_id":user},
|
||||||
|
{"$set": {key : cmd}})
|
||||||
|
else:
|
||||||
|
logThis("I don't wanna tho (error code 945a)")
|
||||||
|
return "Can't do that (error code 945a)"
|
||||||
|
return "Changed " + userCharacter["Name"] + "'s " + key +" to " + cmd
|
||||||
|
else:
|
||||||
|
logThis(key+" isn't in there (error code 944)")
|
||||||
|
return "Couldn't find that data. Are you sure you spelled it correctly? (error code 944)"
|
||||||
else:
|
else:
|
||||||
logThis(key+" isn't in there (error code 944)")
|
logThis(user+" doesn't have a character (error code 943)")
|
||||||
return "Couldn't find that data. Are you sure you spelled it correctly? (error code 944)"
|
return "You don't have a character. You can make one with !swchar (error code 943)"
|
||||||
else:
|
|
||||||
logThis(user+" doesn't have a character (error code 943)")
|
|
||||||
return "You don't have a character. You can make one with !swchar (error code 943)"
|
|
||||||
|
|
||||||
def replaceSpaces(cmd : str):
|
def replaceSpaces(self,cmd : str):
|
||||||
withSpaces = ["Specialization Trees","Wound Threshold","Strain Threshold","Defense - Ranged","Defense - Melee","Force Rating","Core Worlds","Outer Rim","Piloting - Planetary","Piloting - Space","Ranged - Heavy","Ranged - Light","Lightsaber Characteristic","Critical Injuries","Force Powers"]
|
withSpaces = ["Specialization Trees","Wound Threshold","Strain Threshold","Defense - Ranged","Defense - Melee","Force Rating","Core Worlds","Outer Rim","Piloting - Planetary","Piloting - Space","Ranged - Heavy","Ranged - Light","Lightsaber Characteristic","Critical Injuries","Force Powers"]
|
||||||
withoutSpaces = ["Specialization-trees","Wound-threshold","Strain-threshold","Defense-ranged","Defense-melee","Force-rating","Core-worlds","Outer-rim","Piloting-planetary","Piloting-space","Ranged-heavy","Ranged-light","Lightsaber-characteristic","Critical-injuries","Force-powers"]
|
withoutSpaces = ["Specialization-trees","Wound-threshold","Strain-threshold","Defense-ranged","Defense-melee","Force-rating","Core-worlds","Outer-rim","Piloting-planetary","Piloting-space","Ranged-heavy","Ranged-light","Lightsaber-characteristic","Critical-injuries","Force-powers"]
|
||||||
|
|
||||||
for x in range(len(withoutSpaces)):
|
for x in range(len(withoutSpaces)):
|
||||||
cmd = cmd.replace(withSpaces[x],withoutSpaces[x])
|
cmd = cmd.replace(withSpaces[x],withoutSpaces[x])
|
||||||
|
|
||||||
return cmd
|
|
||||||
|
|
||||||
def replaceWithSpaces(cmd : str):
|
return cmd
|
||||||
withSpaces = ["Specialization Trees","Wound Threshold","Strain Threshold","Defense - Ranged","Defense - Melee","Force Rating","Core Worlds","Outer Rim","Piloting - Planetary","Piloting - Space","Ranged - Heavy","Ranged - light","Lightsaber Characteristic","Critical Injuries","Force Powers"]
|
|
||||||
withoutSpaces = ["Specialization-trees","Wound-threshold","Strain-threshold","Defense-ranged","Defense-melee","Force-rating","Core-worlds","Outer-rim","Piloting-planetary","Piloting-space","Ranged-heavy","Ranged-light","Lightsaber-characteristic","Critical-injuries","Force-powers"]
|
|
||||||
|
|
||||||
for x in range(len(withoutSpaces)):
|
def replaceWithSpaces(self,cmd : str):
|
||||||
cmd = cmd.replace(withoutSpaces[x],withSpaces[x])
|
withSpaces = ["Specialization Trees","Wound Threshold","Strain Threshold","Defense - Ranged","Defense - Melee","Force Rating","Core Worlds","Outer Rim","Piloting - Planetary","Piloting - Space","Ranged - Heavy","Ranged - light","Lightsaber Characteristic","Critical Injuries","Force Powers"]
|
||||||
|
withoutSpaces = ["Specialization-trees","Wound-threshold","Strain-threshold","Defense-ranged","Defense-melee","Force-rating","Core-worlds","Outer-rim","Piloting-planetary","Piloting-space","Ranged-heavy","Ranged-light","Lightsaber-characteristic","Critical-injuries","Force-powers"]
|
||||||
return cmd
|
|
||||||
|
|
||||||
def parseChar(user : str, cmd : str):
|
for x in range(len(withoutSpaces)):
|
||||||
|
cmd = cmd.replace(withoutSpaces[x],withSpaces[x])
|
||||||
|
|
||||||
cmd = replaceSpaces(cmd)
|
return cmd
|
||||||
|
|
||||||
with open("resources/starWars/swcharacters.json", "r") as f:
|
def parseChar(self,user : str, cmd : str):
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if cmd == " ":
|
cmd = self.replaceSpaces(cmd)
|
||||||
cmd = ""
|
|
||||||
elif cmd != "":
|
|
||||||
while cmd[0] == " ":
|
|
||||||
cmd = cmd[1:]
|
|
||||||
if cmd == "":
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
if cmd == "":
|
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
|
||||||
if user in data:
|
|
||||||
text1, text2 = characterSheet(data[user])
|
if cmd == " ":
|
||||||
return text1, replaceWithSpaces(text2)
|
cmd = ""
|
||||||
|
elif cmd != "":
|
||||||
|
while cmd[0] == " ":
|
||||||
|
cmd = cmd[1:]
|
||||||
|
if cmd == "":
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if cmd == "":
|
||||||
|
if userCharacter != None:
|
||||||
|
text1, text2 = self.characterSheet(userCharacter)
|
||||||
|
return text1, self.replaceWithSpaces(text2)
|
||||||
|
else:
|
||||||
|
logThis("Makin' a character for "+self.bot.funcs.getName(user))
|
||||||
|
with open("resources/starWars/swtemplates.json", "r") as f:
|
||||||
|
templates = json.load(f)
|
||||||
|
newChar = templates["Character"]
|
||||||
|
print("yeet")
|
||||||
|
newChar["_id"] = user
|
||||||
|
print("yeet")
|
||||||
|
self.bot.database["swcharacters"].insert_one(newChar)
|
||||||
|
print("yeet")
|
||||||
|
return "", "Character for " + self.bot.funcs.getName(user) + " created"
|
||||||
else:
|
else:
|
||||||
logThis("Makin' a character for "+getName(user))
|
if cmd == "Purge":
|
||||||
with open("resources/starWars/swtemplates.json", "r") as f:
|
logThis("Deleting "+self.bot.funcs.getName(user)+"'s character")
|
||||||
templates = json.load(f)
|
self.bot.database["swcharacters"].remove_one({newChar})
|
||||||
newChar = templates["Character"]
|
return "", "Character for " + self.bot.funcs.getName(user) + " deleted"
|
||||||
data[user] = newChar
|
else:
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
return "", self.replaceWithSpaces(str(self.charData(user,cmd)))
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return "", "Character for " + getName(user) + " created"
|
|
||||||
else:
|
|
||||||
if cmd == "Purge":
|
|
||||||
logThis("Deleting "+getName(user)+"'s character")
|
|
||||||
del data[user]
|
|
||||||
with open("resources/starWars/swcharacters.json", "w") as f:
|
|
||||||
json.dump(data,f,indent = 4)
|
|
||||||
return "", "Character for " + getName(user) + " deleted"
|
|
||||||
else:
|
|
||||||
return "", replaceWithSpaces(str(charData(user,cmd)))
|
|
||||||
|
|
||||||
def lightsaberChar(user : str):
|
def lightsaberChar(self,user : str):
|
||||||
with open("resources/starWars/swcharacters.json", "r") as f:
|
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
if user in data:
|
if userCharacter != None:
|
||||||
return data[user]["Lightsaber-characteristic"]
|
return userCharacter["Lightsaber-characteristic"]
|
||||||
|
|
||||||
def userHasChar(user : str):
|
def userHasChar(self,user : str):
|
||||||
with open("resources/starWars/swcharacters.json", "r") as f:
|
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
return user in data
|
return userCharacter != None
|
||||||
|
|
||||||
|
@ -1,66 +1,68 @@
|
|||||||
from . import swroll
|
|
||||||
|
|
||||||
from funcs import logThis
|
from funcs import logThis
|
||||||
|
|
||||||
def destinyNew(num : int):
|
class SwDestiny():
|
||||||
logThis("Creating a new destiny pool with "+str(num)+" players")
|
def __init__(self, bot):
|
||||||
roll, diceResults = swroll.roll(0,0,0,0,0,0,num)
|
self.bot = bot
|
||||||
roll = "".join(sorted(roll))
|
|
||||||
|
|
||||||
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
|
||||||
f.write(roll)
|
|
||||||
|
|
||||||
return "Rolled for Destiny Points and got:\n"+swroll.diceResultToEmoji(diceResults)+"\n"+swroll.resultToEmoji(roll)
|
|
||||||
|
|
||||||
def destinyUse(user : str):
|
def destinyNew(self, num : int):
|
||||||
with open("resources/starWars/destinyPoints.txt","rt") as f:
|
logThis("Creating a new destiny pool with "+str(num)+" players")
|
||||||
points = f.read()
|
roll, diceResults = self.bot.swroll.roll(0,0,0,0,0,0,num)
|
||||||
|
roll = "".join(sorted(roll))
|
||||||
if user == "Nikolaj":
|
|
||||||
logThis("Trying to use a dark side destiny point")
|
|
||||||
if 'B' in points:
|
|
||||||
points = points.replace("B","L",1)
|
|
||||||
points = "".join(sorted(points))
|
|
||||||
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
|
||||||
f.write(points)
|
|
||||||
logThis("Did it")
|
|
||||||
return "Used a dark side destiny point. Destiny pool is now:\n"+swroll.resultToEmoji(points)
|
|
||||||
else:
|
|
||||||
logThis("There were no dark side destiny points")
|
|
||||||
return "No dark side destiny points"
|
|
||||||
else:
|
|
||||||
logThis("Trying to use a light side destiny point")
|
|
||||||
if 'L' in points:
|
|
||||||
points = points.replace("L","B",1)
|
|
||||||
points = "".join(sorted(points))
|
|
||||||
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
|
||||||
f.write(points)
|
|
||||||
logThis("Did it")
|
|
||||||
return "Used a light side destiny point. Destiny pool is now:\n"+swroll.resultToEmoji(points)
|
|
||||||
else:
|
|
||||||
logThis("There were no dark side destiny points")
|
|
||||||
return "No light side destiny points"
|
|
||||||
|
|
||||||
def parseDestiny(user : str, cmd : str):
|
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
||||||
if cmd != "":
|
f.write(roll)
|
||||||
while cmd[0] == ' ':
|
|
||||||
cmd = cmd[1:]
|
return "Rolled for Destiny Points and got:\n"+self.bot.swroll.diceResultToEmoji(diceResults)+"\n"+self.bot.swroll.resultToEmoji(roll)
|
||||||
if cmd == "":
|
|
||||||
break
|
def destinyUse(self, user : str):
|
||||||
|
|
||||||
|
|
||||||
if cmd == "":
|
|
||||||
logThis("Retrieving destiny pool info")
|
|
||||||
with open("resources/starWars/destinyPoints.txt","rt") as f:
|
with open("resources/starWars/destinyPoints.txt","rt") as f:
|
||||||
return swroll.resultToEmoji(f.read())
|
points = f.read()
|
||||||
else:
|
|
||||||
commands = cmd.upper().split(" ")
|
if user == "Nikolaj":
|
||||||
if commands[0] == "N":
|
logThis("Trying to use a dark side destiny point")
|
||||||
if len(commands) > 1:
|
if 'B' in points:
|
||||||
return destinyNew(int(commands[1]))
|
points = points.replace("B","L",1)
|
||||||
|
points = "".join(sorted(points))
|
||||||
|
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
||||||
|
f.write(points)
|
||||||
|
logThis("Did it")
|
||||||
|
return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.swroll.resultToEmoji(points)
|
||||||
else:
|
else:
|
||||||
return "You need to give an amount of players (error code 921)"
|
logThis("There were no dark side destiny points")
|
||||||
elif commands[0] == "U":
|
return "No dark side destiny points"
|
||||||
return destinyUse(user)
|
|
||||||
else:
|
else:
|
||||||
return "I didn't quite understand that (error code 922)"
|
logThis("Trying to use a light side destiny point")
|
||||||
|
if 'L' in points:
|
||||||
|
points = points.replace("L","B",1)
|
||||||
|
points = "".join(sorted(points))
|
||||||
|
with open("resources/starWars/destinyPoints.txt","wt") as f:
|
||||||
|
f.write(points)
|
||||||
|
logThis("Did it")
|
||||||
|
return "Used a light side destiny point. Destiny pool is now:\n"+self.bot.swroll.resultToEmoji(points)
|
||||||
|
else:
|
||||||
|
logThis("There were no dark side destiny points")
|
||||||
|
return "No light side destiny points"
|
||||||
|
|
||||||
|
def parseDestiny(self, user : str, cmd : str):
|
||||||
|
if cmd != "":
|
||||||
|
while cmd[0] == ' ':
|
||||||
|
cmd = cmd[1:]
|
||||||
|
if cmd == "":
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if cmd == "":
|
||||||
|
logThis("Retrieving destiny pool info")
|
||||||
|
with open("resources/starWars/destinyPoints.txt","rt") as f:
|
||||||
|
return self.bot.swroll.resultToEmoji(f.read())
|
||||||
|
else:
|
||||||
|
commands = cmd.upper().split(" ")
|
||||||
|
if commands[0] == "N":
|
||||||
|
if len(commands) > 1:
|
||||||
|
return self.destinyNew(int(commands[1]))
|
||||||
|
else:
|
||||||
|
return "You need to give an amount of players (error code 921)"
|
||||||
|
elif commands[0] == "U":
|
||||||
|
return self.destinyUse(user)
|
||||||
|
else:
|
||||||
|
return "I didn't quite understand that (error code 922)"
|
||||||
|
@ -3,376 +3,378 @@ import re
|
|||||||
import string
|
import string
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from . import swchar
|
|
||||||
from funcs import logThis
|
from funcs import logThis
|
||||||
|
|
||||||
with open("resources/starWars/swskills.json", "r") as f:
|
with open("resources/starWars/swskills.json", "r") as f:
|
||||||
skillData = json.load(f)
|
skillData = json.load(f)
|
||||||
|
|
||||||
# Rolls the specified dice
|
class SwRoll():
|
||||||
def roll(abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int = 0, setb : int = 0, force : int = 0):
|
def __init__(self, bot):
|
||||||
result = ""
|
self.bot = bot
|
||||||
diceResult = []
|
|
||||||
for x in range(abi):
|
|
||||||
choice = random.choice(["","S","S","SS","A","A","SA","AA"])
|
|
||||||
result += choice
|
|
||||||
diceResult.append("abi"+choice)
|
|
||||||
|
|
||||||
for x in range(prof):
|
# Rolls the specified dice
|
||||||
choice = random.choice(["","S","S","SS","SS","A","SA","SA","SA","AA","AA","R"])
|
def roll(self, abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int = 0, setb : int = 0, force : int = 0):
|
||||||
result += choice
|
result = ""
|
||||||
diceResult.append("prof"+choice)
|
diceResult = []
|
||||||
|
for x in range(abi):
|
||||||
for x in range(dif):
|
choice = random.choice(["","S","S","SS","A","A","SA","AA"])
|
||||||
choice = random.choice(["","F","FF","H","H","H","HH","FH"])
|
result += choice
|
||||||
result += choice
|
diceResult.append("abi"+choice)
|
||||||
diceResult.append("dif"+choice)
|
|
||||||
|
|
||||||
for x in range(cha):
|
for x in range(prof):
|
||||||
choice = random.choice(["","F","F","FF","FF","H","H","FH","FH","HH","HH","D"])
|
choice = random.choice(["","S","S","SS","SS","A","SA","SA","SA","AA","AA","R"])
|
||||||
result += choice
|
result += choice
|
||||||
diceResult.append("cha"+choice)
|
diceResult.append("prof"+choice)
|
||||||
|
|
||||||
for x in range(boo):
|
|
||||||
choice = random.choice(["","","S","SA","AA","A"])
|
|
||||||
result += choice
|
|
||||||
diceResult.append("boo"+choice)
|
|
||||||
|
|
||||||
for x in range(setb):
|
for x in range(dif):
|
||||||
choice = random.choice(["","","F","F","H","H"])
|
choice = random.choice(["","F","FF","H","H","H","HH","FH"])
|
||||||
result += choice
|
result += choice
|
||||||
diceResult.append("setb"+choice)
|
diceResult.append("dif"+choice)
|
||||||
|
|
||||||
for x in range (force):
|
|
||||||
choice = random.choice(["B","B","B","B","B","B","BB","L","L","LL","LL","LL"])
|
|
||||||
result += choice
|
|
||||||
diceResult.append("force"+choice)
|
|
||||||
|
|
||||||
return result, diceResult
|
for x in range(cha):
|
||||||
|
choice = random.choice(["","F","F","FF","FF","H","H","FH","FH","HH","HH","D"])
|
||||||
|
result += choice
|
||||||
|
diceResult.append("cha"+choice)
|
||||||
|
|
||||||
# Lets dice cancel each other out
|
for x in range(boo):
|
||||||
def simplify(result : str):
|
choice = random.choice(["","","S","SA","AA","A"])
|
||||||
logThis("Simplifying "+result)
|
result += choice
|
||||||
simp = ""
|
diceResult.append("boo"+choice)
|
||||||
success = (result.count('S') + result.count('R')) - (result.count('F') + result.count('D'))
|
|
||||||
advantage = result.count('A') - result.count('H')
|
|
||||||
result = re.sub("S|A|F|H","",result)
|
|
||||||
|
|
||||||
if success > 0:
|
for x in range(setb):
|
||||||
for x in range(success):
|
choice = random.choice(["","","F","F","H","H"])
|
||||||
simp += "S"
|
result += choice
|
||||||
elif success < 0:
|
diceResult.append("setb"+choice)
|
||||||
for x in range(abs(success)):
|
|
||||||
simp += "F"
|
|
||||||
|
|
||||||
if advantage > 0:
|
|
||||||
for x in range(advantage):
|
|
||||||
simp += "A"
|
|
||||||
elif advantage < 0:
|
|
||||||
for x in range(abs(advantage)):
|
|
||||||
simp += "H"
|
|
||||||
|
|
||||||
simp += result
|
|
||||||
|
|
||||||
return simp
|
for x in range (force):
|
||||||
|
choice = random.choice(["B","B","B","B","B","B","BB","L","L","LL","LL","LL"])
|
||||||
|
result += choice
|
||||||
|
diceResult.append("force"+choice)
|
||||||
|
|
||||||
# Returns emoji that symbolize the dice results
|
return result, diceResult
|
||||||
def diceResultToEmoji(diceResults : list):
|
|
||||||
emoji = ""
|
|
||||||
for result in diceResults:
|
|
||||||
if result == "abiA":
|
|
||||||
emoji += "<:abil1a:695267684476125264> "
|
|
||||||
elif result == "abiSA":
|
|
||||||
emoji += "<:abil1a1s:695267684484513842> "
|
|
||||||
elif result == "abiS":
|
|
||||||
emoji += "<:abil1s:695267684514005013> "
|
|
||||||
elif result == "abiAA":
|
|
||||||
emoji += "<:abil2a:695267684547428352> "
|
|
||||||
elif result == "abiSS":
|
|
||||||
emoji += "<:abil2s:695267684761206914> "
|
|
||||||
elif result == "abi":
|
|
||||||
emoji += "<:abilbla:695267684660674602> "
|
|
||||||
|
|
||||||
elif result == "profA":
|
# Lets dice cancel each other out
|
||||||
emoji += "<:prof1a:695267685361123338> "
|
def simplify(self, result : str):
|
||||||
elif result == "profSA":
|
logThis("Simplifying "+result)
|
||||||
emoji += "<:prof1a1s:695267685067653140> "
|
simp = ""
|
||||||
elif result == "profR":
|
success = (result.count('S') + result.count('R')) - (result.count('F') + result.count('D'))
|
||||||
emoji += "<:prof1r:695267685067522088> "
|
advantage = result.count('A') - result.count('H')
|
||||||
elif result == "profS":
|
result = re.sub("S|A|F|H","",result)
|
||||||
emoji += "<:prof1s:695267684899881012> "
|
|
||||||
elif result == "profAA":
|
|
||||||
emoji += "<:prof2a:695267684996218982> "
|
|
||||||
elif result == "profSS":
|
|
||||||
emoji += "<:prof2s:695267684878647327> "
|
|
||||||
elif result == "prof":
|
|
||||||
emoji += "<:profbla:695267684698292235> "
|
|
||||||
|
|
||||||
elif result == "difF":
|
if success > 0:
|
||||||
emoji += "<:dif1f:695267684924915804> "
|
for x in range(success):
|
||||||
elif result == "difH":
|
simp += "S"
|
||||||
emoji += "<:dif1h:695267684908138506> "
|
elif success < 0:
|
||||||
elif result == "difFH":
|
for x in range(abs(success)):
|
||||||
emoji += "<:dif1h1f:695267684908269678> "
|
simp += "F"
|
||||||
elif result == "difFF":
|
|
||||||
emoji += "<:dif2f:695267684924784680> "
|
if advantage > 0:
|
||||||
elif result == "difHH":
|
for x in range(advantage):
|
||||||
emoji += "<:dif2h:695267685071585340> "
|
simp += "A"
|
||||||
elif result == "dif":
|
elif advantage < 0:
|
||||||
emoji += "<:difbla:695267685000544276> "
|
for x in range(abs(advantage)):
|
||||||
|
simp += "H"
|
||||||
|
|
||||||
|
simp += result
|
||||||
|
|
||||||
|
return simp
|
||||||
|
|
||||||
|
# Returns emoji that symbolize the dice results
|
||||||
|
def diceResultToEmoji(self, diceResults : list):
|
||||||
|
emoji = ""
|
||||||
|
for result in diceResults:
|
||||||
|
if result == "abiA":
|
||||||
|
emoji += "<:abil1a:695267684476125264> "
|
||||||
|
elif result == "abiSA":
|
||||||
|
emoji += "<:abil1a1s:695267684484513842> "
|
||||||
|
elif result == "abiS":
|
||||||
|
emoji += "<:abil1s:695267684514005013> "
|
||||||
|
elif result == "abiAA":
|
||||||
|
emoji += "<:abil2a:695267684547428352> "
|
||||||
|
elif result == "abiSS":
|
||||||
|
emoji += "<:abil2s:695267684761206914> "
|
||||||
|
elif result == "abi":
|
||||||
|
emoji += "<:abilbla:695267684660674602> "
|
||||||
|
|
||||||
|
elif result == "profA":
|
||||||
|
emoji += "<:prof1a:695267685361123338> "
|
||||||
|
elif result == "profSA":
|
||||||
|
emoji += "<:prof1a1s:695267685067653140> "
|
||||||
|
elif result == "profR":
|
||||||
|
emoji += "<:prof1r:695267685067522088> "
|
||||||
|
elif result == "profS":
|
||||||
|
emoji += "<:prof1s:695267684899881012> "
|
||||||
|
elif result == "profAA":
|
||||||
|
emoji += "<:prof2a:695267684996218982> "
|
||||||
|
elif result == "profSS":
|
||||||
|
emoji += "<:prof2s:695267684878647327> "
|
||||||
|
elif result == "prof":
|
||||||
|
emoji += "<:profbla:695267684698292235> "
|
||||||
|
|
||||||
|
elif result == "difF":
|
||||||
|
emoji += "<:dif1f:695267684924915804> "
|
||||||
|
elif result == "difH":
|
||||||
|
emoji += "<:dif1h:695267684908138506> "
|
||||||
|
elif result == "difFH":
|
||||||
|
emoji += "<:dif1h1f:695267684908269678> "
|
||||||
|
elif result == "difFF":
|
||||||
|
emoji += "<:dif2f:695267684924784680> "
|
||||||
|
elif result == "difHH":
|
||||||
|
emoji += "<:dif2h:695267685071585340> "
|
||||||
|
elif result == "dif":
|
||||||
|
emoji += "<:difbla:695267685000544276> "
|
||||||
|
|
||||||
|
elif result == "chaD":
|
||||||
|
emoji += "<:cha1d:695267684962533447> "
|
||||||
|
elif result == "chaF":
|
||||||
|
emoji += "<:cha1f:695267684601954346> "
|
||||||
|
elif result == "chaH":
|
||||||
|
emoji += "<:cha1h:695267685046681620> "
|
||||||
|
elif result == "chaFH":
|
||||||
|
emoji += "<:cha1h1f:695267685063327784> "
|
||||||
|
elif result == "chaFF":
|
||||||
|
emoji += "<:cha2f:695267684832641097> "
|
||||||
|
elif result == "chaHH":
|
||||||
|
emoji += "<:cha2h:695267684631183381> "
|
||||||
|
elif result == "cha":
|
||||||
|
emoji += "<:chabla:695267684895686787> "
|
||||||
|
|
||||||
|
elif result == "booA":
|
||||||
|
emoji += "<:boo1a:695267684975116329> "
|
||||||
|
elif result == "booSA":
|
||||||
|
emoji += "<:boo1a1s:695267684970922024> "
|
||||||
|
elif result == "booS":
|
||||||
|
emoji += "<:boo1s:695267684979441714> "
|
||||||
|
elif result == "booAA":
|
||||||
|
emoji += "<:boo2a:695267685100945488> "
|
||||||
|
elif result == "boo":
|
||||||
|
emoji += "<:boobla:695267684757012550> "
|
||||||
|
|
||||||
|
elif result == "setbF":
|
||||||
|
emoji += "<:set1f:695267685054939197> "
|
||||||
|
elif result == "setbH":
|
||||||
|
emoji += "<:set1h:695267685147082802> "
|
||||||
|
elif result == "setb":
|
||||||
|
emoji += "<:setbla:695267685151408169> "
|
||||||
|
|
||||||
|
elif result == "forceB":
|
||||||
|
emoji += "<:for1b:695267684593434677> "
|
||||||
|
elif result == "forceL":
|
||||||
|
emoji += "<:for1l:695267684606148640> "
|
||||||
|
elif result == "forceBB":
|
||||||
|
emoji += "<:for2b:695267684903944303> "
|
||||||
|
elif result == "forceLL":
|
||||||
|
emoji += "<:for2l:695267684992024626> "
|
||||||
|
|
||||||
|
return emoji
|
||||||
|
|
||||||
|
# Returns emoji that symbolize the results of the dice rolls
|
||||||
|
def resultToEmoji(self, result : str):
|
||||||
|
emoji = ""
|
||||||
|
for char in result:
|
||||||
|
if char == 'S':
|
||||||
|
emoji += "<:success:690971244971163718> "
|
||||||
|
elif char == 'A':
|
||||||
|
emoji += "<:advantage:690970761611051079> "
|
||||||
|
elif char == 'R':
|
||||||
|
emoji += "<:swtriumph:690971267486187643> "
|
||||||
|
elif char == 'F':
|
||||||
|
emoji += "<:failure:690970957786906664> "
|
||||||
|
elif char == 'H':
|
||||||
|
emoji += "<:threat:690971009469382656> "
|
||||||
|
elif char == 'D':
|
||||||
|
emoji += "<:despair:690971200163414238> "
|
||||||
|
elif char == 'L':
|
||||||
|
emoji += "<:light:691010089905029171>"
|
||||||
|
elif char == 'B':
|
||||||
|
emoji += "<:dark:691010101901000852>"
|
||||||
|
|
||||||
elif result == "chaD":
|
return emoji
|
||||||
emoji += "<:cha1d:695267684962533447> "
|
|
||||||
elif result == "chaF":
|
|
||||||
emoji += "<:cha1f:695267684601954346> "
|
|
||||||
elif result == "chaH":
|
|
||||||
emoji += "<:cha1h:695267685046681620> "
|
|
||||||
elif result == "chaFH":
|
|
||||||
emoji += "<:cha1h1f:695267685063327784> "
|
|
||||||
elif result == "chaFF":
|
|
||||||
emoji += "<:cha2f:695267684832641097> "
|
|
||||||
elif result == "chaHH":
|
|
||||||
emoji += "<:cha2h:695267684631183381> "
|
|
||||||
elif result == "cha":
|
|
||||||
emoji += "<:chabla:695267684895686787> "
|
|
||||||
|
|
||||||
elif result == "booA":
|
# Converts emoji into letters
|
||||||
emoji += "<:boo1a:695267684975116329> "
|
def emojiToResult(self, emoji : str):
|
||||||
elif result == "booSA":
|
result = ""
|
||||||
emoji += "<:boo1a1s:695267684970922024> "
|
for char in emoji:
|
||||||
elif result == "booS":
|
if char == "<:light:691010089905029171>":
|
||||||
emoji += "<:boo1s:695267684979441714> "
|
emoji += 'L'
|
||||||
elif result == "booAA":
|
if char == "<:dark:691010101901000852>":
|
||||||
emoji += "<:boo2a:695267685100945488> "
|
emoji += 'B'
|
||||||
elif result == "boo":
|
|
||||||
emoji += "<:boobla:695267684757012550> "
|
|
||||||
|
|
||||||
elif result == "setbF":
|
return result
|
||||||
emoji += "<:set1f:695267685054939197> "
|
|
||||||
elif result == "setbH":
|
|
||||||
emoji += "<:set1h:695267685147082802> "
|
|
||||||
elif result == "setb":
|
|
||||||
emoji += "<:setbla:695267685151408169> "
|
|
||||||
|
|
||||||
elif result == "forceB":
|
# Returns emoji that symbolize the dice
|
||||||
emoji += "<:for1b:695267684593434677> "
|
def diceToEmoji(self, dice : list):
|
||||||
elif result == "forceL":
|
emoji = ""
|
||||||
emoji += "<:for1l:695267684606148640> "
|
|
||||||
elif result == "forceBB":
|
|
||||||
emoji += "<:for2b:695267684903944303> "
|
|
||||||
elif result == "forceLL":
|
|
||||||
emoji += "<:for2l:695267684992024626> "
|
|
||||||
|
|
||||||
return emoji
|
for x in range(dice[0]):
|
||||||
|
emoji += "<:ability:690974213397282826> "
|
||||||
|
for x in range(dice[1]):
|
||||||
|
emoji += "<:proficiency:690973435354153071> "
|
||||||
|
for x in range(dice[2]):
|
||||||
|
emoji += "<:difficulty:690973992470708296> "
|
||||||
|
for x in range(dice[3]):
|
||||||
|
emoji += "<:challenge:690973419906400306> "
|
||||||
|
for x in range(dice[4]):
|
||||||
|
emoji += "<:boost:690972178216386561> "
|
||||||
|
for x in range(dice[5]):
|
||||||
|
emoji += "<:setback:690972157890658415> "
|
||||||
|
for x in range(dice[6]):
|
||||||
|
emoji += "<:force:690973451883774013> "
|
||||||
|
|
||||||
# Returns emoji that symbolize the results of the dice rolls
|
return emoji
|
||||||
def resultToEmoji(result : str):
|
|
||||||
emoji = ""
|
|
||||||
for char in result:
|
|
||||||
if char == 'S':
|
|
||||||
emoji += "<:success:690971244971163718> "
|
|
||||||
elif char == 'A':
|
|
||||||
emoji += "<:advantage:690970761611051079> "
|
|
||||||
elif char == 'R':
|
|
||||||
emoji += "<:swtriumph:690971267486187643> "
|
|
||||||
elif char == 'F':
|
|
||||||
emoji += "<:failure:690970957786906664> "
|
|
||||||
elif char == 'H':
|
|
||||||
emoji += "<:threat:690971009469382656> "
|
|
||||||
elif char == 'D':
|
|
||||||
emoji += "<:despair:690971200163414238> "
|
|
||||||
elif char == 'L':
|
|
||||||
emoji += "<:light:691010089905029171>"
|
|
||||||
elif char == 'B':
|
|
||||||
emoji += "<:dark:691010101901000852>"
|
|
||||||
|
|
||||||
return emoji
|
|
||||||
|
|
||||||
# Converts emoji into letters
|
# Rolls for obligation
|
||||||
def emojiToResult(emoji : str):
|
def obligationRoll(self):
|
||||||
result = ""
|
logThis("Rolling for obligation")
|
||||||
for char in emoji:
|
data = self.bot.database["swcharacters"]
|
||||||
if char == "<:light:691010089905029171>":
|
|
||||||
emoji += 'L'
|
|
||||||
if char == "<:dark:691010101901000852>":
|
|
||||||
emoji += 'B'
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
# Returns emoji that symbolize the dice
|
table = []
|
||||||
def diceToEmoji(dice : list):
|
|
||||||
emoji = ""
|
|
||||||
|
|
||||||
for x in range(dice[0]):
|
for character in data:
|
||||||
emoji += "<:ability:690974213397282826> "
|
for obligation in data[character]["Obligations"]:
|
||||||
for x in range(dice[1]):
|
for x in range(data[character]["Obligations"][obligation]):
|
||||||
emoji += "<:proficiency:690973435354153071> "
|
table.append(data[character]["Name"]+", "+obligation)
|
||||||
for x in range(dice[2]):
|
|
||||||
emoji += "<:difficulty:690973992470708296> "
|
|
||||||
for x in range(dice[3]):
|
|
||||||
emoji += "<:challenge:690973419906400306> "
|
|
||||||
for x in range(dice[4]):
|
|
||||||
emoji += "<:boost:690972178216386561> "
|
|
||||||
for x in range(dice[5]):
|
|
||||||
emoji += "<:setback:690972157890658415> "
|
|
||||||
for x in range(dice[6]):
|
|
||||||
emoji += "<:force:690973451883774013> "
|
|
||||||
|
|
||||||
return emoji
|
while len(table) < 100:
|
||||||
|
table.append("Nothing")
|
||||||
|
|
||||||
# Rolls for obligation
|
return random.choice(table)
|
||||||
def obligationRoll():
|
|
||||||
logThis("Rolling for obligation")
|
|
||||||
with open("resources/starWars/swcharacters.json", "r") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
|
|
||||||
table = []
|
|
||||||
|
|
||||||
for character in data:
|
# Rolls for critical injury
|
||||||
for obligation in data[character]["Obligations"]:
|
def critRoll(self, addington : int):
|
||||||
for x in range(data[character]["Obligations"][obligation]):
|
dd = "<:difficulty:690973992470708296>"
|
||||||
table.append(data[character]["Name"]+", "+obligation)
|
sd = "<:setback:690972157890658415>"
|
||||||
|
bd = "<:boost:690972178216386561>"
|
||||||
while len(table) < 100:
|
roll = random.randint(1,100) + addington
|
||||||
table.append("Nothing")
|
injuries = [
|
||||||
|
"**Minor nick**: The target suffers 1 strain, "+dd] * 5 + [
|
||||||
return random.choice(table)
|
"**Slowed down**: The target can only act during the last allied initiative slot this turn, "+dd] * 5 + [
|
||||||
|
"**Sudden Jolt**: The target drops whatever is in hand, "+dd] * 5 + [
|
||||||
|
"**Distracted**: The target cannot perform a Free maneuver during his next turn, "+dd] * 5 + [
|
||||||
|
"**Off-Balance**: The target adds "+sd+" to his next skill check, "+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 + [
|
||||||
|
"**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 + [
|
||||||
|
"**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 + [
|
||||||
|
"**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 + [
|
||||||
|
"**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 + [
|
||||||
|
"**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 + [
|
||||||
|
"**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 + [
|
||||||
|
"**At the brink**: The target suffers 1 strain each time he performs an action, "+dd+dd+dd] * 5 + [
|
||||||
|
"**Crippled**: One of the target's limbs (selected by the GM) is crippled until healed or replaced. Increase difficulty of all checks that require use of that limb by one, "+dd+dd+dd] * 5 + [
|
||||||
|
"**Maimed**: One of the target's limbs (selected by the GM) is permanently lost. Unless the target has a cybernetic replacement, the target cannot perform actions that would require the use of that limb. All other actions gain "+sd+", "+dd+dd+dd] * 5 + [
|
||||||
|
"HI"] * 5 + [
|
||||||
|
"**Temporarily Lame**: Until this critical injury is healed, the target cannot perform more than one maneuver during his turn, "+dd+dd+dd] * 5 + [
|
||||||
|
"**Blinded**: The target can no longer see. Upgrade the difficulty of all checks twice. Upgrade the difficulty of perception checks three times, "+dd+dd+dd] * 5 + [
|
||||||
|
"**Knocked Senseless**: The target is staggered for the remainder of the encounter, "+dd+dd+dd] * 5 + [
|
||||||
|
"GI"] * 5 + [
|
||||||
|
"**Bleeding Out**: Every round, the target suffers 1 wound and 1 strain at the beginning of his turn. For every five wounds he suffers beyond his wound threshold, he suffers one additional critical injury. (If he suffers this one again, roll again), "+dd+dd+dd+dd] * 10 + [
|
||||||
|
"**The End is Nigh**: The target will die after the last initiative slot during the next round, "+dd+dd+dd+dd] * 10 + [
|
||||||
|
"**Dead**: U B Dead :("]
|
||||||
|
|
||||||
# Rolls for critical injury
|
if roll >= len(injuries):
|
||||||
def critRoll(addington : int):
|
results = injuries[-1]
|
||||||
dd = "<:difficulty:690973992470708296>"
|
|
||||||
sd = "<:setback:690972157890658415>"
|
|
||||||
bd = "<:boost:690972178216386561>"
|
|
||||||
roll = random.randint(1,100) + addington
|
|
||||||
injuries = [
|
|
||||||
"**Minor nick**: The target suffers 1 strain, "+dd] * 5 + [
|
|
||||||
"**Slowed down**: The target can only act during the last allied initiative slot this turn, "+dd] * 5 + [
|
|
||||||
"**Sudden Jolt**: The target drops whatever is in hand, "+dd] * 5 + [
|
|
||||||
"**Distracted**: The target cannot perform a Free maneuver during his next turn, "+dd] * 5 + [
|
|
||||||
"**Off-Balance**: The target adds "+sd+" to his next skill check, "+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 + [
|
|
||||||
"**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 + [
|
|
||||||
"**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 + [
|
|
||||||
"**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 + [
|
|
||||||
"**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 + [
|
|
||||||
"**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 + [
|
|
||||||
"**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 + [
|
|
||||||
"**At the brink**: The target suffers 1 strain each time he performs an action, "+dd+dd+dd] * 5 + [
|
|
||||||
"**Crippled**: One of the target's limbs (selected by the GM) is crippled until healed or replaced. Increase difficulty of all checks that require use of that limb by one, "+dd+dd+dd] * 5 + [
|
|
||||||
"**Maimed**: One of the target's limbs (selected by the GM) is permanently lost. Unless the target has a cybernetic replacement, the target cannot perform actions that would require the use of that limb. All other actions gain "+sd+", "+dd+dd+dd] * 5 + [
|
|
||||||
"HI"] * 5 + [
|
|
||||||
"**Temporarily Lame**: Until this critical injury is healed, the target cannot perform more than one maneuver during his turn, "+dd+dd+dd] * 5 + [
|
|
||||||
"**Blinded**: The target can no longer see. Upgrade the difficulty of all checks twice. Upgrade the difficulty of perception checks three times, "+dd+dd+dd] * 5 + [
|
|
||||||
"**Knocked Senseless**: The target is staggered for the remainder of the encounter, "+dd+dd+dd] * 5 + [
|
|
||||||
"GI"] * 5 + [
|
|
||||||
"**Bleeding Out**: Every round, the target suffers 1 wound and 1 strain at the beginning of his turn. For every five wounds he suffers beyond his wound threshold, he suffers one additional critical injury. (If he suffers this one again, roll again), "+dd+dd+dd+dd] * 10 + [
|
|
||||||
"**The End is Nigh**: The target will die after the last initiative slot during the next round, "+dd+dd+dd+dd] * 10 + [
|
|
||||||
"**Dead**: U B Dead :("]
|
|
||||||
|
|
||||||
if roll >= len(injuries):
|
|
||||||
results = injuries[-1]
|
|
||||||
else:
|
|
||||||
results = injuries[roll]
|
|
||||||
|
|
||||||
if results == "HI":
|
|
||||||
characteristic = random.choice(["brawn"] * 3 + ["agility"] * 3 + ["intellect", "cunning", "presence"])
|
|
||||||
results = "**Horrific Injury**: Until this criticil injury is healed, treat the target's "+characteristic+" as if it's one lower, "+dd+dd+dd
|
|
||||||
|
|
||||||
if results == "GI":
|
|
||||||
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
|
|
||||||
|
|
||||||
return "Roll: "+str(roll)+"\nInjury:\n"+results
|
|
||||||
|
|
||||||
# Parses the command into something the other functions understand
|
|
||||||
def parseRoll(user : str,cmd : str = ""):
|
|
||||||
cmd = re.sub(' +',' ',cmd.upper()) + " "
|
|
||||||
if cmd[0] == " ":
|
|
||||||
cmd = cmd[1:]
|
|
||||||
cmd = swchar.replaceSpaces(string.capwords(cmd))
|
|
||||||
commands = cmd.split(" ")
|
|
||||||
if commands[0] == "":
|
|
||||||
rollParameters = [1,0,3,0,0,0,0]
|
|
||||||
else:
|
|
||||||
rollParameters = [0,0,0,0,0,0,0]
|
|
||||||
|
|
||||||
if string.capwords(commands[0]) == "Obligations":
|
|
||||||
try:
|
|
||||||
return obligationRoll()
|
|
||||||
except:
|
|
||||||
logThis("Obligation fucked up (error code 911)")
|
|
||||||
return "An error occured (error code 911)"
|
|
||||||
|
|
||||||
elif string.capwords(commands[0]) in skillData:
|
|
||||||
logThis("Oh look! This guy has skills!")
|
|
||||||
if swchar.userHasChar:
|
|
||||||
logThis("They have a character. That much we know")
|
|
||||||
skillLevel = swchar.charData(user,"Skills " + string.capwords(commands[0]))
|
|
||||||
|
|
||||||
if string.capwords(commands[0]) == "Lightsaber":
|
|
||||||
logThis("The skill is lightsaber")
|
|
||||||
charLevel = swchar.charData(user,"Characteristics " + swchar.lightsaberChar(user))
|
|
||||||
else:
|
|
||||||
charLevel = swchar.charData(user,"Characteristics " + skillData[string.capwords(commands[0])])
|
|
||||||
|
|
||||||
abilityDice = abs(charLevel-skillLevel)
|
|
||||||
proficiencyDice = min(skillLevel,charLevel)
|
|
||||||
|
|
||||||
commands = [str(abilityDice)] + [str(proficiencyDice)] + commands[1:]
|
|
||||||
logThis("Converted skill to dice")
|
|
||||||
else:
|
else:
|
||||||
logThis("Okay, no they don't i guess (error code 912)")
|
results = injuries[roll]
|
||||||
return "You don't have a user. You can make one with !swchar (error code 912)"
|
|
||||||
|
|
||||||
elif string.capwords(commands[0]) in ["Ranged","Piloting"]:
|
if results == "HI":
|
||||||
logThis("They fucked up writing the name of a ranged or piloting skill")
|
characteristic = random.choice(["brawn"] * 3 + ["agility"] * 3 + ["intellect", "cunning", "presence"])
|
||||||
if string.capwords(commands[0]) == "Ranged":
|
results = "**Horrific Injury**: Until this criticil injury is healed, treat the target's "+characteristic+" as if it's one lower, "+dd+dd+dd
|
||||||
return "Did you mean \"Ranged - Heavy\" or \"Ranged - Light\" (error code 913)"
|
|
||||||
|
if results == "GI":
|
||||||
|
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
|
||||||
|
|
||||||
|
return "Roll: "+str(roll)+"\nInjury:\n"+results
|
||||||
|
|
||||||
|
# Parses the command into something the other functions understand
|
||||||
|
def parseRoll(self, user : str,cmd : str = ""):
|
||||||
|
cmd = re.sub(' +',' ',cmd.upper()) + " "
|
||||||
|
if cmd[0] == " ":
|
||||||
|
cmd = cmd[1:]
|
||||||
|
cmd = self.bot.swchar.replaceSpaces(string.capwords(cmd))
|
||||||
|
commands = cmd.split(" ")
|
||||||
|
if commands[0] == "":
|
||||||
|
rollParameters = [1,0,3,0,0,0,0]
|
||||||
else:
|
else:
|
||||||
return "Did you mean \"Piloting - Planetary\" or \"Piloting - Space\" (error code 913)"
|
rollParameters = [0,0,0,0,0,0,0]
|
||||||
|
|
||||||
try:
|
if string.capwords(commands[0]) == "Obligations":
|
||||||
logThis("Converting commands to dice")
|
try:
|
||||||
for x in range(len(commands)):
|
return obligationRoll()
|
||||||
if commands[x] != "":
|
except:
|
||||||
commands[x] = commands[x].upper()
|
logThis("Obligation fucked up (error code 911)")
|
||||||
if commands[x][0] == "A":
|
return "An error occured (error code 911)"
|
||||||
rollParameters[0] = int(commands[x].replace("A",""))
|
|
||||||
elif commands[x][0] == "P":
|
elif string.capwords(commands[0]) in skillData:
|
||||||
rollParameters[1] = int(commands[x].replace("P",""))
|
logThis("Oh look! This guy has skills!")
|
||||||
elif commands[x][0] == "D":
|
if self.bot.swchar.userHasChar:
|
||||||
rollParameters[2] = int(commands[x].replace("D",""))
|
logThis("They have a character. That much we know")
|
||||||
elif commands[x][0] == "C":
|
skillLevel = self.bot.swchar.charData(user,"Skills " + string.capwords(commands[0]))
|
||||||
rollParameters[3] = int(commands[x].replace("C",""))
|
|
||||||
elif commands[x][0] == "B":
|
if string.capwords(commands[0]) == "Lightsaber":
|
||||||
rollParameters[4] = int(commands[x].replace("B",""))
|
logThis("The skill is lightsaber")
|
||||||
elif commands[x][0] == "S":
|
charLevel = self.bot.swchar.charData(user,"Characteristics " + self.bot.swchar.lightsaberChar(user))
|
||||||
rollParameters[5] = int(commands[x].replace("S",""))
|
|
||||||
elif commands[x][0] == "F":
|
|
||||||
rollParameters[6] = int(commands[x].replace("F",""))
|
|
||||||
else:
|
else:
|
||||||
rollParameters[x] = int(commands[x])
|
charLevel = self.bot.swchar.charData(user,"Characteristics " + skillData[string.capwords(commands[0])])
|
||||||
except:
|
|
||||||
logThis("Someone fucked u-up! (it was them) (error code 914)")
|
|
||||||
return "Invalid input! (error code 914)"
|
|
||||||
|
|
||||||
logThis("Rolling "+str(rollParameters))
|
|
||||||
rollResults, diceResults = roll(rollParameters[0],rollParameters[1],rollParameters[2],rollParameters[3],rollParameters[4],rollParameters[5],rollParameters[6])
|
|
||||||
|
|
||||||
simplified = simplify(rollResults)
|
|
||||||
|
|
||||||
name = swchar.getCharName(user)
|
abilityDice = abs(charLevel-skillLevel)
|
||||||
|
proficiencyDice = min(skillLevel,charLevel)
|
||||||
logThis("Returns results and simplified results")
|
|
||||||
|
commands = [str(abilityDice)] + [str(proficiencyDice)] + commands[1:]
|
||||||
|
logThis("Converted skill to dice")
|
||||||
|
else:
|
||||||
|
logThis("Okay, no they don't i guess (error code 912)")
|
||||||
|
return "You don't have a user. You can make one with !swchar (error code 912)"
|
||||||
|
|
||||||
|
elif string.capwords(commands[0]) in ["Ranged","Piloting"]:
|
||||||
|
logThis("They fucked up writing the name of a ranged or piloting skill")
|
||||||
|
if string.capwords(commands[0]) == "Ranged":
|
||||||
|
return "Did you mean \"Ranged - Heavy\" or \"Ranged - Light\" (error code 913)"
|
||||||
|
else:
|
||||||
|
return "Did you mean \"Piloting - Planetary\" or \"Piloting - Space\" (error code 913)"
|
||||||
|
|
||||||
|
try:
|
||||||
|
logThis("Converting commands to dice")
|
||||||
|
for x in range(len(commands)):
|
||||||
|
if commands[x] != "":
|
||||||
|
commands[x] = commands[x].upper()
|
||||||
|
if commands[x][0] == "A":
|
||||||
|
rollParameters[0] = int(commands[x].replace("A",""))
|
||||||
|
elif commands[x][0] == "P":
|
||||||
|
rollParameters[1] = int(commands[x].replace("P",""))
|
||||||
|
elif commands[x][0] == "D":
|
||||||
|
rollParameters[2] = int(commands[x].replace("D",""))
|
||||||
|
elif commands[x][0] == "C":
|
||||||
|
rollParameters[3] = int(commands[x].replace("C",""))
|
||||||
|
elif commands[x][0] == "B":
|
||||||
|
rollParameters[4] = int(commands[x].replace("B",""))
|
||||||
|
elif commands[x][0] == "S":
|
||||||
|
rollParameters[5] = int(commands[x].replace("S",""))
|
||||||
|
elif commands[x][0] == "F":
|
||||||
|
rollParameters[6] = int(commands[x].replace("F",""))
|
||||||
|
else:
|
||||||
|
rollParameters[x] = int(commands[x])
|
||||||
|
except:
|
||||||
|
logThis("Someone fucked u-up! (it was them) (error code 914)")
|
||||||
|
return "Invalid input! (error code 914)"
|
||||||
|
|
||||||
|
logThis("Rolling "+str(rollParameters))
|
||||||
|
rollResults, diceResults = self.roll(rollParameters[0],rollParameters[1],rollParameters[2],rollParameters[3],rollParameters[4],rollParameters[5],rollParameters[6])
|
||||||
|
|
||||||
|
simplified = self.simplify(rollResults)
|
||||||
|
|
||||||
|
name = self.bot.swchar.getCharName(user)
|
||||||
|
|
||||||
|
logThis("Returns results and simplified results")
|
||||||
|
|
||||||
|
if simplified == "":
|
||||||
|
return name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\nEverything cancels out!"
|
||||||
|
else:
|
||||||
|
return name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\n" + self.resultToEmoji(simplified)
|
||||||
|
|
||||||
if simplified == "":
|
|
||||||
return name + " rolls: " + "\n" + diceResultToEmoji(diceResults) + "\nEverything cancels out!"
|
|
||||||
else:
|
|
||||||
return name + " rolls: " + "\n" + diceResultToEmoji(diceResults) + "\n" + resultToEmoji(simplified)
|
|
||||||
|
|
||||||
|
@ -1,15 +1,5 @@
|
|||||||
{
|
{
|
||||||
"json":{
|
"json":{
|
||||||
"resources/starWars/swcharacters.json" : {},
|
|
||||||
"resources/games/hexGames.json": {},
|
|
||||||
"resources/games/monopolyGames.json": {},
|
|
||||||
"resources/games/hangmanGames.json": {},
|
|
||||||
"resources/games/investments.json" : {},
|
|
||||||
"resources/games/games.json" : {
|
|
||||||
"trivia questions":{},
|
|
||||||
"blackjack games":{},
|
|
||||||
"4 in a row games": {}
|
|
||||||
},
|
|
||||||
"resources/lookup/spells.json" : {
|
"resources/lookup/spells.json" : {
|
||||||
"Fireball" : {
|
"Fireball" : {
|
||||||
"casting_time" : "1 action",
|
"casting_time" : "1 action",
|
||||||
@ -76,9 +66,6 @@
|
|||||||
"resources/games/blackjackTables",
|
"resources/games/blackjackTables",
|
||||||
"resources/games/4InARowBoards",
|
"resources/games/4InARowBoards",
|
||||||
"resources/games/hexBoards",
|
"resources/games/hexBoards",
|
||||||
"resources/games/oldImages",
|
|
||||||
"resources/games/blackjackCards",
|
|
||||||
"resources/games/hilo",
|
|
||||||
"resources/games/monopolyBoards",
|
"resources/games/monopolyBoards",
|
||||||
"resources/games/hangmanBoards"
|
"resources/games/hangmanBoards"
|
||||||
]
|
]
|
||||||
|
Reference in New Issue
Block a user