:spakles: Database and OOP

This commit is contained in:
NikolajDanger
2020-08-13 16:31:28 +02:00
parent f431c079d1
commit 4127e537a1
31 changed files with 3674 additions and 3731 deletions

1
.gitignore vendored
View File

@ -151,6 +151,7 @@ static
.vscode/
token.txt
credentials.txt
options.txt
resources/starWars/swcharacters.json
resources/games/games.json
resources/games/hexGames.json

View File

@ -2,7 +2,7 @@ import discord, os, finnhub, pymongo
from discord.ext import commands
from pymongo import MongoClient
from funcs import logThis, makeFiles, transferUsers
from funcs import logThis, makeFiles, transferUsers, Money, Funcs, SwChar, SwDestiny, SwRoll, Games
commandPrefix = "!"
@ -30,8 +30,22 @@ class Gwendolyn(commands.Bot):
self.options = Options()
self.credentials = Credentials()
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")
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)
# Creates the required files

View File

@ -1,7 +1,7 @@
import discord, asyncio
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):
@ -12,7 +12,7 @@ class GamesCog(commands.Cog):
# Checks user balance
@commands.command(aliases = ["b"])
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:
new_message = ctx.message.author.display_name + " has " + str(response) + " GwendoBuck"
else:
@ -25,7 +25,7 @@ class GamesCog(commands.Cog):
commands = content.split(" ")
if len(commands) == 2:
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)
else:
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
@commands.command(aliases=["i"])
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("**"):
responses = response.split("\n")
em = discord.Embed(title=responses[0],description="\n".join(responses[1:]),colour=0x00FF00)
@ -46,7 +46,7 @@ class GamesCog(commands.Cog):
@commands.command()
async def trivia(self, ctx, *, 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 != "":
results = "**"+question+"**\n"
for x, answer in enumerate(answers):
@ -56,9 +56,9 @@ class GamesCog(commands.Cog):
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))
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)
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 "):
await ctx.message.add_reaction("👍")
else:
@ -78,27 +78,27 @@ class GamesCog(commands.Cog):
# Runs a game of blackjack
@commands.command(aliases = ["bj"])
async def blackjack(self, ctx, *, content = ""):
await parseBlackjack(content,ctx)
await self.client.blackjack.parseBlackjack(content,ctx)
# Runs a game of Connect four
@commands.command(aliases = ["fiar","connect4","connectfour","4iar","4inarow"])
async def fourinarow(self, ctx, *, content = ""):
await 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))
await self.client.gameLoops.fiar(ctx.message.channel,content,"#"+str(ctx.message.author.id))
# Runs a game of Monopoly
@commands.command(aliases = ["m","mon","mono"])
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
@commands.command(aliases = ["hm"])
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):
client.add_cog(GamesCog(client))

View File

@ -1,7 +1,7 @@
import discord, codecs, string
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):
@ -40,7 +40,7 @@ class MiscCog(commands.Cog):
if "#"+str(ctx.message.author.id) in ["#266269899859427329", "#380732645602230272"]:
await ctx.send("Pulling git repo and restarting...")
stopServer()
self.client.funcs.stopServer()
await self.client.logout()
else:

View File

@ -1,6 +1,6 @@
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):
def __init__(self, client):
@ -14,17 +14,17 @@ class ReactionCog(commands.Cog):
channel = message.channel
logThis(user.display_name+" reacted to a message",str(channel.id))
try:
fourInARowTheirTurn, piece = fiarReactionTest(channel,message,"#"+str(user.id))
fourInARowTheirTurn, piece = self.client.funcs.fiarReactionTest(channel,message,"#"+str(user.id))
except:
fourInARowTheirTurn = False
if fourInARowTheirTurn:
place = emojiToCommand(reaction.emoji)
await fiar(channel," place "+str(piece)+" "+str(place),user.id)
elif monopolyReactionTest(channel,message):
await runMonopoly(channel,"roll","#"+str(user.id))
elif hangmanReactionTest(channel,message):
await self.client.gameLoops.fiar(channel," place "+str(piece)+" "+str(place),user.id)
elif self.client.funcs.monopolyReactionTest(channel,message):
await self.client.gameLoops.runMonopoly(channel,"roll","#"+str(user.id))
elif self.client.funcs.hangmanReactionTest(channel,message):
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):
client.add_cog(ReactionCog(client))

View File

@ -1,7 +1,7 @@
import discord, string
from discord.ext import commands
from funcs import parseRoll, parseDestiny, critRoll, parseChar, cap
from funcs import cap
class SwCog(commands.Cog):
@ -13,7 +13,7 @@ class SwCog(commands.Cog):
@commands.command()
async def swroll(self, ctx, *, 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")
for messageItem in messageList:
await ctx.send(messageItem)
@ -21,7 +21,7 @@ class SwCog(commands.Cog):
# Controls destiny points
@commands.command()
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")
for messageItem in messageList:
await ctx.send(messageItem)
@ -29,7 +29,7 @@ class SwCog(commands.Cog):
# Rolls for critical injuries
@commands.command()
async def swcrit(self, ctx, arg : int = 0):
newMessage = critRoll(int(arg))
newMessage = self.client.swroll.critRoll(int(arg))
messageList = newMessage.split("\n")
for messageItem in messageList:
@ -40,7 +40,7 @@ class SwCog(commands.Cog):
@commands.command(aliases=["sw"])
async def swchar(self, ctx, *, content = ""):
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 != "":
em1 = discord.Embed(title = title, description = desc, colour=0xDEADBF)
await ctx.send(embed = em1)

View File

@ -1,10 +1,12 @@
"""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
@ -12,4 +14,4 @@ from .other import nameGen, tavernGen, movieFunc
from .roll import roll_dice
from .swfuncs import parseChar, parseRoll, parseDestiny, critRoll
from .swfuncs import SwChar, SwDestiny, SwRoll

84
funcs/funcs.py Normal file
View 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

View File

@ -1,9 +1,6 @@
"""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 .trivia import triviaCountPoints, triviaStart, triviaAnswer
from .invest import parseInvest
from .gameLoops import fiar, runMonopoly, runHex, runHangman
from .blackjackLoop import blackjackLoop, parseBlackjack
from .money import Money
from .games import Games

View File

@ -1,15 +1,22 @@
import random
import json
import math
import datetime
import os
import asyncio
import discord
from shutil import copyfile
from funcs import logThis, replaceMultiple, getName
from . import money, blackjackDraw
from funcs import logThis, replaceMultiple
from .blackjackDraw import DrawBlackjack
# Shuffles the blackjack cards
def blackjackShuffle(decks,channel):
class Blackjack():
def __init__(self,bot):
self.bot = bot
self.draw = DrawBlackjack(bot)
# Shuffles the blackjack cards
def blackjackShuffle(self, decks, channel):
logThis("Shuffling the blackjack deck")
with open("resources/games/deckofCards.txt","r") as f:
@ -17,21 +24,18 @@ def blackjackShuffle(decks,channel):
allDecks = deck.split("\n") * decks
random.shuffle(allDecks)
data = "\n".join(allDecks)
with open("resources/games/blackjackCards/"+channel+".txt","w") as f:
f.write(data)
self.bot.database["blackjack cards"].update_one({"_id":channel},{"$set":{"_id":channel,"cards":allDecks}},upsert=True)
# Creates hilo file
logThis("creating hilo/"+channel+".txt.")
data = "0"
with open("resources/games/hilo/"+channel+".txt","w") as f:
f.write(data)
logThis("creating hilo doc for "+channel)
data = 0
self.bot.database["hilo"].update_one({"_id":channel},{"$set":{"_id":channel,"hilo":data}},upsert=True)
return
# Calculates the value of a blackjack hand
def calcHandValue(hand : list):
# Calculates the value of a blackjack hand
def calcHandValue(self, hand : list):
logThis("Calculating hand value")
values = [0]
@ -58,97 +62,75 @@ def calcHandValue(hand : list):
return handValue
# Draws a card from the deck
def drawCard(channel):
# Draws a card from the deck
def drawCard(self, channel):
logThis("drawing a card")
with open("resources/games/blackjackCards/"+channel+".txt","r") as f:
cards = f.read().split("\n")
with open("resources/games/hilo/"+channel+".txt", "r") as f:
data = int(f.read())
drawnCard = cards.pop(0)
deck = "\n".join(cards)
value = calcHandValue([drawnCard])
drawnCard = self.bot.database["blackjack cards"].find_one({"_id":channel})["cards"][0]
self.bot.database["blackjack cards"].update_one({"_id":channel},{"$pop":{"cards":-1}})
value = self.calcHandValue([drawnCard])
if value <= 6:
data += 1
self.bot.database["hilo"].update_one({"_id":channel},{"$inc":{"hilo":1}})
elif value >= 10:
data -= 1
with open("resources/games/blackjackCards/"+channel+".txt","w") as f:
f.write(deck)
with open("resources/games/hilo/"+channel+".txt", "w") as f:
f.write(str(data))
self.bot.database["hilo"].update_one({"_id":channel},{"$inc":{"hilo":-1}})
return drawnCard
# Dealer draws a card and checks if they should draw another one
def dealerDraw(channel):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# Dealer draws a card and checks if they should draw another one
def dealerDraw(self,channel):
game = self.bot.database["blackjack games"].find_one({"_id":channel})
done = False
dealerHand = data["blackjack games"][channel]["dealer hand"]
dealerHand = game["dealer hand"]
if calcHandValue(dealerHand) < 17:
data["blackjack games"][channel]["dealer hand"].append(drawCard(channel))
if self.calcHandValue(dealerHand) < 17:
dealerHand.append(self.drawCard(channel))
self.bot.database["blackjack games"].update_one({"_id":channel},{"$set":{"dealer hand":dealerHand}})
else:
done = True
if calcHandValue(dealerHand) > 21:
data["blackjack games"][channel]["dealer busted"] = True
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
print(dealerHand)
if self.calcHandValue(dealerHand) > 21:
print("yeet")
self.bot.database["blackjack games"].update_one({"_id":channel},{"$set":{"dealer busted":True}})
return done
# Goes to the next round and calculates some stuff
def blackjackContinue(channel):
# Goes to the next round and calculates some stuff
def blackjackContinue(self, channel):
logThis("Continuing blackjack game")
with open("resources/games/games.json", "r") as f:
data = json.load(f)
game = self.bot.database["blackjack games"].find_one({"_id":channel})
done = False
data["blackjack games"][channel]["round"] += 1
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["blackjack games"].update_one({"_id":channel},{"$inc":{"round":1}})
allStanding = True
preAllStanding = True
message = "All players are standing. The dealer now shows his cards and draws."
if data["blackjack games"][channel]["all standing"]:
if game["all standing"]:
logThis("All are standing")
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
done = dealerDraw(channel)
done = self.dealerDraw(channel)
message = "The dealer draws a card."
with open("resources/games/games.json", "r") as f:
data = json.load(f)
game = self.bot.database["blackjack games"].find_one({"_id":channel})
logThis("Testing if all are standing")
for user in data["blackjack games"][channel]["user hands"]:
for user in game["user hands"]:
try:
data["blackjack games"][channel]["user hands"][user], allStanding, preAllStanding = testIfStanding(data["blackjack games"][channel]["user hands"][user],allStanding,preAllStanding,True)
newUser, allStanding, preAllStanding = self.testIfStanding(game["user hands"][user],allStanding,preAllStanding,True)
self.bot.database["blackjack games"].update_one({"_id":channel},{"$set":{"user hands."+user:newUser}})
except:
logThis("Error in testing if all are standing (error code 1331)")
if allStanding:
data["blackjack games"][channel]["all standing"] = True
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
else:
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["blackjack games"].update_one({"_id":channel},{"$set":{"all standing":True}})
try:
blackjackDraw.drawImage(channel)
self.draw.drawImage(channel)
except:
logThis("Error drawing blackjack table (error code 1340)")
@ -160,20 +142,20 @@ def blackjackContinue(channel):
elif preAllStanding:
return "", True, done
else:
if data["blackjack games"][channel]["round"] == 1:
if game["round"] == 1:
firstRoundMessage = ". You can also double down with \"!blackjack double\" or split with \"!blackjack split\""
else:
firstRoundMessage = ""
return "You have 2 minutes to either hit or stand with \"!blackjack hit\" or \"!blackjack stand\""+firstRoundMessage+". It's assumed you're standing if you don't make a choice.", False, done
def testIfStanding(hand,allStanding,preAllStanding,topLevel):
def testIfStanding(self, hand,allStanding,preAllStanding,topLevel):
if hand["hit"] == False:
hand["standing"] = True
if hand["standing"] == False:
allStanding = False
if calcHandValue(hand["hand"]) >= 21 or hand["doubled"]:
if self.calcHandValue(hand["hand"]) >= 21 or hand["doubled"]:
hand["standing"] = True
else:
preAllStanding = False
@ -182,53 +164,52 @@ def testIfStanding(hand,allStanding,preAllStanding,topLevel):
if topLevel:
if hand["split"] >= 1:
hand["other hand"], allstanding, preAllStanding = testIfStanding(hand["other hand"],allStanding,preAllStanding,False)
hand["other hand"], allStanding, preAllStanding = self.testIfStanding(hand["other hand"],allStanding,preAllStanding,False)
if hand["split"] >= 2:
hand["third hand"], allstanding, preAllStanding = testIfStanding(hand["third hand"],allStanding,preAllStanding,False)
hand["third hand"], allStanding, preAllStanding = self.testIfStanding(hand["third hand"],allStanding,preAllStanding,False)
if hand["split"] >= 3:
hand["fourth hand"], allstanding, preAllStanding = testIfStanding(hand["fourth hand"],allStanding,preAllStanding,False)
hand["fourth hand"], allStanding, preAllStanding = self.testIfStanding(hand["fourth hand"],allStanding,preAllStanding,False)
return hand, allStanding, preAllStanding
# When players try to hit
def blackjackHit(channel,user,handNumber = 0):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# When players try to hit
def blackjackHit(self,channel,user,handNumber = 0):
game = self.bot.database["blackjack games"].find_one({"_id":channel})
if user in data["blackjack games"][channel]["user hands"]:
if user in game["user hands"]:
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
print(hand)
hand, handNumber = self.getHandNumber(game["user hands"][user],handNumber)
if hand != None:
if data["blackjack games"][channel]["round"] > 0:
if game["round"] > 0:
if hand["hit"] == False:
if hand["standing"] == False:
hand["hand"].append(drawCard(channel))
hand["hand"].append(self.drawCard(channel))
hand["hit"] = True
handValue = calcHandValue(hand["hand"])
handValue = self.calcHandValue(hand["hand"])
if handValue > 21:
hand["busted"] = True
if handNumber == 2:
data["blackjack games"][channel]["user hands"][user]["other hand"] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".other hand":hand}})
elif handNumber == 3:
data["blackjack games"][channel]["user hands"][user]["third hand"] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".third hand":hand}})
elif handNumber == 4:
data["blackjack games"][channel]["user hands"][user]["fourth hand"] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".fourth hand":hand}})
else:
data["blackjack games"][channel]["user hands"][user] = hand
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user:hand}})
response = "accept"
roundDone = isRoundDone(data["blackjack games"][channel])
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
return response + str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
return response + str(roundDone)[0] + str(game["round"])
else:
logThis(user+" is already standing")
return "You can't hit when you're standing"
@ -246,56 +227,54 @@ def blackjackHit(channel,user,handNumber = 0):
return "You have to enter the game before you can hit"
# When players try to double down
def blackjackDouble(channel,user,handNumber = 0):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# When players try to double down
def blackjackDouble(self,channel,user,handNumber = 0):
game = self.bot.database["blackjack games"].find_one({"_id":channel})
if user in data["blackjack games"][channel]["user hands"]:
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
if user in game["user hands"]:
hand, handNumber = self.getHandNumber(game["user hands"][user],handNumber)
if hand != None:
if data["blackjack games"][channel]["round"] > 0:
if game["round"] > 0:
if hand["hit"] == False:
if hand["standing"] == False:
if len(hand["hand"]) == 2:
bet = hand["bet"]
if money.checkBalance(user) >= bet:
money.addMoney(user,-1 * bet)
with open("resources/games/games.json", "r") as f:
data = json.load(f)
if self.bot.money.checkBalance(user) >= bet:
self.bot.money.addMoney(user,-1 * bet)
hand["hand"].append(drawCard(channel))
hand["hand"].append(self.drawCard(channel))
hand["hit"] = True
hand["doubled"] = True
hand["bet"] += bet
handValue = calcHandValue(hand["hand"])
handValue = self.calcHandValue(hand["hand"])
if handValue > 21:
hand["busted"] = True
if handNumber == 2:
data["blackjack games"][channel]["user hands"][user]["other hand"] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".other hand":hand}})
elif handNumber == 3:
data["blackjack games"][channel]["user hands"][user]["third hand"] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".third hand":hand}})
elif handNumber == 4:
data["blackjack games"][channel]["user hands"][user]["fourth hand"] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".fourth hand":hand}})
else:
data["blackjack games"][channel]["user hands"][user] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user:hand}})
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
roundDone = isRoundDone(data["blackjack games"][channel])
return "Adding another "+str(bet)+" GwendoBucks to "+getName(user)+"'s bet and drawing another card.",str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
return "Adding another "+str(bet)+" GwendoBucks to "+self.bot.funcs.getName(user)+"'s bet and drawing another card.",str(roundDone)[0] + str(game["round"])
else:
logThis(user+" doesn't have enough GwendoBucks")
return "You don't have enough GwendoBucks",""
else:
logThis(user+" tried to double on round "+str(data["blackjack games"][channel]["round"]))
logThis(user+" tried to double on round "+str(game["round"]))
return "You can only double down on the first round",""
else:
logThis(user+" is already standing")
@ -313,27 +292,37 @@ def blackjackDouble(channel,user,handNumber = 0):
logThis(user+" tried to double without being in the game")
return "You can't double when you're not in the game",""
# When players try to stand
def blackjackStand(channel,user,handNumber = 0):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# When players try to stand
def blackjackStand(self,channel,user,handNumber = 0):
game = self.bot.database["blackjack games"].find_one({"_id":channel})
if user in data["blackjack games"][channel]["user hands"]:
if user in game["user hands"]:
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
hand, handNumber = self.getHandNumber(game["user hands"][user],handNumber)
if hand != None:
if data["blackjack games"][channel]["round"] > 0:
if game["round"] > 0:
if hand["hit"] == False:
if hand["standing"] == False:
hand["standing"] = True
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
if handNumber == 2:
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".other hand":hand}})
elif handNumber == 3:
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".third hand":hand}})
elif handNumber == 4:
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".fourth hand":hand}})
else:
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user:hand}})
response = "accept"
roundDone = isRoundDone(data["blackjack games"][channel])
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
return response + str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
return response + str(roundDone)[0] + str(game["round"])
else:
logThis(user+" is already standing")
return "You're already standing"
@ -350,52 +339,48 @@ def blackjackStand(channel,user,handNumber = 0):
logThis(user+" tried to stand without being in the game")
return "You have to enter the game before you can stand"
# When players try to split
def blackjackSplit(channel,user,handNumber = 0):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# When players try to split
def blackjackSplit(self,channel,user,handNumber = 0):
game = self.bot.database["blackjack games"].find_one({"_id":channel})
if data["blackjack games"][channel]["user hands"][user]["split"] == 0:
hand = data["blackjack games"][channel]["user hands"][user]
newHand = data["blackjack games"][channel]["user hands"][user]["other hand"]
if game["user hands"][user]["split"] == 0:
hand = game["user hands"][user]
newHand = game["user hands"][user]["other hand"]
handNumber = 0
otherHand = 2
else:
if handNumber != 0:
if handNumber == 1:
hand = data["blackjack games"][channel]["user hands"][user]
hand = game["user hands"][user]
elif handNumber == 2:
hand = data["blackjack games"][channel]["user hands"][user]["other hand"]
hand = game["user hands"][user]["other hand"]
elif handNumber == 3:
hand = data["blackjack games"][channel]["user hands"][user]["third hand"]
hand = game["user hands"][user]["third hand"]
else:
logThis(user+" tried to hit without specifying which hand")
return "You have to specify the hand you're hitting with."
if data["blackjack games"][channel]["user hands"][user]["split"] == 1:
newHand = data["blackjack games"][channel]["user hands"][user]["third hand"]
if game["user hands"][user]["split"] == 1:
newHand = game["user hands"][user]["third hand"]
otherHand = 3
else:
newHand = data["blackjack games"][channel]["user hands"][user]["fourth hand"]
newHand = game["user hands"][user]["fourth hand"]
otherHand = 4
else:
logThis(user+" tried to split without specifying which hand")
return "You have to specify the hand you're splitting.",""
if data["blackjack games"][channel]["user hands"][user]["split"] < 3:
if data["blackjack games"][channel]["round"] != 0:
if game["user hands"][user]["split"] < 3:
if game["round"] != 0:
if hand["hit"] == False:
if hand["standing"] == False:
if len(hand["hand"]) == 2:
firstCard = calcHandValue([hand["hand"][0]])
secondCard = calcHandValue([hand["hand"][1]])
firstCard = self.calcHandValue([hand["hand"][0]])
secondCard = self.calcHandValue([hand["hand"][1]])
if firstCard == secondCard:
bet = hand["bet"]
if money.checkBalance(user) >= bet:
money.addMoney(user,-1 * bet)
with open("resources/games/games.json", "r") as f:
data = json.load(f)
if self.bot.money.checkBalance(user) >= bet:
self.bot.money.addMoney(user,-1 * bet)
hand["hit"] = True
newHand["hit"] = True
@ -407,11 +392,11 @@ def blackjackSplit(channel,user,handNumber = 0):
newHand["bet"] = hand["bet"]
newHand["hand"].append(hand["hand"].pop(1))
newHand["hand"].append(drawCard(channel))
hand["hand"].append(drawCard(channel))
newHand["hand"].append(self.drawCard(channel))
hand["hand"].append(self.drawCard(channel))
handValue = calcHandValue(hand["hand"])
otherHandValue = calcHandValue(newHand["hand"])
handValue = self.calcHandValue(hand["hand"])
otherHandValue = self.calcHandValue(newHand["hand"])
if handValue > 21:
hand["busted"] = True
elif handValue == 21:
@ -423,27 +408,31 @@ def blackjackSplit(channel,user,handNumber = 0):
newHand["blackjack"] = True
if handNumber == 2:
data["blackjack games"][channel]["user hands"][user]["other hand"] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".other hand":hand}})
elif handNumber == 3:
data["blackjack games"][channel]["user hands"][user]["third hand"] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".third hand":hand}})
else:
data["blackjack games"][channel]["user hands"][user] = hand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user:hand}})
if otherHand == 3:
data["blackjack games"][channel]["user hands"][user]["third hand"] = newHand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".third hand":newHand}})
elif otherHand == 4:
data["blackjack games"][channel]["user hands"][user]["fourth hand"] = newHand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".fourth hand":newHand}})
else:
data["blackjack games"][channel]["user hands"][user]["other hand"] = newHand
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user+".other hand":newHand}})
data["blackjack games"][channel]["user hands"][user]["split"] += 1
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$inc":{"user hands."+user+".split":1}})
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
roundDone = self.isRoundDone(self.bot.database["blackjack games"].find_one({"_id":channel}))
roundDone = isRoundDone(data["blackjack games"][channel])
return "Splitting "+getName(user)+"'s hand into 2. Adding their original bet to the second hand. You can use \"!Blackjack hit/stand/double 1\" and \"!Blackjack hit/stand/double 2\" to play the different hands.",str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
return "Splitting "+self.bot.funcs.getName(user)+"'s hand into 2. Adding their original bet to the second hand. You can use \"!Blackjack hit/stand/double 1\" and \"!Blackjack hit/stand/double 2\" to play the different hands.",str(roundDone)[0] + str(game["round"])
else:
logThis(user+" doesn't have enough GwendoBucks")
return "You don't have enough GwendoBucks",""
@ -466,41 +455,36 @@ def blackjackSplit(channel,user,handNumber = 0):
logThis(user+" tried to split more than three times")
return "You can only split 3 times",""
# Player enters the game and draws a hand
def blackjackPlayerDrawHand(channel,user,bet):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# Player enters the game and draws a hand
def blackjackPlayerDrawHand(self,channel,user,bet):
game = self.bot.database["blackjack games"].find_one({"_id":channel})
logThis(getName(user)+" is trying to join the game in "+channel)
logThis(self.bot.funcs.getName(user)+" is trying to join the game in "+channel)
if channel in data["blackjack games"]:
if user not in data["blackjack games"][channel]["user hands"]:
if len(data["blackjack games"][channel]["user hands"]) < 5:
if data["blackjack games"][channel]["round"] == 0:
if game != None:
if user not in game["user hands"]:
if len(game["user hands"]) < 5:
if game["round"] == 0:
if bet >= 0:
if money.checkBalance(user) >= bet:
money.addMoney(user,-1 * bet)
playerHand = [drawCard(channel),drawCard(channel)]
if self.bot.money.checkBalance(user) >= bet:
self.bot.money.addMoney(user,-1 * bet)
playerHand = [self.drawCard(channel),self.drawCard(channel)]
handValue = calcHandValue(playerHand)
with open("resources/games/games.json", "r") as f:
data = json.load(f)
handValue = self.calcHandValue(playerHand)
if handValue == 21:
data["blackjack games"][channel]["user hands"][user] = {"hand":playerHand,
"bet":bet,"standing":False,"busted":False,"blackjack":True,"hit":True,
"doubled":False,"split":0,"other hand":{},"third hand":{},"fourth hand":{}}
blackjackHand = True
else:
data["blackjack games"][channel]["user hands"][user] = {"hand":playerHand,
"bet":bet,"standing":False,"busted":False,"blackjack":False,"hit":True,
blackjackHand = False
newHand = {"hand":playerHand,
"bet":bet,"standing":False,"busted":False,"blackjack":blackjackHand,"hit":True,
"doubled":False,"split":0,"other hand":{},"third hand":{},"fourth hand":{}}
self.bot.database["blackjack games"].update_one({"_id":channel},
{"$set":{"user hands."+user:newHand}})
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
logThis(getName(user)+" entered the game")
return getName(user)+" entered the game"
logThis(self.bot.funcs.getName(user)+" entered the game")
return self.bot.funcs.getName(user)+" entered the game"
else:
logThis(user+" doesn't have enough GwendoBucks")
return "You don't have enough GwendoBucks to place that bet"
@ -520,25 +504,23 @@ def blackjackPlayerDrawHand(channel,user,bet):
logThis("There is no game going on in "+channel)
return "There is no game going on in this channel"
# Starts a game of blackjack
def blackjackStart(channel:str):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# Starts a game of blackjack
def blackjackStart(self,channel:str):
game = self.bot.database["blackjack games"].find_one({"_id":channel})
logThis("Trying to start a blackjack game in "+channel)
if channel not in data["blackjack games"]:
if game == None:
dealerHand = [drawCard(channel),drawCard(channel)]
dealerHand = [self.drawCard(channel),self.drawCard(channel)]
gameID = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
data["blackjack games"][channel] = {"dealer hand": dealerHand,"dealer busted":False,"dealer blackjack":False,"user hands": {},"all standing":False,"round":0,"id":gameID}
newGame = {"_id":channel,"dealer hand": dealerHand,"dealer busted":False,"dealer blackjack":False,"user hands": {},"all standing":False,"round":0,"gameID":gameID}
if calcHandValue(dealerHand) == 21:
data["blackjack games"][channel]["dealer blackjack"] = True
if self.calcHandValue(dealerHand) == 21:
newGame["dealer blackjack"] = True
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["blackjack games"].insert_one(newGame)
copyfile("resources/games/blackjackTable.png","resources/games/blackjackTables/blackjackTable"+channel+".png")
@ -547,59 +529,52 @@ def blackjackStart(channel:str):
logThis("There is already a blackjack game going on in "+channel)
return "There's already a blackjack game going on. Try again in a few minutes."
# Ends the game and calculates winnings
def blackjackFinish(channel):
# Ends the game and calculates winnings
def blackjackFinish(self,channel):
finalWinnings = "*Final Winnings:*\n"
with open("resources/games/games.json", "r") as f:
data = json.load(f)
game = self.bot.database["blackjack games"].find_one({"_id":channel})
dealerValue = calcHandValue(data["blackjack games"][channel]["dealer hand"])
dealerBlackjack = data["blackjack games"][channel]["dealer blackjack"]
dealerBusted = data["blackjack games"][channel]["dealer busted"]
dealerValue = self.calcHandValue(game["dealer hand"])
dealerBlackjack = game["dealer blackjack"]
dealerBusted = game["dealer busted"]
try:
for user in data["blackjack games"][channel]["user hands"]:
for user in game["user hands"]:
try:
winnings, netWinnings, reason = calcWinnings(data["blackjack games"][channel]["user hands"][user],dealerValue,True,dealerBlackjack,dealerBusted)
winnings, netWinnings, reason = self.calcWinnings(game["user hands"][user],dealerValue,True,dealerBlackjack,dealerBusted)
except:
logThis("Error calculating winnings for "+str(user)+" (error code 1312)")
if winnings < 0:
if winnings == -1:
finalWinnings += getName(user)+" lost "+str(-1 * winnings)+" GwendoBuck "+reason+"\n"
finalWinnings += self.bot.funcs.getName(user)+" lost "+str(-1 * winnings)+" GwendoBuck "+reason+"\n"
else:
finalWinnings += getName(user)+" lost "+str(-1 * winnings)+" GwendoBucks "+reason+"\n"
finalWinnings += self.bot.funcs.getName(user)+" lost "+str(-1 * winnings)+" GwendoBucks "+reason+"\n"
else:
if winnings == 1:
finalWinnings += getName(user)+" won "+str(winnings)+" GwendoBuck "+reason+"\n"
finalWinnings += self.bot.funcs.getName(user)+" won "+str(winnings)+" GwendoBuck "+reason+"\n"
else:
finalWinnings += getName(user)+" won "+str(winnings)+" GwendoBucks "+reason+"\n"
finalWinnings += self.bot.funcs.getName(user)+" won "+str(winnings)+" GwendoBucks "+reason+"\n"
money.addMoney(user,netWinnings)
self.bot.money.addMoney(user,netWinnings)
except:
logThis("Error calculating winnings (error code 1311)")
with open("resources/games/games.json", "r") as f:
data = json.load(f)
del data["blackjack games"][channel]
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["blackjack games"].delete_one({"_id":channel})
return finalWinnings
def calcWinnings(hand, dealerValue, topLevel, dealerBlackjack, dealerBusted):
def calcWinnings(self,hand, dealerValue, topLevel, dealerBlackjack, dealerBusted):
logThis("Calculating winnings")
reason = ""
bet = hand["bet"]
winnings = -1 * bet
netWinnings = 0
handValue = calcHandValue(hand["hand"])
handValue = self.calcHandValue(hand["hand"])
if hand["blackjack"] and dealerBlackjack == False:
reason += "(blackjack)"
@ -628,24 +603,24 @@ def calcWinnings(hand, dealerValue, topLevel, dealerBlackjack, dealerBusted):
if topLevel:
if hand["split"] >= 1:
winningsTemp, netWinningsTemp, reasonTemp = calcWinnings(hand["other hand"],dealerValue,False,dealerBlackjack,dealerBusted)
winningsTemp, netWinningsTemp, reasonTemp = self.calcWinnings(hand["other hand"],dealerValue,False,dealerBlackjack,dealerBusted)
winnings += winningsTemp
netWinnings += netWinningsTemp
reason += reasonTemp
if hand["split"] >= 2:
winningsTemp, netWinningsTemp, reasonTemp = calcWinnings(hand["third hand"],dealerValue,False,dealerBlackjack,dealerBusted)
winningsTemp, netWinningsTemp, reasonTemp = self.calcWinnings(hand["third hand"],dealerValue,False,dealerBlackjack,dealerBusted)
winnings += winningsTemp
netWinnings += netWinningsTemp
reason += reasonTemp
if hand["split"] >= 3:
winningsTemp, netWinningsTemp, reasonTemp = calcWinnings(hand["fourth hand"],dealerValue,False,dealerBlackjack,dealerBusted)
winningsTemp, netWinningsTemp, reasonTemp = self.calcWinnings(hand["fourth hand"],dealerValue,False,dealerBlackjack,dealerBusted)
winnings += winningsTemp
netWinnings += netWinningsTemp
reason += reasonTemp
return winnings, netWinnings, reason
def getHandNumber(user,handNumber):
def getHandNumber(self, user,handNumber):
try:
hand = None
@ -667,7 +642,7 @@ def getHandNumber(user,handNumber):
except:
logThis("Problem with getHandNumber() (error code 1322)")
def isRoundDone(game):
def isRoundDone(self,game):
roundDone = True
for person in game["user hands"].values():
@ -687,3 +662,224 @@ def isRoundDone(game):
roundDone = False
return roundDone
# Loop of blackjack game rounds
async def blackjackLoop(self,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 = self.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)")
game = self.bot.database["blackjack games"].find_one({"_id":str(channel.id)})
if game != None:
realRound = game["round"]
realGameID = game["gameID"]
if gameRound == realRound and realGameID == gameID:
if gamedone == False:
logThis("Loop "+str(gameRound)+" calling self.blackjackLoop()",str(channel.id))
await self.blackjackLoop(channel,gameRound+1,gameID)
else:
try:
new_message = self.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(self,content, ctx):
# Blackjack shuffle variables
blackjackMinCards = 50
blackjackDecks = 4
channel = ctx.message.channel.id
# Starts the game
if content == "":
cardsLeft = 0
cards = self.bot.database["blackjack cards"].find_one({"_id":str(channel)})
if cards != None:
cardsLeft = len(cards["cards"])
# Shuffles if not enough cards
if cardsLeft < blackjackMinCards:
self.blackjackShuffle(blackjackDecks,str(channel))
logThis("Shuffling the blackjack deck...",str(channel))
await ctx.send("Shuffling the deck...")
new_message = self.blackjackStart(str(channel))
if new_message == "started":
new_message = "Blackjack game started. Use \"!blackjack bet [amount]\" to enter the game within the next 30 seconds."
await ctx.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
game = self.bot.database["blackjack games"].find_one({"_id":str(channel)})
if len(game["user hands"]) == 0:
gamedone = True
await ctx.send("No one entered the game. Ending the game.")
gameID = game["gameID"]
# Loop of game rounds
if gamedone == False:
logThis("!blackjack calling self.blackjackLoop()",str(channel))
await self.blackjackLoop(ctx.message.channel,1,gameID)
else:
new_message = self.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 = self.blackjackPlayerDrawHand(str(channel),"#"+str(ctx.message.author.id),amount)
await ctx.send(response)
# Hitting
elif content.startswith("hit"):
if content == "hit":
response = self.blackjackHit(str(channel),"#"+str(ctx.message.author.id))
else:
commands = content.split(" ")
try:
handNumber = int(commands[1])
except:
handNumber = 0
response = self.blackjackHit(str(channel),"#"+str(ctx.message.author.id),handNumber)
if response.startswith("accept"):
await ctx.message.add_reaction("👍")
#try:
if response[6] == "T":
gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"]
logThis("Hit calling self.blackjackLoop()",str(channel))
await self.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 = self.blackjackStand(str(channel),"#"+str(ctx.message.author.id))
else:
commands = content.split(" ")
try:
handNumber = int(commands[1])
except:
handNumber = 0
response = self.blackjackStand(str(channel),"#"+str(ctx.message.author.id),handNumber)
if response.startswith("accept"):
await ctx.message.add_reaction("👍")
#try:
if response[6] == "T":
gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"]
logThis("Stand calling self.blackjackLoop()",str(channel))
await self.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 = self.blackjackDouble(str(channel),"#"+str(ctx.message.author.id),handNumber)
await ctx.send(response)
try:
if roundDone[0] == "T":
gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"]
logThis("Double calling self.blackjackLoop()",str(channel))
await self.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 = self.blackjackSplit(str(channel),"#"+str(ctx.message.author.id),handNumber)
await ctx.send(response)
try:
if roundDone[0] == "T":
gameID = self.bot.database["blackjack games"].find_one({"_id":str(channel)})["gameID"]
logThis("Split calling self.blackjackLoop()",str(channel))
await self.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":
data = self.bot.database["hilo"].find_one({"_id":str(channel)})
if data != None:
hilo = str(data["hilo"])
else:
hilo = "0"
await ctx.send(hilo)
# Shuffles the blackjack deck
elif content.startswith("shuffle"):
self.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
cards = self.bot.database["blackjack cards"].find_one({"_id":str(channel)})
if cards != None:
cardsLeft = len(cards["cards"])
decksLeft = round(cardsLeft/52,1)
await ctx.send(str(cardsLeft)+" cards, "+str(decksLeft)+" decks")
else:
logThis("Not a command (error code 1301)")
await ctx.send("I didn't quite understand that (error code 1301)")

View File

@ -1,15 +1,17 @@
import json
from PIL import Image, ImageDraw, ImageFont
from funcs import logThis, getName
from funcs import logThis
border = 100
placement = [0,0]
rotation = 0
def drawImage(channel):
class DrawBlackjack():
def __init__(self,bot):
self.bot = bot
def drawImage(self,channel):
logThis("Drawing blackjack table",channel)
with open("resources/games/games.json", "r") as f:
data = json.load(f)
game = self.bot.database["blackjack games"].find_one({"_id":channel})
fnt = ImageFont.truetype('resources/futura-bold.ttf', 50)
fntSmol = ImageFont.truetype('resources/futura-bold.ttf', 40)
@ -18,16 +20,16 @@ def drawImage(channel):
table = Image.open("resources/games/blackjackTable.png")
placement = [2,1,3,0,4]
textImage = ImageDraw.Draw(table)
hands = data["blackjack games"][channel]["user hands"]
hands = game["user hands"]
dealerBusted = data["blackjack games"][channel]["dealer busted"]
dealerBlackjack = data["blackjack games"][channel]["dealer blackjack"]
dealerBusted = game["dealer busted"]
dealerBlackjack = game["dealer blackjack"]
try:
if data["blackjack games"][channel]["all standing"] == False:
dealerHand = drawHand(data["blackjack games"][channel]["dealer hand"],True,False,False)
if game["all standing"] == False:
dealerHand = self.drawHand(game["dealer hand"],True,False,False)
else:
dealerHand = drawHand(data["blackjack games"][channel]["dealer hand"],False,dealerBusted,dealerBlackjack)
dealerHand = self.drawHand(game["dealer hand"],False,dealerBusted,dealerBlackjack)
except:
logThis("Error drawing dealer hand (error code 1341a)")
@ -35,27 +37,27 @@ def drawImage(channel):
for x in range(len(hands)):
key, value = list(hands.items())[x]
key = getName(key)
key = self.bot.funcs.getName(key)
#logThis("Drawing "+key+"'s hand")
userHand = drawHand(value["hand"],False,value["busted"],value["blackjack"])
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 = drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
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 = drawHand(value["third hand"]["hand"],False,value["third hand"]["busted"],value["third hand"]["blackjack"])
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 = drawHand(value["fourth hand"]["hand"],False,value["fourth hand"]["busted"],value["fourth hand"]["blackjack"])
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 = drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
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 = drawHand(value["third hand"]["hand"],False,value["third hand"]["busted"],value["third hand"]["blackjack"])
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 = drawHand(value["other hand"]["hand"],False,value["other hand"]["busted"],value["other hand"]["blackjack"])
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)
@ -82,8 +84,8 @@ def drawImage(channel):
return
def drawHand(hand, dealer, busted, blackjack):
logThis("Drawing hand "+str(hand))
def drawHand(self, hand, dealer, busted, blackjack):
logThis("Drawing hand "+str(hand)+", "+str(busted)+", "+str(blackjack))
fnt = ImageFont.truetype('resources/futura-bold.ttf', 200)
fnt2 = ImageFont.truetype('resources/futura-bold.ttf', 120)
length = len(hand)

View File

@ -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)")

View File

@ -1,11 +1,10 @@
import json
import random
import copy
import math
import asyncio
from . import fourInARowDraw
from funcs import logThis, getName, getID
from .fourInARowDraw import DrawFourInARow
from funcs import logThis
AIScores = {
"middle": 3,
@ -22,12 +21,16 @@ rowCount = 6
columnCount = 7
easy = True
# Starts the game
def fourInARowStart(channel, user, opponent):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
class FourInARow():
def __init__(self,bot):
self.bot = bot
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 game == None:
if opponent in ["1","2","3","4","5"]:
difficulty = int(opponent)
@ -43,7 +46,7 @@ def fourInARowStart(channel, user, opponent):
return "That difficulty doesn't exist", False, False, False, False
except:
# Opponent is another player
opponent = getID(opponent)
opponent = self.bot.funcs.getID(opponent)
if opponent != None:
difficulty = 5
diffText = ""
@ -57,80 +60,72 @@ def fourInARowStart(channel, user, opponent):
players = [user,opponent]
random.shuffle(players)
data["4 in a row games"][channel] = {"board": board,"winner":0,"win direction":"",
newGame = {"_id":channel,"board": board,"winner":0,"win direction":"",
"win coordinates":[0,0],"players":players,"turn":0,"difficulty":difficulty}
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["4 in a row games"].insert_one(newGame)
fourInARowDraw.drawImage(channel)
self.draw.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
return "Started game against "+self.bot.funcs.getName(opponent)+diffText+". It's "+self.bot.funcs.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)
# Places a piece at the lowest available point in a specific column
def placePiece(self, channel : str,player : int,column : int):
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
if channel in data["4 in a row games"]:
board = data["4 in a row games"][channel]["board"]
board = placeOnBoard(board,player,column)
if game != None:
board = game["board"]
board = self.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)
self.bot.database["4 in a row games"].update_one({"_id":channel},{"$set":{"board":board}})
turn = (game["turn"]+1)%2
self.bot.database["4 in a row games"].update_one({"_id":channel},{"$set":{"turn":turn}})
logThis("Checking for win")
won, winDirection, winCoordinates = isWon(data["4 in a row games"][channel]["board"])
won, winDirection, winCoordinates = self.isWon(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
self.bot.database["4 in a row games"].update_one({"_id":channel},{"$set":{"winner":won}})
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}})
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 = self.bot.funcs.getName(game["players"][won-1])+" placed a piece in column "+str(column+1)+" and won."
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 = 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."
with open("resources/games/games.json", "w") as f:
json.dump(data,f,indent=4)
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 data["4 in a row games"][channel]["players"][turn] == "Gwendolyn":
if game["players"][turn] == "Gwendolyn":
logThis("It's Gwendolyn's turn")
gwendoTurn = True
fourInARowDraw.drawImage(channel)
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:
return "There's no game in this channel", False, False, False, False
# Returns a board where a piece has been placed in the column
def placeOnBoard(board,player,column):
# Returns a board where a piece has been placed in the column
def placeOnBoard(self,board,player,column):
placementx, placementy = -1, column
for x in range(len(board)):
@ -144,8 +139,8 @@ def placeOnBoard(board,player,column):
else:
return board
# Parses command
def parseFourInARow(command, channel, user):
# Parses command
def parseFourInARow(self, command, channel, user):
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
@ -153,14 +148,13 @@ def parseFourInARow(command, channel, user):
# 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
return self.fourInARowStart(channel,user,commands[1]) # commands[1] is the opponent
# Stopping the game
elif commands[0] == "stop":
with open("resources/games/games.json", "r") as f:
data = json.load(f)
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
if user in data["4 in a row games"][channel]["players"]:
if user in game["players"]:
return "Ending game.", False, False, True, False
else:
return "You can't end a game where you're not a player.", False, False, False, False
@ -168,14 +162,14 @@ def parseFourInARow(command, channel, user):
# Placing manually
elif commands[0] == "place":
try:
return placePiece(channel,int(commands[1]),int(commands[2])-1)
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 if someone has won the game and returns the winner
def isWon(board):
# Checks if someone has won the game and returns the winner
def isWon(self, board):
won = 0
winDirection = ""
winCoordinates = [0,0]
@ -232,22 +226,21 @@ def isWon(board):
return won, winDirection, winCoordinates
# Plays as the AI
async def fourInARowAI(channel):
# Plays as the AI
async def fourInARowAI(self, channel):
logThis("Figuring out best move")
with open("resources/games/games.json", "r") as f:
data = json.load(f)
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
board = data["4 in a row games"][channel]["board"]
player = data["4 in a row games"][channel]["players"].index("Gwendolyn")+1
difficulty = data["4 in a row games"][channel]["difficulty"]
board = game["board"]
player = game["players"].index("Gwendolyn")+1
difficulty = game["difficulty"]
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)
testBoard = self.placeOnBoard(testBoard,player,column)
if testBoard != None:
scores[column] = await minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False)
scores[column] = await self.minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False)
logThis("Best score for column "+str(column)+" is "+str(scores[column]))
possibleScores = scores.copy()
@ -259,10 +252,10 @@ async def fourInARowAI(channel):
indices = [i for i, x in enumerate(scores) if x == highest_score]
placement = random.choice(indices)
return placePiece(channel,player,placement)
return self.placePiece(channel,player,placement)
# Calculates points for a board
def AICalcPoints(board,player):
# Calculates points for a board
def AICalcPoints(self,board,player):
score = 0
otherPlayer = player%2+1
@ -274,24 +267,24 @@ def AICalcPoints(board,player):
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)
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 += evaluateWindow(window,player,otherPlayer)
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 += evaluateWindow(window,player,otherPlayer)
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 += evaluateWindow(window,player,otherPlayer)
score += self.evaluateWindow(window,player,otherPlayer)
## Checks if anyone has won
@ -304,7 +297,7 @@ def AICalcPoints(board,player):
return score
def evaluateWindow(window,player,otherPlayer):
def evaluateWindow(self, window,player,otherPlayer):
if window.count(player) == 4:
return AIScores["win"]
elif window.count(player) == 3 and window.count(0) == 1:
@ -316,10 +309,10 @@ def evaluateWindow(window,player,otherPlayer):
else:
return 0
async def minimax(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer):
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 = AICalcPoints(board,originalPlayer)
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
@ -327,9 +320,9 @@ async def minimax(board, depth, player , originalPlayer, alpha, beta, maximizing
value = -math.inf
for column in range(0,columnCount):
testBoard = copy.deepcopy(board)
testBoard = placeOnBoard(testBoard,player,column)
testBoard = self.placeOnBoard(testBoard,player,column)
if testBoard != None:
evaluation = await minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,False)
evaluation = await self.minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,False)
if evaluation < -9000: evaluation += AIScores["avoid losing"]
value = max(value,evaluation)
alpha = max(alpha,evaluation)
@ -339,9 +332,9 @@ async def minimax(board, depth, player , originalPlayer, alpha, beta, maximizing
value = math.inf
for column in range(0,columnCount):
testBoard = copy.deepcopy(board)
testBoard = placeOnBoard(testBoard,player,column)
testBoard = self.placeOnBoard(testBoard,player,column)
if testBoard != None:
evaluation = await minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,True)
evaluation = await self.minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,True)
if evaluation < -9000: evaluation += AIScores["avoid losing"]
value = min(value,evaluation)
beta = min(beta,evaluation)

View File

@ -1,16 +1,18 @@
import json
import math
from PIL import Image, ImageDraw, ImageFont
from funcs import logThis, getName
from funcs import logThis
# Draws the whole thing
def drawImage(channel):
class DrawFourInARow():
def __init__(self,bot):
self.bot = bot
# Draws the whole thing
def drawImage(self, channel):
logThis("Drawing four in a row board")
with open("resources/games/games.json", "r") as f:
data = json.load(f)
game = self.bot.database["4 in a row games"].find_one({"_id":channel})
board = data["4 in a row games"][channel]["board"]
board = game["board"]
border = 40
gridBorder = 40
@ -39,15 +41,15 @@ def drawImage(channel):
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":
if game["players"][0] == "Gwendolyn":
player1 = "Gwendolyn"
else:
player1 = getName(data["4 in a row games"][channel]["players"][0])
player1 = self.bot.funcs.getName(game["players"][0])
if data["4 in a row games"][channel]["players"][1] == "Gwendolyn":
if game["players"][1] == "Gwendolyn":
player2 = "Gwendolyn"
else:
player2 = getName(data["4 in a row games"][channel]["players"][1])
player2 = self.bot.funcs.getName(game["players"][1])
background = Image.new("RGB", (w,h+bottomBorder),backgroundColor)
@ -88,8 +90,8 @@ def drawImage(channel):
d.ellipse([(startx,starty),(startx+placeSize,starty+placeSize)],fill=pieceColor,outline=outlineColor,width=outlineWidth)
if data["4 in a row games"][channel]["winner"] != 0:
coordinates = data["4 in a row games"][channel]["win coordinates"]
if game["winner"] != 0:
coordinates = game["win coordinates"]
startx = border + placeGridSize[0]*coordinates[1] + gridBorder
starty = border + placeGridSize[1]*coordinates[0] + gridBorder
a = (placeGridSize[0]*4-gridBorder-border)**2
@ -97,21 +99,21 @@ def drawImage(channel):
diagonalLength = (math.sqrt(a+b))/placeGridSize[0]
diagonalAngle = math.degrees(math.atan(placeGridSize[1]/placeGridSize[0]))
if data["4 in a row games"][channel]["win direction"] == "h":
if game["win direction"] == "h":
winBar = Image.new("RGBA",(placeGridSize[0]*4,placeGridSize[1]),(0,0,0,0))
winD = ImageDraw.Draw(winBar)
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=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)
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))
winD = ImageDraw.Draw(winBar)
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],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)
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))
winD = ImageDraw.Draw(winBar)
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)
@ -121,7 +123,7 @@ def drawImage(channel):
startx -= 90
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))
winD = ImageDraw.Draw(winBar)
winD.ellipse([(0,0),(placeGridSize[0],placeGridSize[1])],fill=white)

View File

@ -1,16 +1,15 @@
import asyncio
import discord
import json
from funcs import logThis, deleteGame
from .money import addMoney
from .fourInARow import parseFourInARow, fourInARowAI
from .hex import parseHex, hexAI
from .monopoly import parseMonopoly, monopolyContinue
from .hangman import parseHangman
from funcs import logThis
# Deletes a message
async def deleteMessage(imageLocation,channel):
class GameLoops():
def __init__(self,bot):
self.bot = bot
# Deletes a message
async def deleteMessage(self, imageLocation,channel):
try:
with open("resources/games/oldImages/"+imageLocation, "r") as f:
messages = f.read().splitlines()
@ -24,61 +23,10 @@ async def deleteMessage(imageLocation,channel):
return oldMessage
# Runs Hex
async def runHex(channel,command,user):
# Runs Four in a Row
async def fiar(self, 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)
# Runs Four in a Row
async def fiar(channel,command,user):
try:
response, showImage, deleteImage, gameDone, gwendoTurn = parseFourInARow(command,str(channel.id),user)
response, showImage, deleteImage, gameDone, gwendoTurn = self.bot.fourInARow.parseFourInARow(command,str(channel.id),user)
except:
logThis("Error parsing command (error code 1410)")
@ -87,14 +35,14 @@ async def fiar(channel,command,user):
if showImage:
if deleteImage:
try:
oldImage = await deleteMessage("fourInARow"+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 fourInARowAI(str(channel.id))
response, showImage, deleteImage, gameDone, gwendoTurn = await self.bot.fourInARow.fourInARowAI(str(channel.id))
except:
logThis("AI error (error code 1420)")
await channel.send(response)
@ -125,8 +73,7 @@ async def fiar(channel,command,user):
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)
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:
@ -136,20 +83,18 @@ async def fiar(channel,command,user):
except:
logThis("The old image was already deleted")
winner = data["4 in a row games"][str(channel.id)]["winner"]
difficulty = int(data["4 in a row games"][str(channel.id)]["difficulty"])
winner = game["winner"]
difficulty = int(game["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?
if game["players"][winner-1].lower() != "gwendolyn":
self.bot.money.addMoney(game["players"][winner-1].lower(),reward)
deleteGame("4 in a row games",str(channel.id))
self.bot.funcs.deleteGame("4 in a row games",str(channel.id))
async def runMonopoly(channel, command, user):
async def runMonopoly(self,channel, command, user):
try:
response, showImage, deleteImage, gameStarted, gameContinue = parseMonopoly(command,str(channel.id),user)
response, showImage, deleteImage, gameStarted, gameContinue = self.bot.monopoly.parseMonopoly(command,str(channel.id),user)
except:
logThis("Error parsing command (error code 1610)")
if response != "":
@ -158,7 +103,7 @@ async def runMonopoly(channel, command, user):
if showImage:
if deleteImage:
try:
oldImage = await deleteMessage("monopoly"+str(channel.id),channel)
oldImage = await self.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"))
@ -170,15 +115,16 @@ async def runMonopoly(channel, command, user):
await asyncio.sleep(60)
else:
await asyncio.sleep(3)
response, showImage, deleteImage, gameDone = monopolyContinue(str(channel.id))
response, showImage, deleteImage, gameDone = self.bot.monopoly.monopolyContinue(str(channel.id))
em = discord.Embed(description=response,colour = 0x59f442)
await channel.send(embed=em)
if showImage:
if deleteImage:
try:
oldImage = await deleteMessage("monopoly"+str(channel.id),channel)
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))
@ -188,9 +134,9 @@ async def runMonopoly(channel, command, user):
except:
logThis("Image deleted before I could react to all of them")
async def runHangman(channel,user,apiKey = "",command = "start"):
async def runHangman(self,channel,user,command = "start"):
try:
response, showImage, deleteImage, remainingLetters = parseHangman(str(channel.id),user,command,apiKey)
response, showImage, deleteImage, remainingLetters = self.bot.hangman.parseHangman(str(channel.id),user,command)
except:
logThis("Error parsing command (error code 1701)")
if response != "":
@ -198,7 +144,7 @@ async def runHangman(channel,user,apiKey = "",command = "start"):
logThis(response,str(channel.id))
if showImage:
if deleteImage:
await deleteMessage("hangman"+str(channel.id),channel)
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:
@ -221,3 +167,47 @@ async def runHangman(channel,user,apiKey = "",command = "start"):
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)
logThis(response,str(channel.id))
if showImage:
if deleteImage:
try:
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"))
else:
with open("resources/games/oldImages/hex"+str(channel.id), "w") as f:
f.write(str(oldImage.id))
if gameDone:
game = self.bot.database["hexGames"].find_one({"_id":str(channel.id)})
print(game)
winner = game["winner"]
if winner != 0 and game["players"][0] != game["players"][1]: # player1 != player2
winnings = game["difficulty"]*10
self.bot.money.addMoney(game["players"][winner-1].lower(),winnings)
self.bot.funcs.deleteGame("hex games",str(channel.id))

21
funcs/games/games.py Normal file
View 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)

View File

@ -1,68 +1,67 @@
import json, urllib, datetime, string
from . import hangmanDraw, money
from funcs import getName, logThis
from .hangmanDraw import DrawHangman
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="
def hangmanStart(channel,user,apiKey):
with open("resources/games/hangmanGames.json", "r") as f:
data = json.load(f)
class Hangman():
def __init__(self,bot):
self.bot = bot
self.draw = DrawHangman(bot)
if channel not in data:
def hangmanStart(self,channel,user):
game = self.bot.database["hangman games"].find_one({"_id":channel})
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')
data[channel] = {"player" : user,"guessed letters" : [],"word" : word,"game ID" : gameID,"misses" : 0,"guessed" : guessed}
newGame = {"_id":channel,"player" : user,"guessed letters" : [],"word" : word,"game ID" : gameID,"misses" : 0,"guessed" : guessed}
self.bot.database["hangman games"].insert_one(newGame)
remainingLetters = list(string.ascii_uppercase)
with open("resources/games/hangmanGames.json", "w") as f:
json.dump(data,f)
try:
hangmanDraw.drawImage(channel)
self.draw.drawImage(channel)
except:
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:
return "There's already a Hangman game going on in the channel", False, False, []
def hangmanStop(channel):
with open("resources/games/hangmanGames.json", "r") as f:
data = json.load(f)
del data[channel]
with open("resources/games/hangmanGames.json", "w") as f:
json.dump(data,f,indent=4)
def hangmanStop(self,channel):
self.bot.database["hangman games"].delete_one({"_id":channel})
return "Game stopped.", False, False, []
def hangmanGuess(channel,user,guess):
with open("resources/games/hangmanGames.json", "r") as f:
data = json.load(f)
def hangmanGuess(self,channel,user,guess):
game = self.bot.database["hangman games"].find_one({"_id":channel})
if channel in data:
if user == data[channel]["player"]:
if game != None:
if user == game["player"]:
if len(guess) == 1:
if guess not in data[channel]["guessed letters"]:
if guess not in game["guessed letters"]:
correctGuess = 0
for x, letter in enumerate(data[channel]["word"]):
for x, letter in enumerate(game["word"]):
if guess == letter:
correctGuess += 1
data[channel]["guessed"][x] = True
self.bot.database["hangman games"].update_one({"_id":channel},{"$set":{"guessed."+str(x):True}})
if correctGuess == 0:
data[channel]["misses"] += 1
self.bot.database["hangman games"].update_one({"_id":channel},{"$inc":{"misses":1}})
data[channel]["guessed letters"].append(guess)
self.bot.database["hangman games"].update_one({"_id":channel},{"$push":{"guessed letters":guess}})
remainingLetters = list(string.ascii_uppercase)
for letter in data[channel]["guessed letters"]:
game = self.bot.database["hangman games"].find_one({"_id":channel})
for letter in game["guessed letters"]:
remainingLetters.remove(letter)
if correctGuess == 1:
@ -70,20 +69,17 @@ def hangmanGuess(channel,user,guess):
else:
message = f"Guessed {guess}. There were {correctGuess} {guess}s in the word."
with open("resources/games/hangmanGames.json", "w") as f:
json.dump(data,f)
try:
hangmanDraw.drawImage(channel)
self.draw.drawImage(channel)
except:
logThis("Error drawing image (error code 1710)")
if data[channel]["misses"] == 6:
hangmanStop(channel)
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 data[channel]["guessed"]):
hangmanStop(channel)
money.addMoney(user,15)
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
@ -96,18 +92,18 @@ def hangmanGuess(channel,user,guess):
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":
try:
return hangmanStart(channel,user,apiKey)
return self.hangmanStart(channel,user)
except:
logThis("Error starting game (error code 1730)")
elif command == "stop":
return hangmanStop(channel)
return self.hangmanStop(channel)
elif command.startswith("guess "):
guess = command[6:].upper()
try:
return hangmanGuess(channel,user,guess)
return self.hangmanGuess(channel,user,guess)
except:
logThis("Error in guessing (Error Code 1720)")
else:

View File

@ -1,4 +1,4 @@
import math, random, json
import math, random
from PIL import ImageDraw, Image, ImageFont
from funcs import logThis
@ -28,7 +28,11 @@ smolfnt = ImageFont.truetype('resources/comic-sans-bold.ttf', textSize)
backgroundColor = (255,255,255,255)
def calcDeviance(preDev,preDevAcc,posChange,maxmin,maxAcceleration):
class DrawHangman():
def __init__(self,bot):
self.bot = bot
def calcDeviance(self,preDev,preDevAcc,posChange,maxmin,maxAcceleration):
devAcc = preDevAcc + random.uniform(-posChange,posChange)
if devAcc > maxmin * maxAcceleration: devAcc = maxmin * maxAcceleration
elif devAcc < -maxmin * maxAcceleration: devAcc = -maxmin * maxAcceleration
@ -38,7 +42,7 @@ def calcDeviance(preDev,preDevAcc,posChange,maxmin,maxAcceleration):
elif dev < -maxmin: dev = -maxmin
return dev, devAcc
def badCircle():
def badCircle(self):
background = Image.new("RGBA",(circleSize+(lineWidth*3),circleSize+(lineWidth*3)),color=(0,0,0,0))
d = ImageDraw.Draw(background,"RGBA")
@ -51,8 +55,8 @@ def badCircle():
degreesAmount = circleDegrees + random.randint(-10,30)
for degree in range(degreesAmount):
devx, devAccx = calcDeviance(devx,devAccx,lineWidth/100,lineWidth,0.03)
devy, devAccy = calcDeviance(devy,devAccy,lineWidth/100,lineWidth,0.03)
devx, devAccx = self.calcDeviance(devx,devAccx,lineWidth/100,lineWidth,0.03)
devy, devAccy = self.calcDeviance(devy,devAccy,lineWidth/100,lineWidth,0.03)
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
@ -61,7 +65,7 @@ def badCircle():
return background
def badLine(length, rotated = False):
def badLine(self, length, rotated = False):
if rotated:
w, h = length+lineWidth*3, lineWidth*3
else:
@ -75,8 +79,8 @@ def badLine(length, rotated = False):
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)
devx, devAccx = self.calcDeviance(devx,devAccx,lineWidth/1000,lineWidth,0.004)
devy, devAccy = self.calcDeviance(devy,devAccy,lineWidth/1000,lineWidth,0.004)
if rotated:
x = lineWidth + pixel + devx
@ -89,14 +93,14 @@ def badLine(length, rotated = False):
return background
def drawMan(misses):
def drawMan(self, misses):
background = Image.new("RGBA",(manx,many),color=(0,0,0,0))
if misses >= 1:
head = badCircle()
head = self.badCircle()
background.paste(head,(int((manx-(circleSize+(lineWidth*3)))/2),0),head)
if misses >= 2:
body = badLine(bodySize)
body = self.badLine(bodySize)
background.paste(body,(int((manx-(lineWidth*3))/2),circleSize),body)
if misses >= 3:
@ -105,7 +109,7 @@ def drawMan(misses):
for limb in limbs:
if limb == "ra":
limbDrawing = badLine(limbSize,True)
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)
@ -113,7 +117,7 @@ def drawMan(misses):
limbDrawing = limbDrawing.rotate(rotation,expand=1)
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
elif limb == "la":
limbDrawing = badLine(limbSize,True)
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)
@ -121,14 +125,14 @@ def drawMan(misses):
limbDrawing = limbDrawing.rotate(rotation,expand=1)
background.paste(limbDrawing,(xpos,ypos),limbDrawing)
elif limb == "rl":
limbDrawing = badLine(limbSize,True)
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 = badLine(limbSize,True)
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
@ -137,7 +141,7 @@ def drawMan(misses):
return background
def badText(text, big, color=(0,0,0,255)):
def badText(self, text, big, color=(0,0,0,255)):
if big: font = fnt
else: font = smolfnt
w, h = font.getsize(text)
@ -147,41 +151,41 @@ def badText(text, big, color=(0,0,0,255)):
d.text((0,0),text,font=font,fill=color)
return img
def drawGallows():
def drawGallows(self):
background = Image.new("RGBA",(gallowx,gallowy),color=(0,0,0,0))
bottomLine = badLine(int(gallowx*0.75),True)
bottomLine = self.badLine(int(gallowx*0.75),True)
background.paste(bottomLine,(int(gallowx*0.125),gallowy-(lineWidth*4)),bottomLine)
lineTwo = badLine(gallowy-lineWidth*6)
lineTwo = self.badLine(gallowy-lineWidth*6)
background.paste(lineTwo,(int(gallowx*(0.75*goldenRatio)),lineWidth*2),lineTwo)
topLine = badLine(int(gallowy*0.30),True)
topLine = self.badLine(int(gallowy*0.30),True)
background.paste(topLine,(int(gallowx*(0.75*goldenRatio))-lineWidth,lineWidth*3),topLine)
lastLine = badLine(int(gallowy*0.125))
lastLine = self.badLine(int(gallowy*0.125))
background.paste(lastLine,((int(gallowx*(0.75*goldenRatio))+int(gallowy*0.30)-lineWidth),lineWidth*3),lastLine)
return background
def drawLetterLines(word,guessed,misses):
def drawLetterLines(self, word,guessed,misses):
letterLines = Image.new("RGBA",((letterLineLength+letterLineDistance)*len(word),letterLineLength+lineWidth*3),color=(0,0,0,0))
for x, letter in enumerate(word):
line = badLine(letterLineLength,True)
line = self.badLine(letterLineLength,True)
letterLines.paste(line,(x*(letterLineLength+letterLineDistance),letterLineLength),line)
if guessed[x]:
letterDrawing = badText(letter,True)
letterDrawing = self.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))
letterDrawing = self.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
def shortestDist(positions,newPosition):
def shortestDist(self,positions,newPosition):
shortestDist = math.inf
x, y = newPosition
for i, j in positions:
@ -191,49 +195,49 @@ def shortestDist(positions,newPosition):
if shortestDist > dist: shortestDist = dist
return shortestDist
def drawMisses(guesses,word):
def drawMisses(self,guesses,word):
background = Image.new("RGBA",(600,400),color=(0,0,0,0))
pos = []
for guess in guesses:
if guess not in word:
placed = False
while placed == False:
letter = badText(guess,True)
letter = self.badText(guess,True)
w, h = fnt.getsize(guess)
x = random.randint(0,600-w)
y = random.randint(0,400-h)
if shortestDist(pos,(x,y)) > 70:
if self.shortestDist(pos,(x,y)) > 70:
pos.append((x,y))
background.paste(letter,(x,y),letter)
placed = True
return background
def drawImage(channel):
with open("resources/games/hangmanGames.json", "r") as f:
data = json.load(f)
def drawImage(self,channel):
logThis("Drawing hangman image",channel)
game = self.bot.database["hangman games"].find_one({"_id":channel})
random.seed(data[channel]["game ID"])
random.seed(game["game ID"])
background = Image.open("resources/paper.jpg")
try:
gallow = drawGallows()
gallow = self.drawGallows()
except:
logThis("Error drawing gallows (error code 1711)")
try:
man = drawMan(data[channel]["misses"])
man = self.drawMan(game["misses"])
except:
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"])
letterLines = self.drawLetterLines(game["word"],game["guessed"],game["misses"])
except:
logThis("error drawing letter lines (error code 1713)")
random.seed(data[channel]["game ID"])
random.seed(game["game ID"])
try:
misses = drawMisses(data[channel]["guessed letters"],data[channel]["word"])
misses = self.drawMisses(game["guessed letters"],game["word"])
except:
logThis("Error drawing misses (error code 1714)")
@ -242,7 +246,7 @@ def drawImage(channel):
background.paste(letterLines,(120,840),letterLines)
background.paste(misses,(600,150),misses)
missesText = badText("MISSES",False)
missesText = self.badText("MISSES",False)
missesTextWidth = missesText.size[0]
background.paste(missesText,(850-int(missesTextWidth/2),50),missesText)

View File

@ -1,10 +1,9 @@
import json
import random
import copy
import math
from . import hexDraw
from funcs import logThis, getName, getID
from .hexDraw import DrawHex
from funcs import logThis
BOARDWIDTH = 11
ALL_POSITIONS = [(i,j) for i in range(11) for j in range(11)]
@ -14,11 +13,15 @@ for position in ALL_POSITIONS:
EMPTY_DIJKSTRA[position] = math.inf # an impossibly high number
HEX_DIRECTIONS = [(0,1),(-1,1),(-1,0),(0,-1),(1,-1),(1,0)]
# Parses command
def parseHex(command, channel, user):
class HexGame():
def __init__(self,bot):
self.bot = bot
self.draw = DrawHex(bot)
# Parses command
def parseHex(self, command, channel, user):
commands = command.lower().split()
with open("resources/games/hexGames.json", "r") as f:
data = json.load(f)
game = self.bot.database["hex games"].find_one({"_id":channel})
if command == "" or command == " ":
return "I didn't get that. Use \"!hex start [opponent]\" to start a game.", False, False, False, False
@ -28,15 +31,15 @@ def parseHex(command, channel, user):
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
return self.hexStart(channel,user,commands[1]) # commands[1] is the opponent
# If using a command with no game, return error
elif channel not in data:
elif game == None:
return "There's no game in this channel", False, False, False, False
# Stopping the game
elif commands[0] == "stop":
if user in data[channel]["players"]:
if user in game["players"]:
return "Ending game.", False, False, True, False
else:
return "You can't end a game where you're not a player.", False, False, False, False
@ -44,33 +47,33 @@ def parseHex(command, channel, user):
# Placing a piece
elif commands[0] == "place":
try:
return placeHex(channel,commands[1], user)
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 undoHex(channel, user)
return self.undoHex(channel, user)
# Surrender
elif commands[0] == "surrender":
players = data[channel]["players"]
players = game["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
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(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)
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:
hexDraw.drawSwap(channel)
player2 = data[channel]["players"][1]
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:
@ -80,12 +83,11 @@ def parseHex(command, channel, user):
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(channel, user, opponent):
with open("resources/games/hexGames.json", "r") as f:
data = json.load(f)
# Starts the game
def hexStart(self, channel, user, opponent):
game = self.bot.database["hex games"].find_one({"_id":channel})
if channel not in data:
if game == None:
if opponent in ["1","2","3","4","5"]:
difficulty = int(opponent)
diffText = " with difficulty "+opponent
@ -99,7 +101,7 @@ def hexStart(channel, user, opponent):
int(opponent)
return "That difficulty doesn't exist", False, False, False, False
except:
opponent = getID(opponent)
opponent = self.bot.funcs.getID(opponent)
if opponent == None:
return "I can't find that user", False, False, False, False
else:
@ -113,79 +115,74 @@ def hexStart(channel, user, opponent):
random.shuffle(players) # random starting player
gameHistory = []
data[channel] = {"board":board, "winner":0,
newGame = {"_id":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)
self.bot.database["hex games"].insert_one(newGame)
# draw the board
hexDraw.drawBoard(channel)
self.draw.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
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(channel : str,position : str, user):
with open("resources/games/hexGames.json", "r") as f:
data = json.load(f)
# 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 channel in data:
players = data[channel]["players"]
if game != None:
players = game["players"]
if user in players:
turn = data[channel]["turn"]
turn = game["turn"]
if players[0] == players[1]:
player = turn
else:
player = players.index(user)+1
if player == turn:
board = data[channel]["board"]
board = game["board"]
logThis("Placing a piece on the board with placeHex()")
# Places on board
board = placeOnHexBoard(board,player,position)
board = self.placeOnHexBoard(board,player,position)
if isinstance(board, list):
# If the move is valid:
data[channel]["board"] = board
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"board":board}})
turn = 1 if turn == 2 else 2
data[channel]["turn"] = turn
self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"turn":turn}})
# Checking for a win
logThis("Checking for win")
score, winner = evaluateBoard(data[channel]["board"])
winner = self.evaluateBoard(game["board"])[1]
if winner == 0: # Continue with the game.
gameWon = False
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)
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
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
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."
data[channel]["gameHistory"].append((int(position[1])-1, ord(position[0])-97))
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 data[channel]["players"][turn-1] == "Gwendolyn":
if game["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)
self.draw.drawHexPlacement(channel,player,position)
return message, True, True, gameWon, gwendoTurn
else:
@ -194,17 +191,17 @@ def placeHex(channel : str,position : str, user):
return message, False, False, False, False
else:
# Move out of turn
message = "It isn't your turn, it is "+getName(data[channel]["players"][turn-1])+"'s 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
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])+"."
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])+"."
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
def placeOnHexBoard(board,player,position):
# Returns a board where the placement has occured
def placeOnHexBoard(self, board,player,position):
# Translates the position
position = position.lower()
# Error handling
@ -226,26 +223,25 @@ def placeOnHexBoard(board,player,position):
return "Error. You must place on an empty space."
# After your move, you have the option to undo get your turn back #TimeTravel
def undoHex(channel, user):
with open("resources/games/hexGames.json", "r") as f:
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)))
# After your move, you have the option to undo get your turn back #TimeTravel
def undoHex(self, channel, user):
game = self.bot.database["hex games"].find_one({"_id":channel})
lastMove = data[channel]["gameHistory"].pop()
data[channel]["board"][lastMove[0]][lastMove[1]] = 0
data[channel]["turn"] = turn%2 + 1
# Save the data
with open("resources/games/hexGames.json", "w") as f:
json.dump(data,f,indent=4)
if user in game["players"]:
if len(game["gameHistory"]):
turn = game["turn"]
# You can only undo after your turn, which is the opponent's turn.
if user == game["players"][(turn % 2)]: # If it's not your turn
logThis("Undoing {}'s last move".format(self.bot.funcs.getName(user)))
lastMove = game["gameHistory"].pop()
self.bot.database["hex games"].update_one({"_id":channel},
{"$set":{"board."+lastMove[0]+"."+lastMove[1]:0}})
self.bot.database["hex games"].update_one({"_id":channel},
{"$set":{"turn":turn%2 + 1}})
# Update the board
hexDraw.drawHexPlacement(channel,0,"abcdefghijk"[lastMove[1]]+str(lastMove[0]+1)) # The zero makes the hex disappear
self.draw.drawHexPlacement(channel,0,"abcdefghijk"[lastMove[1]]+str(lastMove[0]+1)) # The zero makes the hex disappear
return "You undid your last move at {}".format(lastMove), True, True, False, False
else:
# Sassy
@ -258,15 +254,14 @@ def undoHex(channel, user):
return "You're not a player in the game", False, False, False, False
# Plays as the AI
def hexAI(channel):
# Plays as the AI
def hexAI(self, channel):
logThis("Figuring out best move")
with open("resources/games/hexGames.json", "r") as f:
data = json.load(f)
board = data[channel]["board"]
game = self.bot.database["hex games"].find_one({"_id":channel})
board = game["board"]
if len(data[channel]["gameHistory"]):
lastMove = data[channel]["gameHistory"][-1]
if len(game["gameHistory"]):
lastMove = game["gameHistory"][-1]
else:
lastMove = (5,5)
@ -304,10 +299,10 @@ def hexAI(channel):
"""
placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1)
logThis("ChosenMove is {} at {}".format(chosenMove,placement))
return placeHex(channel,placement, "Gwendolyn")
return self.placeHex(channel,placement, "Gwendolyn")
def evaluateBoard(board):
def evaluateBoard(self, 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
@ -344,10 +339,10 @@ def evaluateBoard(board):
return scores[2]-scores[1], winner
def minimaxHex(board, depth, alpha, beta, maximizingPlayer):
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 = evaluateBoard(board)[0]
score = self.evaluateBoard(board)[0]
return score
# if final depth is not reached, look another move ahead:
if maximizingPlayer: # red player predicts next move
@ -357,7 +352,7 @@ def minimaxHex(board, depth, alpha, beta, maximizingPlayer):
for i in possiblePlaces:
testBoard = copy.deepcopy(board)
testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 1 # because maximizingPlayer is Red which is number 1
evaluation = minimaxHex(testBoard,depth-1,alpha,beta,False)
evaluation = self.minimaxHex(testBoard,depth-1,alpha,beta,False)
maxEval = max(maxEval, evaluation)
alpha = max(alpha, evaluation)
if beta <= alpha:
@ -371,7 +366,7 @@ def minimaxHex(board, depth, alpha, beta, maximizingPlayer):
for i in possiblePlaces:
testBoard = copy.deepcopy(board)
testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 2 # because minimizingPlayer is Blue which is number 2
evaluation = minimaxHex(testBoard,depth-1,alpha,beta,True)
evaluation = self.minimaxHex(testBoard,depth-1,alpha,beta,True)
minEval = min(minEval, evaluation)
beta = min(beta, evaluation)
if beta <= alpha:

View File

@ -1,9 +1,8 @@
import json
import math
import os
from PIL import Image, ImageDraw, ImageFont
from funcs import logThis, getName
from funcs import logThis
# Defining all the variables
CANVAS_WIDTH = 2400
@ -38,7 +37,11 @@ NAMEHEXPADDING = 90
SMOL_WIDTH = HEXAGONWIDTH * 0.6
SMOL_SIDELENGTH = SIDELENGTH * 0.6
def drawBoard(channel):
class DrawHex():
def __init__(self,bot):
self.bot = bot
def drawBoard(self, channel):
logThis("Drawing empty Hex board")
# Creates the empty image
@ -94,10 +97,10 @@ def drawBoard(channel):
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)
game = self.bot.database["hex games"].find_one({"_id":channel})
for p in [1,2]:
playername = getName(data[channel]["players"][p-1])
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
@ -119,7 +122,7 @@ def drawBoard(channel):
def drawHexPlacement(channel,player,position):
def drawHexPlacement(self, channel,player,position):
FILEPATH = "resources/games/hexBoards/board"+channel+".png"
logThis("Drawing a newly placed hex. Filepath: "+FILEPATH)
@ -151,10 +154,9 @@ def drawHexPlacement(channel,player,position):
except:
logThis("Error drawing new hex on board (error code 1541")
def drawSwap(channel):
def drawSwap(self, channel):
FILEPATH = "resources/games/hexBoards/board"+channel+".png"
with open("resources/games/hexGames.json", "r") as f:
data = json.load(f)
game = self.bot.database["hex games"].find_one({"_id":channel})
# Opens the image
try:
with Image.open(FILEPATH) as im:
@ -162,7 +164,7 @@ def drawSwap(channel):
# Write player names and color
for p in [1,2]:
playername = getName(data[channel]["players"][p%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
@ -183,7 +185,3 @@ def drawSwap(channel):
im.save(FILEPATH)
except:
logThis("Error drawing swap (error code 1542)")

View File

@ -1,27 +1,25 @@
import json
class Invest():
def __init__(self,bot):
self.bot = bot
from funcs import getName
from .money import checkBalance, addMoney
def getPrice(symbol : str,finnhubClient):
res = finnhubClient.quote(symbol.upper())
def getPrice(self, symbol : str):
res = self.bot.finnhubClient.quote(symbol.upper())
if res == {}:
return 0
else:
return int(res["c"] * 100)
def getPortfolio(user : str,finnhubClient):
with open("resources/games/investments.json") as f:
data = json.load(f)
def getPortfolio(self, user : str):
userInvestments = self.bot.database["investments"].find_one({"_id":user})
if user not in data or data[user] == {}:
return f"{getName(user)} does not have a stock portfolio."
if userInvestments in [None,{}]:
return f"{self.bot.funcs.getName(user)} does not have a stock portfolio."
else:
portfolio = f"**Stock portfolio for {getName(user)}**"
portfolio = f"**Stock portfolio for {self.bot.funcs.getName(user)}**"
for key, value in list(data[user].items()):
for key, value in list(userInvestments["investments"].items()):
purchaseValue = value["purchased for"]
currentValue = int((getPrice(key,finnhubClient) / value["value at purchase"]) * value["purchased"])
currentValue = int((self.getPrice(key) / value["value at purchase"]) * value["purchased"])
if purchaseValue == "?":
portfolio += f"\n**{key}**: ___{str(currentValue)} GwendoBucks___"
else:
@ -29,35 +27,40 @@ def getPortfolio(user : str,finnhubClient):
return portfolio
def buyStock(user : str, stock : str, buyAmount : int,finnhubClient):
def buyStock(self, user : str, stock : str, buyAmount : int):
if buyAmount >= 100:
if checkBalance(user) >= buyAmount:
stockPrice = getPrice(stock,finnhubClient)
if self.bot.money.checkBalance(user) >= buyAmount:
stockPrice = self.getPrice(stock)
if stockPrice > 0:
with open("resources/games/investments.json", "r") as f:
data = json.load(f)
userInvestments = self.bot.database["investments"].find_one({"_id":user})
addMoney(user,-1*buyAmount)
self.bot.money.addMoney(user,-1*buyAmount)
stock = stock.upper()
if user in data:
if stock in data[user]:
value = data[user][stock]
if userInvestments != None:
userInvestments = userInvestments["investments"]
if stock in userInvestments:
value = userInvestments[stock]
newAmount = int((stockPrice / value["value at purchase"]) * value["purchased"]) + buyAmount
data[user][stock]["value at purchase"] = stockPrice
data[user][stock]["purchased"] = newAmount
self.bot.database["investments"].update_one({"_id":user},
{"$set":{"investments."+stock+".value at purchase" : stockPrice}})
self.bot.database["investments"].update_one({"_id":user},
{"$set":{"investments."+stock+".purchased" : newAmount}})
if value["purchased for"] != "?":
data[user][stock]["purchased for"] += buyAmount
self.bot.database["investments"].update_one({"_id":user},
{"$set":{"investments."+stock+".purchased for" : buyAmount}})
else:
data[user][stock] = {"purchased" : buyAmount, "value at purchase" : stockPrice, "purchased for" : buyAmount}
self.bot.database["investments"].update_one({"_id":user},
{"$set":{"investments."+stock : {"purchased" : buyAmount, "value at purchase" : stockPrice,
"purchased for" : buyAmount}}})
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)
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"
return f"{self.bot.funcs.getName(user)} bought {buyAmount} GwendoBucks worth of {stock} stock"
else:
return f"{stock} is not traded on the american market."
else:
@ -65,31 +68,34 @@ def buyStock(user : str, stock : str, buyAmount : int,finnhubClient):
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:
with open("resources/games/investments.json", "r") as f:
data = json.load(f)
userInvestments = self.bot.database["investments"].find_one({"_id":user})["investments"]
stock = stock.upper()
if user in data and stock in data[user]:
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 userInvestments != None and stock in userInvestments:
value = userInvestments[stock]
stockPrice = self.getPrice(stock)
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:
addMoney(user,sellAmount)
self.bot.money.addMoney(user,sellAmount)
if sellAmount < value["purchased"]:
data[user][stock]["purchased"] -= sellAmount
data[user][stock]["purchased for"] = "?"
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:
del data[user][stock]
self.bot.database["investments"].update_one({"_id":user},
{"$unset":{"investments."+stock:""}})
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"
return f"{self.bot.funcs.getName(user)} sold {sellAmount} GwendoBucks worth of {stock} stock"
else:
return f"You don't have enough {stock} stocks to do that"
else:
@ -97,13 +103,13 @@ def sellStock(user : str, stock : str, sellAmount : int,finnhubClient):
else:
return "no"
def parseInvest(content: str, user : str,finnhubClient):
def parseInvest(self, content: str, user : str):
if content.startswith("check"):
commands = content.split(" ")
if len(commands) == 1:
return getPortfolio(user,finnhubClient)
return self.getPortfolio(user)
else:
price = getPrice(commands[1],finnhubClient)
price = self.getPrice(commands[1])
if price == 0:
return f"{commands[1].upper()} is not traded on the american market."
else:
@ -113,10 +119,10 @@ def parseInvest(content: str, user : str,finnhubClient):
elif content.startswith("buy"):
commands = content.split(" ")
if len(commands) == 3:
try:
return buyStock(user,commands[1],int(commands[2]),finnhubClient)
except:
return "The command must be given as \"!invest buy [stock] [amount of GwendoBucks to purchase with]\""
#try:
return self.buyStock(user,commands[1],int(commands[2]))
#except:
# return "The command must be given as \"!invest buy [stock] [amount of GwendoBucks to purchase with]\""
else:
return "You must give both a stock name and an amount of gwendobucks you wish to spend."
@ -124,7 +130,7 @@ def parseInvest(content: str, user : str,finnhubClient):
commands = content.split(" ")
if len(commands) == 3:
try:
return sellStock(user,commands[1],int(commands[2]),finnhubClient)
return self.sellStock(user,commands[1],int(commands[2]))
except:
return "The command must be given as \"!invest sell [stock] [amount of GwendoBucks to sell stocks for]\""
else:

View File

@ -1,47 +1,47 @@
import json
import pymongo
from funcs import logThis, getID, getName
from funcs import logThis
# Returns the account balance for a user
def checkBalance(user):
user = user.lower()
class Money():
def __init__(self, bot):
self.bot = bot
self.database = bot.database
# Returns the account balance for a user
def checkBalance(self, user):
logThis("checking "+user+"'s account balance")
with open("resources/users.json", "r") as f:
data = json.load(f)
if user in data:
return data[user]["money"]
userData = self.database["users"].find_one({"_id":user})
if userData != None:
return userData["money"]
else: return 0
# Adds money to the account of a user
def addMoney(user,amount):
# Adds money to the account of a user
def addMoney(self,user,amount):
logThis("adding "+str(amount)+" to "+user+"'s account")
with open("resources/users.json", "r") as f:
data = json.load(f)
if user in data:
points = data[user]["money"]
data[user]["money"] = points + amount
userData = self.database["users"].find_one({"_id":user})
if userData != None:
self.database["users"].update_one({"_id":user},{"$inc":{"money":amount}})
else:
data[user]["money"] = amount
self.database["users"].insert_one({"_id":user,"user name":self.bot.funcs.getName(user),"money":amount})
with open("resources/users.json", "w") as f:
json.dump(data,f,indent=4)
# Transfers money from one user to another
def giveMoney(user,targetUser,amount):
with open("resources/users.json", "r") as f:
data = json.load(f)
targetUser = getID(targetUser)
# Transfers money from one user to another
def giveMoney(self,user,targetUser,amount):
userData = self.database["users"].find_one({"_id":user})
targetUser = self.bot.funcs.getID(targetUser)
if amount > 0:
if targetUser != None:
if user in data:
if data[user]["money"] >= amount:
addMoney(user,-1 * amount)
addMoney(targetUser,amount)
return "Transferred "+str(amount)+" GwendoBucks to "+getName(targetUser)
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)"

View File

@ -1,28 +1,31 @@
import json, random
import random
from funcs import getName, logThis
from . import monopolyDraw
from funcs import logThis
from .monopolyDraw import DrawMonopoly
rulesAndTerms = {
"pass go money" : 200,
"money term" : "GP"
}
def monopolyStart(channel):
logThis("Starting a monopoly game")
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
class Monopoly():
def __init__(self, bot):
self.bot = bot
self.draw = DrawMonopoly(bot)
if channel not in data:
def monopolyStart(self, channel):
logThis("Starting a monopoly game")
game = self.bot.database["monopoly games"].find_one({"_id":channel})
if game == None:
buildings = [0] * 40
data[channel] = {"players" : {}, "player list" : [],"turn" : 0, "buildings" : buildings, "last roll" : [0,0], "started" : False}
newGame = {"_id":channel,"players" : {}, "player list" : [],"turn" : 0, "buildings" : buildings, "last roll" : [0,0], "started" : False}
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["monopoly games"].insert_one(newGame)
try:
monopolyDraw.drawImage(channel)
self.draw.drawImage(channel)
except:
logThis("Error drawing board (error code 1640)")
@ -30,21 +33,19 @@ def monopolyStart(channel):
else:
return "There's already a monopoly game going on.", False, False, False, False
def monopolyJoin(channel,user):
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
def monopolyJoin(self,channel,user):
game = self.bot.database["monopoly games"].find_one({"_id":channel})
if channel in data:
if not data[channel]["started"]:
if user not in data[channel]["players"]:
if len(data[channel]["players"]) < 6:
if game != None:
if not game["started"]:
if user not in game["players"]:
if len(game["players"]) < 6:
data[channel]["players"][user] = {"position" : 0, "properties" : [], "money" : 1500, "doubles" : 0}
newPlayer = {"position" : 0, "properties" : [], "money" : 1500, "doubles" : 0}
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"players."+user:newPlayer}})
return getName(user)+" has joined the game.", False, False, False, False
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:
@ -54,86 +55,82 @@ def monopolyJoin(channel,user):
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)
commands = command.split()
if command in [" ", ""] or commands[0] == "start":
try:
return monopolyStart(channel)
return self.monopolyStart(channel)
except:
logThis("Error starting game (error code 1620)")
elif commands[0] == "join":
try:
return monopolyJoin(channel,user)
return self.monopolyJoin(channel,user)
except:
logThis("Error joining game (error code 1630)")
elif commands[0] == "roll":
try:
return monopolyRoll(channel,user)
return self.monopolyRoll(channel,user)
except:
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)
def monopolyContinue(self, channel):
game = self.bot.database["monopoly games"].find_one({"_id":channel})
if channel in data:
if data[channel]["started"] == False:
data[channel]["started"] = True
playerList = list(data[channel]["players"].keys())
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)
data[channel]["player list"] = playerList
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"player list":playerList}})
turn = 0
else:
if data[channel]["last roll"][0] == data[channel]["last roll"][1]:
turn = data[channel]["turn"]
if game["last roll"][0] == game["last roll"][1]:
turn = game["turn"]
else:
turn = (data[channel]["turn"] + 1)%len(data[channel]["player list"])
data[channel]["turn"] = turn
playerList = list(data[channel]["players"].keys())
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(data,f,indent=4)
turn = (game["turn"] + 1)%len(game["player list"])
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"turn":turn}})
playerList = list(game["players"].keys())
try:
monopolyDraw.drawImage(channel)
self.draw.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."
if playerList == []:
return "No one joined. Ending game.", False, True, True
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."
return message, True, True, False
def monopolyRoll(channel,user):
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
def monopolyRoll(self, channel,user):
game = self.bot.database["monopoly games"].find_one({"_id":channel})
turn = data[channel]["turn"]
currentPlayer = data[channel]["player list"][turn]
turn = game["turn"]
currentPlayer = game["player list"][turn]
if user == currentPlayer:
rolls = [random.randint(1,6),random.randint(1,6)]
message = getName(user)+" rolled a "+str(rolls[0])+" and a "+str(rolls[1])+"."
message = self.bot.funcs.getName(user)+" rolled a "+str(rolls[0])+" and a "+str(rolls[1])+"."
if rolls[0] == rolls[1]:
message += " Doubbles!"
roll = rolls[0] + rolls[1]
oldPosition = data[channel]["players"][user]["position"]
oldPosition = game["players"][user]["position"]
newPosition = (oldPosition + roll)%40
if newPosition < oldPosition:
data[channel]["players"][user]["money"] += rulesAndTerms["pass go money"]
self.bot.database["monopoly games"].update_one({"_id":channel},
{"$inc":{"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
data[channel]["last roll"] = rolls
with open("resources/games/monopolyGames.json", "w") as f:
json.dump(data,f,indent=4)
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"players."+user+".position":newPosition}})
self.bot.database["monopoly games"].update_one({"_id":channel},{"$set":{"last roll":rolls}})
try:
monopolyDraw.drawImage(channel)
self.draw.drawImage(channel)
except:
logThis("Error drawing board (error code 1640)")

View File

@ -1,4 +1,4 @@
import math, json
import math
from funcs import logThis
@ -10,29 +10,29 @@ smallSpace = math.floor((w - 2*largeSpace)/9)
avatarSize = 50
avatarHalf = math.floor(avatarSize/2)
def drawImage(channel):
class DrawMonopoly():
def __init__(self,bot):
self.bot = bot
def drawImage(self, channel):
logThis("Drawing monopoly board for "+channel)
with open("resources/games/monopolyGames.json", "r") as f:
data = json.load(f)
game = self.bot.database["monopoly games"].find_one({"_id":channel})
board = Image.open("resources/games/monopolyBoard.png")
d = ImageDraw.Draw(board,"RGBA")
for key, value in list(data[channel]["players"].items()):
for key, value in list(game["players"].items()):
logThis("Drawing "+key)
try:
x, y = getPosition(value["position"])
x, y = self.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")
def getPosition(positionNumber):
print(positionNumber)
def getPosition(self, positionNumber):
x, y = 0, 0
if positionNumber == 0 or positionNumber >= 30:
x = math.floor(largeSpace/2)
@ -43,7 +43,7 @@ def getPosition(positionNumber):
elif positionNumber > 20 and positionNumber < 30:
x = w - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 20))
if positionNumber >= 0 and positionNumber <= 20:
if positionNumber >= 0 and positionNumber <= 10:
y = math.floor(largeSpace/2)
elif positionNumber > 10 and positionNumber < 20:
y = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*(positionNumber-10))

View File

@ -5,15 +5,18 @@ import random
from . import money
from funcs import logThis
# Starts a game of trivia. Downloads a question with answers, shuffles the wrong answers with the
# correct answer and returns the questions and answers. Also saves the question in the games.json file.
def triviaStart(channel : str):
with open("resources/games/games.json", "r") as f:
triviaFile = json.load(f)
class Trivia():
def __init__(self, bot):
self.bot = bot
# Starts a game of trivia. Downloads a question with answers, shuffles the wrong answers with the
# correct answer and returns the questions and answers. Also saves the question in the games.json file.
def triviaStart(self, channel : str):
question = self.bot.database["trivia questions"].find_one({"_id":channel})
logThis("Trying to find a trivia question for "+channel)
if channel not in triviaFile["trivia questions"]:
if question == None:
with urllib.request.urlopen("https://opentdb.com/api.php?amount=10&type=multiple") as response:
data = json.loads(response.read())
@ -23,9 +26,7 @@ def triviaStart(channel : str):
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)
self.bot.database["trivia questions"].insert_one({"_id":channel,"answer" : str(chr(correctAnswer)),"players" : {}})
replacements = {"&#039;": "\'",
"&quot;": "\"",
@ -46,20 +47,16 @@ def triviaStart(channel : str):
logThis("There was already a trivia question for that channel (error code 1106)")
return "There's already a trivia question going on. Try again in like, a minute (error code 1106)", "", ""
# Lets players answer a trivia question
def triviaAnswer(user : str, channel : str, command : str):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# Lets players answer a trivia question
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 channel in data["trivia questions"]:
if user not in data["trivia questions"][channel]["players"]:
if question != None:
if user not in question["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)
self.bot.database["trivia questions"].update_one({"_id":channel},{"$set":{"players."+user : command}})
return "Locked in "+user+"'s answer"
else:
@ -73,17 +70,16 @@ def triviaAnswer(user : str, channel : str, command : str):
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.
def triviaCountPoints(channel : str):
with open("resources/games/games.json", "r") as f:
data = json.load(f)
# Adds 1 GwendoBuck to each player that got the question right and deletes question from games.json.
def triviaCountPoints(self, channel : str):
question = self.bot.database["trivia questions"].find_one({"_id":channel})
logThis("Counting points for question in "+channel)
if channel in data["trivia questions"]:
for player, answer in data["trivia questions"][channel]["players"].items():
if answer == data["trivia questions"][channel]["answer"]:
money.addMoney(player,1)
if question != None:
for player, answer in question["players"].items():
if answer == question["answer"]:
self.bot.money.addMoney(player,1)
else:

View File

@ -7,7 +7,6 @@ import time # Used for logging
import logging # Used for... you know... logging
import wikia # Used by findWikiPage
import os # Used by makeFiles
import git # Used by stopServer()
import pymongo # Used by transferUsers
logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
@ -207,86 +206,6 @@ def emojiToCommand(emoji):
return "roll"
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):
with open("resources/users.json", "r") as f:
data = json.load(f)
@ -315,35 +234,6 @@ def addToDict(userID,userName):
with open("resources/users.json", "w") as f:
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):
collist = database.list_collection_names()
if "users" not in collist and os.path.exists("resources/users.json"):
@ -354,7 +244,20 @@ def transferUsers(database):
userList = []
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)
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)

View File

@ -1,7 +1,7 @@
"""Functions related to the Star Wars TTRPG."""
__all__ = ["parseChar", "parseRoll", "critRoll", "parseDestiny"]
__all__ = ["SwChar", "SwRoll", "SwDestiny"]
from .swchar import parseChar
from .swroll import parseRoll, critRoll
from .swdestiny import parseDestiny
from .swchar import SwChar
from .swroll import SwRoll
from .swdestiny import SwDestiny

View File

@ -1,21 +1,24 @@
import json
import string
from funcs import logThis, getName
from funcs import logThis
def getCharName(user : str):
logThis("Getting name for "+getName(user)+"'s character")
with open("resources/starWars/swcharacters.json", "r") as f:
data = json.load(f)
class SwChar():
def __init__(self, bot):
self.bot = bot
if user in data:
logThis("Name is "+data[user]["Name"])
return data[user]["Name"]
def getCharName(self, user : str):
logThis("Getting name for "+self.bot.funcs.getName(user)+"'s character")
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
if user != None:
logThis("Name is "+userCharacter["Name"])
return userCharacter["Name"]
else:
logThis("Just using "+getName(user))
return getName(user)
logThis("Just using "+self.bot.funcs.getName(user))
return self.bot.funcs.getName(user)
def setUpDict(cmd : dict):
def setUpDict(self, cmd : dict):
logThis("Setting up a dictionary in a nice way")
if bool(cmd):
keys = list(cmd)
@ -41,7 +44,7 @@ def setUpDict(cmd : dict):
logThis("Couldn't find anything")
return "There doesn't seem to be anything here..."
def lookUp(data : dict, key : str, cmd : str = ""):
def lookUp(self, data : dict, key : str, cmd : str = ""):
if cmd == " ":
cmd = ""
elif cmd != "":
@ -55,7 +58,7 @@ def lookUp(data : dict, key : str, cmd : str = ""):
logThis(key+" exists")
if cmd == "":
if type(data[key]) is dict and key != "Weapons":
return setUpDict(data[key])
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]):
@ -145,7 +148,7 @@ def lookUp(data : dict, key : str, cmd : str = ""):
if cmd == "":
break
logThis("Looking up "+newKey+" in "+key)
lookUpResult = lookUp(data[key],newKey,cmd)
lookUpResult = self.lookUp(data[key],newKey,cmd)
if type(lookUpResult) is dict:
data[key] = lookUpResult
return data
@ -191,7 +194,7 @@ def lookUp(data : dict, key : str, cmd : str = ""):
if cmd == "":
logThis("Returning "+search)
return setUpDict(data[search])
return self.setUpDict(data[search])
else:
newKey = cmd.split(" ")[0]
cmd = cmd[len(newKey):]
@ -200,14 +203,14 @@ def lookUp(data : dict, key : str, cmd : str = ""):
cmd = cmd[1:]
if cmd == "":
break
lookUpResult = lookUp(data[search],newKey,cmd)
lookUpResult = self.lookUp(data[search],newKey,cmd)
if type(lookUpResult) is dict:
data[search] = lookUpResult
return data
else:
return lookUpResult
def characterSheet(character : dict):
def characterSheet(self,character : dict):
logThis("Setting up a character sheet for "+character["Name"])
divider = "--------------------\n"
name = character["Name"]
@ -217,8 +220,8 @@ def characterSheet(character : dict):
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"])
text3 = self.setUpDict(character["Characteristics"])
text4 = self.setUpDict(character["Skills"])
text5 = ""
text6 = ""
text7 = ""
@ -237,9 +240,8 @@ def characterSheet(character : dict):
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)
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):]
@ -251,24 +253,24 @@ def charData(user : str,cmd : str):
if cmd == "":
break
logThis("Looking for "+getName(user)+"'s character")
if user in data:
logThis("Looking for "+self.bot.funcs.getName(user)+"'s character")
if userCharacter != None:
logThis("Foundt it! Looking for "+key+" in the data")
if key in data[user]:
if key in userCharacter:
logThis("Found it!")
if type(data[user][key]) is dict:
if type(userCharacter[key]) is dict:
logThis("It's a dictionary!")
if cmd == "":
logThis("Retrieving data")
if key == "Weapons":
if bool(data[user][key]):
if bool(userCharacter[key]):
logThis("Returning a list of weapons")
return ", ".join(list(data[user][key]))
return ", ".join(list(userCharacter[key]))
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 "There doesn't seem to be anything there... (error code 941)"
else:
return setUpDict(data[user][key])
return self.setUpDict(userCharacter[key])
elif cmd[0] == "+":
logThis("Gonna add something!!!")
try:
@ -284,10 +286,9 @@ def charData(user : str,cmd : str):
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"]
self.bot.database["swcharacters"].update_one({"_id":user},
{"$set": {key+"."+cmd[0] : cmd[1]}})
return cmd[0]+" added to "+key+" for " + userCharacter["Name"]
elif key == "Obligations" and "," in cmd:
cmd = cmd.split(",")
@ -295,24 +296,22 @@ def charData(user : str,cmd : str):
cmd[1] = cmd[1][1:]
logThis("Adding "+cmd[0]+" to "+key)
try:
data[user][key][cmd[0]] = int(cmd[1])
self.bot.database["swcharacters"].update_one({"_id":user},
{"$set": {key+"."+cmd[0] : int(cmd[1])}})
except:
logThis("Fucked that up (error code 949)")
return "Wrong data type (error code 949)"
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"]
return cmd[0]+" added to "+key+" for " + userCharacter["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
self.bot.database["swcharacters"].update_one({"_id":user},
{"$set": {key+"."+cmd : newWeapon}})
with open("resources/starWars/swcharacters.json", "w") as f:
json.dump(data,f,indent = 4)
return cmd+" added to weapons for " + data[user]["Name"]
return cmd+" added to weapons for " + userCharacter["Name"]
else:
logThis("That's not happening (error code 947d)")
@ -330,12 +329,11 @@ def charData(user : str,cmd : str):
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)
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 "+data[user]["Name"]
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)"
@ -352,22 +350,21 @@ def charData(user : str,cmd : str):
newKey = string.capwords(cmd.split(" ")[0])
newcmd = cmd[len(newKey):]
lookUpResult = lookUp(data[user][key],newKey,newcmd)
lookUpResult = self.lookUp(userCharacter[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
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(data[user][key]) is list:
return key+":\n"+", ".join(data[user][key])
if type(userCharacter[key]) is list:
return key+":\n"+", ".join(userCharacter[key])
else:
return data[user][key]
return userCharacter[key]
elif cmd[0] == '+':
logThis("Adding")
try:
@ -378,24 +375,21 @@ def charData(user : str,cmd : str):
logThis("Error message (error code 948)")
return "Can't do that (error code 948)"
if type(data[user][key]) is int:
if type(userCharacter[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
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(data[user][key]) is list:
elif type(userCharacter[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
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)"
@ -412,29 +406,25 @@ def charData(user : str,cmd : str):
logThis("lalalala (error code 948)")
return "Can't do that (error code 948)"
if type(data[user][key]) is int:
if type(userCharacter[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
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(data[user][key]) is list:
elif type(userCharacter[key]) is list:
try:
logThis("removing "+cmd+" from "+key)
beforeData = data[user][key]
try:
data[user][key].remove(cmd)
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)"
with open("resources/starWars/swcharacters.json", "w") as f:
json.dump(data,f,indent = 4)
return "Removed " + cmd + " from " + data[user]["Name"] + "'s " + key
return "Removed " + cmd + " from " + userCharacter["Name"] + "'s " + key
except:
logThis("nah (error code 946b)")
return "Can't remove that (error code 946b)"
@ -443,21 +433,20 @@ def charData(user : str,cmd : str):
return "Can't remove that (error code 946a)"
else:
logThis("Changing "+key+" to "+cmd)
if type(data[user][key]) is int:
if type(userCharacter[key]) is int:
try:
data[user][key] = int(cmd)
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(data[user][key]) is str:
data[user][key] = cmd
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)"
with open("resources/starWars/swcharacters.json", "w") as f:
json.dump(data,f,indent = 4)
return "Changed " + data[user]["Name"] + "'s " + key +" to " + cmd
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)"
@ -465,7 +454,7 @@ def charData(user : str,cmd : str):
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"]
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"]
@ -474,7 +463,7 @@ def replaceSpaces(cmd : str):
return cmd
def replaceWithSpaces(cmd : str):
def replaceWithSpaces(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"]
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"]
@ -483,12 +472,11 @@ def replaceWithSpaces(cmd : str):
return cmd
def parseChar(user : str, cmd : str):
def parseChar(self,user : str, cmd : str):
cmd = replaceSpaces(cmd)
cmd = self.replaceSpaces(cmd)
with open("resources/starWars/swcharacters.json", "r") as f:
data = json.load(f)
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
if cmd == " ":
cmd = ""
@ -500,38 +488,36 @@ def parseChar(user : str, cmd : str):
if cmd == "":
if user in data:
text1, text2 = characterSheet(data[user])
return text1, replaceWithSpaces(text2)
if userCharacter != None:
text1, text2 = self.characterSheet(userCharacter)
return text1, self.replaceWithSpaces(text2)
else:
logThis("Makin' a character for "+getName(user))
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"]
data[user] = newChar
with open("resources/starWars/swcharacters.json", "w") as f:
json.dump(data,f,indent = 4)
return "", "Character for " + getName(user) + " created"
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:
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"
logThis("Deleting "+self.bot.funcs.getName(user)+"'s character")
self.bot.database["swcharacters"].remove_one({newChar})
return "", "Character for " + self.bot.funcs.getName(user) + " deleted"
else:
return "", replaceWithSpaces(str(charData(user,cmd)))
return "", self.replaceWithSpaces(str(self.charData(user,cmd)))
def lightsaberChar(user : str):
with open("resources/starWars/swcharacters.json", "r") as f:
data = json.load(f)
def lightsaberChar(self,user : str):
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
if user in data:
return data[user]["Lightsaber-characteristic"]
if userCharacter != None:
return userCharacter["Lightsaber-characteristic"]
def userHasChar(user : str):
with open("resources/starWars/swcharacters.json", "r") as f:
data = json.load(f)
def userHasChar(self,user : str):
userCharacter = self.bot.database["swcharacters"].find_one({"_id":user})
return user in data
return userCharacter != None

View File

@ -1,18 +1,20 @@
from . import swroll
from funcs import logThis
def destinyNew(num : int):
class SwDestiny():
def __init__(self, bot):
self.bot = bot
def destinyNew(self, num : int):
logThis("Creating a new destiny pool with "+str(num)+" players")
roll, diceResults = swroll.roll(0,0,0,0,0,0,num)
roll, diceResults = self.bot.swroll.roll(0,0,0,0,0,0,num)
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)
return "Rolled for Destiny Points and got:\n"+self.bot.swroll.diceResultToEmoji(diceResults)+"\n"+self.bot.swroll.resultToEmoji(roll)
def destinyUse(user : str):
def destinyUse(self, user : str):
with open("resources/starWars/destinyPoints.txt","rt") as f:
points = f.read()
@ -24,7 +26,7 @@ def destinyUse(user : str):
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)
return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.swroll.resultToEmoji(points)
else:
logThis("There were no dark side destiny points")
return "No dark side destiny points"
@ -36,12 +38,12 @@ def destinyUse(user : str):
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)
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(user : str, cmd : str):
def parseDestiny(self, user : str, cmd : str):
if cmd != "":
while cmd[0] == ' ':
cmd = cmd[1:]
@ -52,15 +54,15 @@ def parseDestiny(user : str, cmd : str):
if cmd == "":
logThis("Retrieving destiny pool info")
with open("resources/starWars/destinyPoints.txt","rt") as f:
return swroll.resultToEmoji(f.read())
return self.bot.swroll.resultToEmoji(f.read())
else:
commands = cmd.upper().split(" ")
if commands[0] == "N":
if len(commands) > 1:
return destinyNew(int(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 destinyUse(user)
return self.destinyUse(user)
else:
return "I didn't quite understand that (error code 922)"

View File

@ -3,14 +3,17 @@ import re
import string
import json
from . import swchar
from funcs import logThis
with open("resources/starWars/swskills.json", "r") as f:
skillData = json.load(f)
# Rolls the specified dice
def roll(abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int = 0, setb : int = 0, force : int = 0):
class SwRoll():
def __init__(self, bot):
self.bot = bot
# Rolls the specified dice
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 = ""
diceResult = []
for x in range(abi):
@ -50,8 +53,8 @@ def roll(abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int
return result, diceResult
# Lets dice cancel each other out
def simplify(result : str):
# Lets dice cancel each other out
def simplify(self, result : str):
logThis("Simplifying "+result)
simp = ""
success = (result.count('S') + result.count('R')) - (result.count('F') + result.count('D'))
@ -76,8 +79,8 @@ def simplify(result : str):
return simp
# Returns emoji that symbolize the dice results
def diceResultToEmoji(diceResults : list):
# Returns emoji that symbolize the dice results
def diceResultToEmoji(self, diceResults : list):
emoji = ""
for result in diceResults:
if result == "abiA":
@ -165,8 +168,8 @@ def diceResultToEmoji(diceResults : list):
return emoji
# Returns emoji that symbolize the results of the dice rolls
def resultToEmoji(result : str):
# Returns emoji that symbolize the results of the dice rolls
def resultToEmoji(self, result : str):
emoji = ""
for char in result:
if char == 'S':
@ -188,8 +191,8 @@ def resultToEmoji(result : str):
return emoji
# Converts emoji into letters
def emojiToResult(emoji : str):
# Converts emoji into letters
def emojiToResult(self, emoji : str):
result = ""
for char in emoji:
if char == "<:light:691010089905029171>":
@ -199,8 +202,8 @@ def emojiToResult(emoji : str):
return result
# Returns emoji that symbolize the dice
def diceToEmoji(dice : list):
# Returns emoji that symbolize the dice
def diceToEmoji(self, dice : list):
emoji = ""
for x in range(dice[0]):
@ -220,11 +223,10 @@ def diceToEmoji(dice : list):
return emoji
# Rolls for obligation
def obligationRoll():
# Rolls for obligation
def obligationRoll(self):
logThis("Rolling for obligation")
with open("resources/starWars/swcharacters.json", "r") as f:
data = json.load(f)
data = self.bot.database["swcharacters"]
table = []
@ -238,8 +240,8 @@ def obligationRoll():
return random.choice(table)
# Rolls for critical injury
def critRoll(addington : int):
# Rolls for critical injury
def critRoll(self, addington : int):
dd = "<:difficulty:690973992470708296>"
sd = "<:setback:690972157890658415>"
bd = "<:boost:690972178216386561>"
@ -290,12 +292,12 @@ def critRoll(addington : int):
return "Roll: "+str(roll)+"\nInjury:\n"+results
# Parses the command into something the other functions understand
def parseRoll(user : str,cmd : str = ""):
# 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 = swchar.replaceSpaces(string.capwords(cmd))
cmd = self.bot.swchar.replaceSpaces(string.capwords(cmd))
commands = cmd.split(" ")
if commands[0] == "":
rollParameters = [1,0,3,0,0,0,0]
@ -311,15 +313,15 @@ def parseRoll(user : str,cmd : str = ""):
elif string.capwords(commands[0]) in skillData:
logThis("Oh look! This guy has skills!")
if swchar.userHasChar:
if self.bot.swchar.userHasChar:
logThis("They have a character. That much we know")
skillLevel = swchar.charData(user,"Skills " + string.capwords(commands[0]))
skillLevel = self.bot.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))
charLevel = self.bot.swchar.charData(user,"Characteristics " + self.bot.swchar.lightsaberChar(user))
else:
charLevel = swchar.charData(user,"Characteristics " + skillData[string.capwords(commands[0])])
charLevel = self.bot.swchar.charData(user,"Characteristics " + skillData[string.capwords(commands[0])])
abilityDice = abs(charLevel-skillLevel)
proficiencyDice = min(skillLevel,charLevel)
@ -363,16 +365,16 @@ def parseRoll(user : str,cmd : str = ""):
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])
rollResults, diceResults = self.roll(rollParameters[0],rollParameters[1],rollParameters[2],rollParameters[3],rollParameters[4],rollParameters[5],rollParameters[6])
simplified = simplify(rollResults)
simplified = self.simplify(rollResults)
name = swchar.getCharName(user)
name = self.bot.swchar.getCharName(user)
logThis("Returns results and simplified results")
if simplified == "":
return name + " rolls: " + "\n" + diceResultToEmoji(diceResults) + "\nEverything cancels out!"
return name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\nEverything cancels out!"
else:
return name + " rolls: " + "\n" + diceResultToEmoji(diceResults) + "\n" + resultToEmoji(simplified)
return name + " rolls: " + "\n" + self.diceResultToEmoji(diceResults) + "\n" + self.resultToEmoji(simplified)

View File

@ -1,15 +1,5 @@
{
"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" : {
"Fireball" : {
"casting_time" : "1 action",
@ -76,9 +66,6 @@
"resources/games/blackjackTables",
"resources/games/4InARowBoards",
"resources/games/hexBoards",
"resources/games/oldImages",
"resources/games/blackjackCards",
"resources/games/hilo",
"resources/games/monopolyBoards",
"resources/games/hangmanBoards"
]