Merge branch 'master' of https://github.com/NikolajDanger/Gwendolyn
This commit is contained in:
@ -1,10 +1,10 @@
|
||||
"""A collection of all Gwendolyn functions."""
|
||||
|
||||
__all__ = ["helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToNumber", "fiarReactionTest", "deleteGame", "stopServer", "checkBalance", "giveMoney", "addMoney", "triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "parseFourInARow", "fourInARowAI", "spellFunc", "monsterFunc", "nameGen", "tavernGen", "movieFunc", "roll_dice", "parseChar", "parseRoll", "critRoll", "parseDestiny", "parseHex", "hexAI", "addToDict", "getName", "getID"]
|
||||
__all__ = ["helloFunc", "cap", "imageFunc", "logThis", "findWikiPage", "makeFiles", "emojiToCommand", "fiarReactionTest", "deleteGame", "stopServer", "checkBalance", "giveMoney", "addMoney", "triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "parseFourInARow", "fourInARowAI", "spellFunc", "monsterFunc", "nameGen", "tavernGen", "movieFunc", "roll_dice", "parseChar", "parseRoll", "critRoll", "parseDestiny", "parseHex", "addToDict", "getName", "getID", "replaceMultiple", "hexAI", "parseMonopoly", "monopolyContinue", "monopolyReactionTest"]
|
||||
|
||||
from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToNumber, fiarReactionTest, deleteGame, stopServer, addToDict, getName, getID
|
||||
from .miscFuncs import helloFunc, cap, imageFunc, logThis, findWikiPage, makeFiles, replaceMultiple, emojiToCommand, fiarReactionTest, deleteGame, stopServer, addToDict, getName, getID, monopolyReactionTest
|
||||
|
||||
from .games import checkBalance, giveMoney, addMoney, triviaCountPoints, triviaStart, triviaAnswer, blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit, parseFourInARow, fourInARowAI, parseHex, hexAI
|
||||
from .games import checkBalance, giveMoney, addMoney, triviaCountPoints, triviaStart, triviaAnswer, blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit, parseFourInARow, fourInARowAI, parseHex, hexAI, parseMonopoly, monopolyContinue
|
||||
|
||||
from .lookup import spellFunc, monsterFunc
|
||||
|
||||
@ -13,4 +13,3 @@ from .other import nameGen, tavernGen, movieFunc
|
||||
from .roll import roll_dice
|
||||
|
||||
from .swfuncs import parseChar, parseRoll, parseDestiny, critRoll
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
"""Functions for games Gwendolyn can play."""
|
||||
|
||||
__all__ = ["checkBalance", "giveMoney", "addMoney","triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "parseFourInARow", "fourInARowAI", "parseHex","hexAI"]
|
||||
__all__ = ["checkBalance", "giveMoney", "addMoney","triviaCountPoints", "triviaStart", "triviaAnswer", "blackjackShuffle", "blackjackStart", "blackjackPlayerDrawHand", "blackjackContinue", "blackjackFinish", "blackjackHit", "blackjackStand", "blackjackDouble", "blackjackSplit", "parseFourInARow", "fourInARowAI", "parseHex", "hexAI", "parseMonopoly", "monopolyContinue"]
|
||||
|
||||
from .money import checkBalance, giveMoney, addMoney
|
||||
from .trivia import triviaCountPoints, triviaStart, triviaAnswer
|
||||
from .blackjack import blackjackShuffle, blackjackStart, blackjackPlayerDrawHand, blackjackContinue, blackjackFinish, blackjackHit, blackjackStand, blackjackDouble, blackjackSplit
|
||||
from .fourInARow import parseFourInARow, fourInARowAI
|
||||
from .hex import parseHex, hexAI
|
||||
from .monopoly import parseMonopoly, monopolyContinue
|
||||
|
@ -197,126 +197,18 @@ def blackjackHit(channel,user,handNumber = 0):
|
||||
data = json.load(f)
|
||||
|
||||
if user in data["blackjack games"][channel]["user hands"]:
|
||||
if data["blackjack games"][channel]["user hands"][user]["split"] == 0:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]
|
||||
handNumber = 0
|
||||
else:
|
||||
if handNumber != 0:
|
||||
if handNumber == 1:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]
|
||||
elif handNumber == 2:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["other hand"]
|
||||
elif handNumber == 3:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["third hand"]
|
||||
elif handNumber == 4:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["fourth hand"]
|
||||
else:
|
||||
logThis(user+" tried to hit without specifying which hand")
|
||||
return "You have to specify the hand you're hitting with."
|
||||
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]["round"] > 0:
|
||||
if hand["hit"] == False:
|
||||
if hand["standing"] == False:
|
||||
hand["hand"].append(drawCard(channel))
|
||||
hand["hit"] = True
|
||||
|
||||
handValue = calcHandValue(hand["hand"])
|
||||
|
||||
if handValue > 21:
|
||||
hand["busted"] = True
|
||||
|
||||
if handNumber == 2:
|
||||
data["blackjack games"][channel]["user hands"][user]["other hand"] = hand
|
||||
elif handNumber == 3:
|
||||
data["blackjack games"][channel]["user hands"][user]["third hand"] = hand
|
||||
elif handNumber == 4:
|
||||
data["blackjack games"][channel]["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)
|
||||
|
||||
response = "accept"
|
||||
roundDone = True
|
||||
|
||||
for person in data["blackjack games"][channel]["user hands"].values():
|
||||
if person["hit"] == False and person["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 0:
|
||||
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 1:
|
||||
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 2:
|
||||
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
return response + str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
|
||||
else:
|
||||
logThis(user+" is already standing")
|
||||
return "You can't hit when you're standing"
|
||||
else:
|
||||
logThis(user+" has already hit this round")
|
||||
return "You've already hit this round"
|
||||
else:
|
||||
logThis(user+" tried to hit on the 0th round")
|
||||
return "You can't hit before you see your cards"
|
||||
else:
|
||||
logThis(user+" tried to hit without being in the game")
|
||||
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)
|
||||
|
||||
if data["blackjack games"][channel]["user hands"][user]["split"] == 0:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]
|
||||
handNumber = 0
|
||||
else:
|
||||
if handNumber != 0:
|
||||
if handNumber == 1:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]
|
||||
elif handNumber == 2:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["other hand"]
|
||||
elif handNumber == 3:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["third hand"]
|
||||
elif handNumber == 4:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["fourth hand"]
|
||||
else:
|
||||
logThis(user+" tried to double without specifying which hand")
|
||||
return "You have to specify the hand you're doubling down.",""
|
||||
else:
|
||||
logThis(user+" tried to double without specifying which hand")
|
||||
return "You have to specify the hand you're doubling down.",""
|
||||
|
||||
|
||||
if data["blackjack games"][channel]["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)
|
||||
|
||||
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
|
||||
print(hand)
|
||||
|
||||
if hand != None:
|
||||
if data["blackjack games"][channel]["round"] > 0:
|
||||
if hand["hit"] == False:
|
||||
if hand["standing"] == False:
|
||||
hand["hand"].append(drawCard(channel))
|
||||
hand["hit"] = True
|
||||
hand["doubled"] = True
|
||||
hand["bet"] += bet
|
||||
|
||||
handValue = calcHandValue(hand["hand"])
|
||||
|
||||
|
||||
if handValue > 21:
|
||||
hand["busted"] = True
|
||||
@ -333,41 +225,93 @@ def blackjackDouble(channel,user,handNumber = 0):
|
||||
with open("resources/games/games.json", "w") as f:
|
||||
json.dump(data,f,indent=4)
|
||||
|
||||
roundDone = True
|
||||
response = "accept"
|
||||
roundDone = isRoundDone(data["blackjack games"][channel])
|
||||
|
||||
for person in data["blackjack games"][channel]["user hands"].values():
|
||||
if person["hit"] == False and person["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 0:
|
||||
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 1:
|
||||
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 2:
|
||||
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
|
||||
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 response + str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
|
||||
else:
|
||||
logThis(user+" doesn't have enough GwendoBucks")
|
||||
return "You don't have enough GwendoBucks",""
|
||||
logThis(user+" is already standing")
|
||||
return "You can't hit when you're standing"
|
||||
else:
|
||||
logThis(user+" tried to double on round "+str(data["blackjack games"][channel]["round"]))
|
||||
return "You can only double down on the first round",""
|
||||
logThis(user+" has already hit this round")
|
||||
return "You've already hit this round"
|
||||
else:
|
||||
logThis(user+" is already standing")
|
||||
return "You can't double when you're standing",""
|
||||
logThis(user+" tried to hit on the 0th round")
|
||||
return "You can't hit before you see your cards"
|
||||
else:
|
||||
logThis(user+" has already hit this round")
|
||||
return "You've already hit this round",""
|
||||
logThis(user+" didn't specify a hand")
|
||||
return "You need to specify a hand"
|
||||
else:
|
||||
logThis(user+" tried to double on the 0th round")
|
||||
return "You can't double down before you see your cards",""
|
||||
logThis(user+" tried to hit without being in the game")
|
||||
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)
|
||||
|
||||
if user in data["blackjack games"][channel]["user hands"]:
|
||||
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
|
||||
|
||||
if hand != None:
|
||||
if data["blackjack games"][channel]["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)
|
||||
|
||||
hand["hand"].append(drawCard(channel))
|
||||
hand["hit"] = True
|
||||
hand["doubled"] = True
|
||||
hand["bet"] += bet
|
||||
|
||||
handValue = calcHandValue(hand["hand"])
|
||||
|
||||
|
||||
if handValue > 21:
|
||||
hand["busted"] = True
|
||||
|
||||
if handNumber == 2:
|
||||
data["blackjack games"][channel]["user hands"][user]["other hand"] = hand
|
||||
elif handNumber == 3:
|
||||
data["blackjack games"][channel]["user hands"][user]["third hand"] = hand
|
||||
elif handNumber == 4:
|
||||
data["blackjack games"][channel]["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)
|
||||
|
||||
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"])
|
||||
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"]))
|
||||
return "You can only double down on the first round",""
|
||||
else:
|
||||
logThis(user+" is already standing")
|
||||
return "You can't double when you're standing",""
|
||||
else:
|
||||
logThis(user+" has already hit this round")
|
||||
return "You've already hit this round",""
|
||||
else:
|
||||
logThis(user+" tried to double on the 0th round")
|
||||
return "You can't double down before you see your cards",""
|
||||
else:
|
||||
logThis(user+" didn't specify a hand")
|
||||
return "You need to specify which hand"
|
||||
else:
|
||||
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):
|
||||
@ -375,62 +319,33 @@ def blackjackStand(channel,user,handNumber = 0):
|
||||
data = json.load(f)
|
||||
|
||||
if user in data["blackjack games"][channel]["user hands"]:
|
||||
if data["blackjack games"][channel]["user hands"][user]["split"] == 0:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]
|
||||
handNumber = 0
|
||||
else:
|
||||
if handNumber != 0:
|
||||
if handNumber == 1:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]
|
||||
elif handNumber == 2:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["other hand"]
|
||||
elif handNumber == 3:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["third hand"]
|
||||
elif handNumber == 4:
|
||||
hand = data["blackjack games"][channel]["user hands"][user]["fourth hand"]
|
||||
else:
|
||||
logThis(user+" tried to hit without specifying which hand")
|
||||
return "You have to specify the hand you're hitting with."
|
||||
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]["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)
|
||||
hand, handNumber = getHandNumber(data["blackjack games"][channel]["user hands"][user],handNumber)
|
||||
|
||||
response = "accept"
|
||||
roundDone = True
|
||||
if hand != None:
|
||||
if data["blackjack games"][channel]["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)
|
||||
|
||||
for person in data["blackjack games"][channel]["user hands"].values():
|
||||
if person["hit"] == False and person["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 0:
|
||||
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
response = "accept"
|
||||
roundDone = isRoundDone(data["blackjack games"][channel])
|
||||
|
||||
if person["split"] > 1:
|
||||
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 2:
|
||||
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
return response + str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
|
||||
return response + str(roundDone)[0] + str(data["blackjack games"][channel]["round"])
|
||||
else:
|
||||
logThis(user+" is already standing")
|
||||
return "You're already standing"
|
||||
else:
|
||||
logThis(user+" is already standing")
|
||||
return "You're already standing"
|
||||
logThis(user+" has already hit this round")
|
||||
return "You've already hit this round"
|
||||
else:
|
||||
logThis(user+" has already hit this round")
|
||||
return "You've already hit this round"
|
||||
logThis(user+" tried to stand on the first round")
|
||||
return "You can't stand before you see your cards"
|
||||
else:
|
||||
logThis(user+" tried to stand on the first round")
|
||||
return "You can't stand before you see your cards"
|
||||
logThis(user+" didn't specify a hand")
|
||||
return "You need to specify which hand"
|
||||
else:
|
||||
logThis(user+" tried to stand without being in the game")
|
||||
return "You have to enter the game before you can stand"
|
||||
@ -526,23 +441,7 @@ def blackjackSplit(channel,user,handNumber = 0):
|
||||
with open("resources/games/games.json", "w") as f:
|
||||
json.dump(data,f,indent=4)
|
||||
|
||||
roundDone = True
|
||||
|
||||
for person in data["blackjack games"][channel]["user hands"].values():
|
||||
if person["hit"] == False and person["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 0:
|
||||
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 1:
|
||||
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 2:
|
||||
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
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"])
|
||||
else:
|
||||
@ -744,4 +643,47 @@ def calcWinnings(hand, dealerValue, topLevel, dealerBlackjack, dealerBusted):
|
||||
netWinnings += netWinningsTemp
|
||||
reason += reasonTemp
|
||||
|
||||
return winnings, netWinnings, reason
|
||||
return winnings, netWinnings, reason
|
||||
|
||||
def getHandNumber(user,handNumber):
|
||||
try:
|
||||
hand = None
|
||||
|
||||
if user["split"] == 0:
|
||||
hand = user
|
||||
handNumber = 0
|
||||
else:
|
||||
if handNumber != 0:
|
||||
if handNumber == 1:
|
||||
hand = user
|
||||
elif handNumber == 2:
|
||||
hand = user["other hand"]
|
||||
elif handNumber == 3:
|
||||
hand = user["third hand"]
|
||||
elif handNumber == 4:
|
||||
hand = user["fourth hand"]
|
||||
|
||||
return hand, handNumber
|
||||
except:
|
||||
logThis("Problem with getHandNumber() (error code 1322)")
|
||||
|
||||
def isRoundDone(game):
|
||||
roundDone = True
|
||||
|
||||
for person in game["user hands"].values():
|
||||
if person["hit"] == False and person["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 0:
|
||||
if person["other hand"]["hit"] == False and person["other hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 1:
|
||||
if person["third hand"]["hit"] == False and person["third hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
if person["split"] > 2:
|
||||
if person["fourth hand"]["hit"] == False and person["fourth hand"]["standing"] == False:
|
||||
roundDone = False
|
||||
|
||||
return roundDone
|
||||
|
@ -22,7 +22,7 @@ def drawImage(channel):
|
||||
|
||||
dealerBusted = data["blackjack games"][channel]["dealer busted"]
|
||||
dealerBlackjack = data["blackjack games"][channel]["dealer blackjack"]
|
||||
|
||||
|
||||
try:
|
||||
if data["blackjack games"][channel]["all standing"] == False:
|
||||
dealerHand = drawHand(data["blackjack games"][channel]["dealer hand"],True,False,False)
|
||||
@ -36,7 +36,7 @@ def drawImage(channel):
|
||||
for x in range(len(hands)):
|
||||
key, value = list(hands.items())[x]
|
||||
key = getName(key)
|
||||
logThis("drawing "+key+"'s hand")
|
||||
#logThis("Drawing "+key+"'s hand")
|
||||
userHand = drawHand(value["hand"],False,value["busted"],value["blackjack"])
|
||||
try:
|
||||
if value["split"] == 3:
|
||||
|
@ -20,6 +20,9 @@ def drawImage(channel):
|
||||
exampleCircles = 100
|
||||
w, h = 2800,2000
|
||||
backgroundColor = (128,128,128,255)
|
||||
outlineColor = (0,0,0)
|
||||
player1Color = (200,0,0)
|
||||
player2Color = (255,255,0)
|
||||
boardColor = (0,0,170)
|
||||
placeSize = 285
|
||||
white = (255,255,255,160)
|
||||
@ -48,35 +51,33 @@ def drawImage(channel):
|
||||
|
||||
# This whole part was the easiest way to make a rectangle with rounded corners and an outline
|
||||
# - Corners:
|
||||
d.ellipse([(border,border),(border+cornerSize,border+cornerSize)],fill=boardColor,outline=(0,0,0),width=outlineSize)
|
||||
d.ellipse([(w-(border+cornerSize),h-(border+cornerSize)),(w-border,h-border)],fill=boardColor,outline=(0,0,0),width=outlineSize)
|
||||
d.ellipse([(border,h-(border+cornerSize)),(border+cornerSize,h-border)],fill=boardColor,outline=(0,0,0),width=outlineSize)
|
||||
d.ellipse([(w-(border+cornerSize),border),(w-border,border+cornerSize)],fill=boardColor,outline=(0,0,0),width=outlineSize)
|
||||
d.ellipse([(border,border),(border+cornerSize,border+cornerSize)],fill=boardColor,outline=outlineColor,width=outlineSize)
|
||||
d.ellipse([(w-(border+cornerSize),h-(border+cornerSize)),(w-border,h-border)],fill=boardColor,outline=outlineColor,width=outlineSize)
|
||||
d.ellipse([(border,h-(border+cornerSize)),(border+cornerSize,h-border)],fill=boardColor,outline=outlineColor,width=outlineSize)
|
||||
d.ellipse([(w-(border+cornerSize),border),(w-border,border+cornerSize)],fill=boardColor,outline=outlineColor,width=outlineSize)
|
||||
# - Rectangle:
|
||||
d.rectangle([(border+math.floor(cornerSize/2),border),(w-(border+math.floor(cornerSize/2)),h-border)],fill=boardColor,outline=(0,0,0),width=outlineSize)
|
||||
d.rectangle([(border,border+math.floor(cornerSize/2)),(w-border,h-(border+math.floor(cornerSize/2)))],fill=boardColor,outline=(0,0,0),width=outlineSize)
|
||||
d.rectangle([(border+math.floor(cornerSize/2),border),(w-(border+math.floor(cornerSize/2)),h-border)],fill=boardColor,outline=outlineColor,width=outlineSize)
|
||||
d.rectangle([(border,border+math.floor(cornerSize/2)),(w-border,h-(border+math.floor(cornerSize/2)))],fill=boardColor,outline=outlineColor,width=outlineSize)
|
||||
# - Removing outline on the inside:
|
||||
d.rectangle([(border+math.floor(cornerSize/2),border+math.floor(cornerSize/2)),(w-(border+math.floor(cornerSize/2)),h-(border+math.floor(cornerSize/2)))],fill=boardColor)
|
||||
d.ellipse([(border+outlineSize,border+outlineSize),(border+cornerSize-outlineSize,border+cornerSize-outlineSize)],fill=boardColor)
|
||||
d.ellipse([(w-(border+cornerSize)+outlineSize,h-(border+cornerSize)+outlineSize),(w-border-outlineSize,h-border-outlineSize)],fill=boardColor)
|
||||
d.ellipse([(border+outlineSize,h-(border+cornerSize)+outlineSize),(border+cornerSize-outlineSize,h-border-outlineSize)],fill=boardColor)
|
||||
d.ellipse([(w-(border+cornerSize)+outlineSize,border+outlineSize),(w-border-outlineSize,border+cornerSize-outlineSize)],fill=boardColor)
|
||||
d.rectangle([(border+math.floor(cornerSize/2),border+outlineSize),(w-(border+math.floor(cornerSize/2)),h-(border+outlineSize))],fill=boardColor)
|
||||
d.rectangle([(border+outlineSize,border+math.floor(cornerSize/2)),(w-(border+outlineSize),h-(border+math.floor(cornerSize/2)))],fill=boardColor)
|
||||
|
||||
for line in range(len(board)):
|
||||
for place in range(len(board[line])):
|
||||
piece = board[line][place]
|
||||
|
||||
if piece == 1:
|
||||
pieceColor = (255,255,0)
|
||||
pieceColor = player1Color
|
||||
elif piece == 2:
|
||||
pieceColor = (200,0,0)
|
||||
pieceColor = player2Color
|
||||
else:
|
||||
pieceColor = backgroundColor
|
||||
|
||||
startx = pieceStartx + placeGridSize[0]*place
|
||||
starty = pieceStarty + placeGridSize[1]*line
|
||||
|
||||
d.ellipse([(startx,starty),(startx+placeSize,starty+placeSize)],fill=pieceColor,outline=(0,0,0),width=outlineSize)
|
||||
d.ellipse([(startx,starty),(startx+placeSize,starty+placeSize)],fill=pieceColor,outline=outlineColor,width=outlineSize)
|
||||
|
||||
if data["4 in a row games"][channel]["winner"] != 0:
|
||||
coordinates = data["4 in a row games"][channel]["win coordinates"]
|
||||
@ -120,8 +121,7 @@ def drawImage(channel):
|
||||
winBar = winBar.rotate(diagonalAngle,expand=1)
|
||||
startx -= placeGridSize[0]*3 + border
|
||||
starty -= gridBorder + border
|
||||
|
||||
|
||||
|
||||
mask = winBar.copy()#.convert("L")
|
||||
#mask.putalpha(128)
|
||||
#mask.save("test.png")
|
||||
@ -133,11 +133,11 @@ def drawImage(channel):
|
||||
textPadding = 20
|
||||
|
||||
exampleHeight = h - border + int((bottomBorder+border)/2) - int(exampleCircles/2)
|
||||
d.ellipse([(border,exampleHeight),(border+exampleCircles),(exampleHeight+exampleCircles)],fill=(255,255,0),outline=(0,0,0),width=3)
|
||||
d.ellipse([(border,exampleHeight),(border+exampleCircles),(exampleHeight+exampleCircles)],fill=player1Color,outline=outlineColor,width=3)
|
||||
d.text((border+exampleCircles+textPadding,exampleHeight),player1,font=fnt,fill=(0,0,0))
|
||||
|
||||
textWidth = fnt.getsize(player2)[0]
|
||||
d.ellipse([(w-border-exampleCircles-textWidth-textPadding,exampleHeight),(w-border-textWidth-textPadding),(exampleHeight+exampleCircles)],fill=(255,0,0),outline=(0,0,0),width=3)
|
||||
d.ellipse([(w-border-exampleCircles-textWidth-textPadding,exampleHeight),(w-border-textWidth-textPadding),(exampleHeight+exampleCircles)],fill=player2Color,outline=outlineColor,width=3)
|
||||
d.text((w-border-textWidth,exampleHeight),player2,font=fnt,fill=(0,0,0))
|
||||
|
||||
|
||||
|
@ -18,13 +18,13 @@ def addMoney(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
|
||||
else:
|
||||
logThis("Error adding money")
|
||||
|
||||
|
||||
with open("resources/users.json", "w") as f:
|
||||
json.dump(data,f,indent=4)
|
||||
|
||||
@ -32,11 +32,11 @@ def addMoney(user,amount):
|
||||
def giveMoney(user,targetUser,amount):
|
||||
with open("resources/users.json", "r") as f:
|
||||
data = json.load(f)
|
||||
|
||||
|
||||
targetUser = getID(targetUser)
|
||||
|
||||
if amount > 0:
|
||||
if targetUser.startswith("#"):
|
||||
if targetUser != None:
|
||||
if user in data:
|
||||
if data[user]["money"] >= amount:
|
||||
addMoney(user,-1 * amount)
|
||||
|
141
funcs/games/monopoly.py
Normal file
141
funcs/games/monopoly.py
Normal file
@ -0,0 +1,141 @@
|
||||
import json, random
|
||||
|
||||
from funcs import getName, logThis
|
||||
from . import monopolyDraw
|
||||
|
||||
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)
|
||||
|
||||
if channel not in data:
|
||||
buildings = [0] * 40
|
||||
|
||||
data[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)
|
||||
|
||||
try:
|
||||
monopolyDraw.drawImage(channel)
|
||||
except:
|
||||
logThis("Error drawing board (error code 1640)")
|
||||
|
||||
return "Started a monopoly game. Use \"!monopoly join\" to join within the next minute.", True, False, True, True
|
||||
else:
|
||||
return "There's already a monopoly game going on.", False, False, False, False
|
||||
|
||||
def monopolyJoin(channel,user):
|
||||
with open("resources/games/monopolyGames.json", "r") as f:
|
||||
data = json.load(f)
|
||||
|
||||
if channel in data:
|
||||
if not data[channel]["started"]:
|
||||
if user not in data[channel]["players"]:
|
||||
if len(data[channel]["players"]) < 6:
|
||||
|
||||
data[channel]["players"][user] = {"position" : 0, "properties" : [], "money" : 1500, "doubles" : 0}
|
||||
|
||||
with open("resources/games/monopolyGames.json", "w") as f:
|
||||
json.dump(data,f,indent=4)
|
||||
|
||||
return 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:
|
||||
return "You're already in the game!", False, False, False, False
|
||||
else:
|
||||
return "It's too late to join.", False, False, False, False
|
||||
else:
|
||||
return "There's no game going on.", False, False, False, False
|
||||
|
||||
def parseMonopoly(command, channel, user):
|
||||
logThis("Parsing "+command)
|
||||
commands = command.split()
|
||||
if command in [" ", ""] or commands[0] == "start":
|
||||
try:
|
||||
return monopolyStart(channel)
|
||||
except:
|
||||
logThis("Error starting game (error code 1620)")
|
||||
elif commands[0] == "join":
|
||||
try:
|
||||
return monopolyJoin(channel,user)
|
||||
except:
|
||||
logThis("Error joining game (error code 1630)")
|
||||
elif commands[0] == "roll":
|
||||
try:
|
||||
return 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)
|
||||
|
||||
if channel in data:
|
||||
if data[channel]["started"] == False:
|
||||
data[channel]["started"] = True
|
||||
playerList = list(data[channel]["players"].keys())
|
||||
random.shuffle(playerList)
|
||||
data[channel]["player list"] = playerList
|
||||
turn = 0
|
||||
|
||||
else:
|
||||
if data[channel]["last roll"][0] == data[channel]["last roll"][1]:
|
||||
turn = data[channel]["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)
|
||||
|
||||
try:
|
||||
monopolyDraw.drawImage(channel)
|
||||
except:
|
||||
logThis("Error drawing board (error code 1640)")
|
||||
|
||||
message = "It's "+getName(playerList[turn])+"'s turn. Use the 🎲 reaction to roll. You can also use \"!monopoly trade\" at any time."
|
||||
return message, True, True, False
|
||||
|
||||
def monopolyRoll(channel,user):
|
||||
with open("resources/games/monopolyGames.json", "r") as f:
|
||||
data = json.load(f)
|
||||
|
||||
turn = data[channel]["turn"]
|
||||
currentPlayer = data[channel]["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])+"."
|
||||
if rolls[0] == rolls[1]:
|
||||
message += " Doubbles!"
|
||||
|
||||
roll = rolls[0] + rolls[1]
|
||||
oldPosition = data[channel]["players"][user]["position"]
|
||||
newPosition = (oldPosition + roll)%40
|
||||
if newPosition < oldPosition:
|
||||
data[channel]["players"][user]["money"] += rulesAndTerms["pass go money"]
|
||||
message += "\nYou passed go and got "+str(rulesAndTerms["pass go money"])+" "+rulesAndTerms["money term"]+"."
|
||||
|
||||
data[channel]["players"][user]["position"] = newPosition
|
||||
data[channel]["last roll"] = rolls
|
||||
|
||||
with open("resources/games/monopolyGames.json", "w") as f:
|
||||
json.dump(data,f,indent=4)
|
||||
|
||||
try:
|
||||
monopolyDraw.drawImage(channel)
|
||||
except:
|
||||
logThis("Error drawing board (error code 1640)")
|
||||
|
||||
return message, True, True, False, True
|
||||
else: return "", False, False, False, False
|
57
funcs/games/monopolyDraw.py
Normal file
57
funcs/games/monopolyDraw.py
Normal file
@ -0,0 +1,57 @@
|
||||
import math, json
|
||||
|
||||
from funcs import logThis
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
w, h = 1440, 1440
|
||||
largeSpace = 191
|
||||
smallSpace = math.floor((w - 2*largeSpace)/9)
|
||||
avatarSize = 50
|
||||
avatarHalf = math.floor(avatarSize/2)
|
||||
|
||||
def drawImage(channel):
|
||||
logThis("Drawing monopoly board for "+channel)
|
||||
with open("resources/games/monopolyGames.json", "r") as f:
|
||||
data = json.load(f)
|
||||
|
||||
board = Image.open("resources/games/monopolyBoard.png")
|
||||
d = ImageDraw.Draw(board,"RGBA")
|
||||
|
||||
for key, value in list(data[channel]["players"].items()):
|
||||
logThis("Drawing "+key)
|
||||
try:
|
||||
x, y = getPosition(value["position"])
|
||||
except:
|
||||
logThis("Error getting position (error code 1641)")
|
||||
print(str(x)+", "+str(y))
|
||||
d.ellipse([(x-avatarHalf,y-avatarHalf),(x+avatarHalf,y+avatarHalf)],fill=(255,0,0))
|
||||
|
||||
board.save("resources/games/monopolyBoards/monopolyBoard"+channel+".png")
|
||||
|
||||
|
||||
def getPosition(positionNumber):
|
||||
print(positionNumber)
|
||||
|
||||
x, y = 0, 0
|
||||
if positionNumber == 0 or positionNumber >= 30:
|
||||
x = math.floor(largeSpace/2)
|
||||
elif positionNumber > 0 and positionNumber < 10:
|
||||
x = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*positionNumber)
|
||||
elif positionNumber >= 10 and positionNumber <= 20:
|
||||
x = w - math.floor(largeSpace/2)
|
||||
elif positionNumber > 20 and positionNumber < 30:
|
||||
x = w - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 20))
|
||||
|
||||
if positionNumber >= 0 and positionNumber <= 20:
|
||||
y = math.floor(largeSpace/2)
|
||||
elif positionNumber > 10 and positionNumber < 20:
|
||||
y = math.floor(largeSpace - (smallSpace/2)) + (smallSpace*(positionNumber-10))
|
||||
elif positionNumber >= 20 and positionNumber <= 30:
|
||||
y = h - math.floor(largeSpace/2)
|
||||
elif positionNumber > 30:
|
||||
y = h - math.floor(largeSpace - (smallSpace/2)) - (smallSpace*(positionNumber - 30))
|
||||
|
||||
return x, y
|
||||
|
||||
|
@ -13,6 +13,7 @@ logging.basicConfig(filename="gwendolyn.log", level=logging.INFO)
|
||||
# Capitalizes all words except some of them
|
||||
no_caps_list = ["of","the"]
|
||||
def cap(s):
|
||||
# Capitalizes a strink like a movie title
|
||||
word_number = 0
|
||||
lst = s.split()
|
||||
res = ''
|
||||
@ -25,7 +26,7 @@ def cap(s):
|
||||
return res
|
||||
|
||||
def time_in_range(start, end, x):
|
||||
"""Return true if x is in the range [start, end]"""
|
||||
# Return true if x is in the range [start, end]
|
||||
if start <= end:
|
||||
return start <= x <= end
|
||||
else:
|
||||
@ -134,146 +135,45 @@ def findWikiPage(search : str):
|
||||
logThis("Couldn't find the page (error code 1002)")
|
||||
return "", "Couldn't find page (error code 1002)", ""
|
||||
|
||||
def makeJsonFile(path,content):
|
||||
# Creates json file if it doesn't exist
|
||||
try:
|
||||
f = open(path,"r")
|
||||
except:
|
||||
logThis(path.split("/")[-1]+" didn't exist. Making it now.")
|
||||
with open(path,"w") as f:
|
||||
json.dump(content,f,indent = 4)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def makeTxtFile(path,content):
|
||||
# Creates txt file if it doesn't exist
|
||||
try:
|
||||
f = open(path,"r")
|
||||
except:
|
||||
logThis(path.split("/")[-1]+" didn't exist. Making it now.")
|
||||
with open(path,"w") as f:
|
||||
f.write(content)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def makeFolder(path):
|
||||
if os.path.isdir(path) == False:
|
||||
os.makedirs(path)
|
||||
logThis("The "+path.split("/")[-1]+" directory didn't exist")
|
||||
|
||||
def makeFiles():
|
||||
# Creates swcharacters.json if it doesn't exist
|
||||
try:
|
||||
f = open("resources/starWars/swcharacters.json","r")
|
||||
except:
|
||||
logThis("swcharacters.json didn't exist. Making it now.")
|
||||
emptyDict = {}
|
||||
with open("resources/starWars/swcharacters.json","w") as f:
|
||||
json.dump(emptyDict,f,indent = 4)
|
||||
finally:
|
||||
f.close()
|
||||
with open("resources/startingFiles.json") as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Creates games.json if it doesn't exist
|
||||
try:
|
||||
f = open("resources/games/games.json","r")
|
||||
except:
|
||||
logThis("games.json didn't exist. Making it now.")
|
||||
data = {"trivia questions":{},"blackjack games":{},"4 in a row games": {},"users":{}}
|
||||
with open("resources/games/games.json","w") as f:
|
||||
json.dump(data,f,indent = 4)
|
||||
finally:
|
||||
f.close()
|
||||
for path, content in data["json"].items():
|
||||
makeJsonFile(path,content)
|
||||
|
||||
# Creates hexGames.json if it doesn't exist
|
||||
try:
|
||||
f = open("resources/games/hexGames.json","r")
|
||||
except:
|
||||
logThis("hexGames.json didn't exist. Making it now.")
|
||||
data = {}
|
||||
with open("resources/games/hexGames.json","w") as f:
|
||||
json.dump(data,f,indent = 4)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
# Creates monsters.json if it doesn't exist
|
||||
try:
|
||||
f = open("resources/lookup/monsters.json","r")
|
||||
except:
|
||||
logThis("monsters.json didn't exist. Making it now.")
|
||||
with open("resources/lookup/lookupExamples.json") as f:
|
||||
data = json.load(f)["monster"]
|
||||
with open("resources/lookup/monsters.json","w") as f:
|
||||
json.dump(data,f,indent = 4)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
# Creates spells.json if it doesn't exist
|
||||
try:
|
||||
f = open("resources/lookup/spells.json","r")
|
||||
except:
|
||||
logThis("spells.json didn't exist. Making it now.")
|
||||
with open("resources/lookup/lookupExamples.json") as f:
|
||||
data = json.load(f)["spell"]
|
||||
with open("resources/lookup/spells.json","w") as f:
|
||||
json.dump(data,f,indent = 4)
|
||||
finally:
|
||||
f.close()
|
||||
for path, content in data["txt"].items():
|
||||
makeTxtFile(path,content)
|
||||
|
||||
# Creates users.json if it doesn't exist
|
||||
try:
|
||||
f = open("resources/users.json","r")
|
||||
except:
|
||||
logThis("users.json didn't exist. Making it now.")
|
||||
data = {}
|
||||
with open("resources/users.json","w") as f:
|
||||
json.dump(data,f,indent = 4)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
# Creates destinyPoints.txt if it doesn't exist
|
||||
try:
|
||||
f = open("resources/starWars/destinyPoints.txt","r")
|
||||
except:
|
||||
logThis("destinyPoints.txt didn't exist. Making it now.")
|
||||
with open("resources/starWars/destinyPoints.txt","w") as f:
|
||||
f.write("")
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
# Creates movies.txt if it doesn't exist
|
||||
try:
|
||||
f = open("resources/movies.txt","r")
|
||||
except:
|
||||
logThis("movies.txt didn't exist. Making it now.")
|
||||
with open("resources/movies.txt","w") as f:
|
||||
f.write("The Room")
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
# Creates names.txt if it doesn't exist
|
||||
try:
|
||||
f = open("resources/names.txt","r")
|
||||
except:
|
||||
logThis("names.txt didn't exist. Making it now.")
|
||||
with open("resources/names.txt","w") as f:
|
||||
f.write("Gandalf")
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
# Creates token.txt if it doesn't exist
|
||||
try:
|
||||
f = open("token.txt","r")
|
||||
except:
|
||||
logThis("token.txt didn't exist. Write your bot token below, or in token.txt later.")
|
||||
token = input()
|
||||
with open("token.txt","w") as f:
|
||||
f.write(token)
|
||||
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
# Creates the blackjacktables foulder if it doesn't exist
|
||||
if os.path.isdir("resources/games/blackjackTables") == False:
|
||||
os.makedirs("resources/games/blackjackTables")
|
||||
logThis("The tables directory didn't exist")
|
||||
|
||||
# Creates the 4InARowBoards foulder if it doesn't exist
|
||||
if os.path.isdir("resources/games/4InARowBoards") == False:
|
||||
os.makedirs("resources/games/4InARowBoards")
|
||||
logThis("The 4 in a row boards directory didn't exist")
|
||||
|
||||
# Creates the hexBoards foulder if it doesn't exist
|
||||
if os.path.isdir("resources/games/hexBoards") == False:
|
||||
os.makedirs("resources/games/hexBoards")
|
||||
logThis("The Hex boards directory didn't exist")
|
||||
|
||||
# Creates the oldImages foulder if it doesn't exist
|
||||
if os.path.isdir("resources/games/oldImages") == False:
|
||||
os.makedirs("resources/games/oldImages")
|
||||
logThis("The old images directory didn't exist")
|
||||
|
||||
# Creates the blackjackCards foulder if it doesn't exist
|
||||
if os.path.isdir("resources/games/blackjackCards") == False:
|
||||
os.makedirs("resources/games/blackjackCards")
|
||||
logThis("The blackjack cards directory didn't exist")
|
||||
|
||||
# Creates the hilo foulder if it doesn't exist
|
||||
if os.path.isdir("resources/games/hilo") == False:
|
||||
os.makedirs("resources/games/hilo")
|
||||
logThis("The hi-lo directory didn't exist")
|
||||
for path in data["folder"]:
|
||||
makeFolder(path)
|
||||
|
||||
# Replaces multiple things with the same thing
|
||||
def replaceMultiple(mainString, toBeReplaces, newString):
|
||||
@ -286,7 +186,7 @@ def replaceMultiple(mainString, toBeReplaces, newString):
|
||||
|
||||
return mainString
|
||||
|
||||
def emojiToNumber(emoji):
|
||||
def emojiToCommand(emoji):
|
||||
if emoji == "1️⃣":
|
||||
return 1
|
||||
elif emoji == "2️⃣":
|
||||
@ -301,21 +201,21 @@ def emojiToNumber(emoji):
|
||||
return 6
|
||||
elif emoji == "7️⃣":
|
||||
return 7
|
||||
elif 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), "r") as 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)]["turn"]
|
||||
print(user)
|
||||
print(data["4 in a row games"][str(channel)]["players"][turn])
|
||||
if user == data["4 in a row games"][str(channel)]["players"][turn]:
|
||||
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")
|
||||
@ -323,16 +223,31 @@ def fiarReactionTest(channel,message,user):
|
||||
else:
|
||||
return False, 0
|
||||
|
||||
def monopolyReactionTest(channel,message):
|
||||
with open("resources/games/oldImages/monopoly"+str(channel.id), "r") as f:
|
||||
oldImage = int(f.read())
|
||||
|
||||
if message.id == oldImage:
|
||||
logThis("They reacted to the monopoly game")
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def stopServer():
|
||||
with open("resources/games/games.json","r") as f:
|
||||
data = json.load(f)
|
||||
games = json.load(f)
|
||||
|
||||
data["trivia questions"] = {}
|
||||
data["blackjack games"] = {}
|
||||
data["4 in a row games"] = {}
|
||||
games["trivia questions"] = {}
|
||||
games["blackjack games"] = {}
|
||||
games["4 in a row games"] = {}
|
||||
|
||||
with open("resources/games/games.json","w") as f:
|
||||
json.dump(data,f,indent=4)
|
||||
json.dump(games,f,indent=4)
|
||||
|
||||
emptyDict = {}
|
||||
|
||||
with open("resources/games/monopolyGames.json", "w") as f:
|
||||
json.dump(emptyDict,f,indent=4)
|
||||
|
||||
def deleteGame(gameType,channel):
|
||||
with open("resources/games/games.json", "r") as f:
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""I stole this."""
|
||||
"""Rolling dice."""
|
||||
|
||||
__all__ = ["roll_dice"]
|
||||
|
||||
|
@ -1,560 +1,20 @@
|
||||
import random
|
||||
import re
|
||||
import traceback
|
||||
from heapq import nlargest, nsmallest
|
||||
from math import floor
|
||||
from re import IGNORECASE
|
||||
import d20
|
||||
|
||||
import numexpr
|
||||
class MyStringifier(d20.MarkdownStringifier):
|
||||
|
||||
from . import errors
|
||||
#from funcs import logThis
|
||||
def _str_expression(self, node):
|
||||
|
||||
VALID_OPERATORS = 'k|rr|ro|mi|ma|ra|e|p'
|
||||
VALID_OPERATORS_ARRAY = VALID_OPERATORS.split('|')
|
||||
VALID_OPERATORS_2 = re.compile('|'.join(["({})".format(i) for i in VALID_OPERATORS_ARRAY]))
|
||||
DICE_PATTERN = re.compile(
|
||||
r'^\s*(?:(?:(\d*d\d+)(?:(?:' + VALID_OPERATORS + r')(?:[lh<>]?\d+))*|(\d+)|([-+*/().=])?)\s*(\[.*\])?)(.*?)\s*$',
|
||||
IGNORECASE)
|
||||
|
||||
|
||||
def roll_dice(author : str, rollStr : str = "1d20"):
|
||||
if rollStr == '0/0': # easter eggs
|
||||
return("What do you expect me to do, destroy the universe?")
|
||||
|
||||
adv = 0
|
||||
if re.search('(^|\s+)(adv|dis)(\s+|$)', rollStr) is not None:
|
||||
adv = 1 if re.search('(^|\s+)adv(\s+|$)', rollStr) is not None else -1
|
||||
rollStr = re.sub('(adv|dis)(\s+|$)', '', rollStr)
|
||||
res = roll(rollStr, adv=adv)
|
||||
out = res.result
|
||||
outStr = author + ' :game_die:\n' + out
|
||||
if len(outStr) > 1999:
|
||||
outputs = author + ' :game_die:\n[Output truncated due to length]\n**Result:** ' + str(res.plain)
|
||||
else:
|
||||
outputs = outStr
|
||||
return(outputs)
|
||||
|
||||
def list_get(index, default, l):
|
||||
try:
|
||||
a = l[index]
|
||||
except IndexError:
|
||||
a = default
|
||||
return a
|
||||
|
||||
|
||||
def roll(rollStr, adv: int = 0, rollFor='', inline=False, double=False, show_blurbs=True, **kwargs):
|
||||
roller = Roll()
|
||||
result = roller.roll(rollStr, adv, rollFor, inline, double, show_blurbs, **kwargs)
|
||||
return result
|
||||
|
||||
|
||||
def get_roll_comment(rollStr):
|
||||
"""Returns: A two-tuple (dice without comment, comment)"""
|
||||
try:
|
||||
comment = ''
|
||||
no_comment = ''
|
||||
dice_set = re.split('([-+*/().=])', rollStr)
|
||||
dice_set = [d for d in dice_set if not d in (None, '')]
|
||||
#logThis("Found dice set: " + str(dice_set))
|
||||
for index, dice in enumerate(dice_set):
|
||||
match = DICE_PATTERN.match(dice)
|
||||
#logThis("Found dice group: " + str(match.groups()))
|
||||
no_comment += dice.replace(match.group(5), '')
|
||||
if match.group(5):
|
||||
comment = match.group(5) + ''.join(dice_set[index + 1:])
|
||||
break
|
||||
|
||||
return no_comment, comment
|
||||
except:
|
||||
pass
|
||||
return rollStr, ''
|
||||
|
||||
|
||||
class Roll(object):
|
||||
def __init__(self, parts=None):
|
||||
if parts ==None:
|
||||
parts = []
|
||||
self.parts = parts
|
||||
|
||||
def get_crit(self):
|
||||
"""Returns: 0 for no crit, 1 for 20, 2 for 1."""
|
||||
try:
|
||||
crit = next(p.get_crit() for p in self.parts if isinstance(p, SingleDiceGroup))
|
||||
except StopIteration:
|
||||
crit = 0
|
||||
return crit
|
||||
|
||||
def get_total(self):
|
||||
"""Returns: int"""
|
||||
return numexpr.evaluate(''.join(p.get_eval() for p in self.parts if not isinstance(p, Comment)))
|
||||
|
||||
# # Dice Roller
|
||||
def roll(self, rollStr, adv: int = 0, rollFor='', inline=False, double=False, show_blurbs=True, **kwargs):
|
||||
try:
|
||||
if '**' in rollStr:
|
||||
raise errors.InvalidArgument("Exponents are currently disabled.")
|
||||
self.parts = []
|
||||
# split roll string into XdYoptsSel [comment] or Op
|
||||
# set remainder to comment
|
||||
# parse each, returning a SingleDiceResult
|
||||
dice_set = re.split('([-+*/().=])', rollStr)
|
||||
dice_set = [d for d in dice_set if not d in (None, '')]
|
||||
#logThis("Found dice set: " + str(dice_set))
|
||||
for index, dice in enumerate(dice_set):
|
||||
match = DICE_PATTERN.match(dice)
|
||||
#logThis("Found dice group: " + str(match.groups()))
|
||||
# check if it's dice
|
||||
if match.group(1):
|
||||
roll = self.roll_one(dice.replace(match.group(5), ''), adv)
|
||||
self.parts.append(roll)
|
||||
# or a constant
|
||||
elif match.group(2):
|
||||
self.parts.append(Constant(value=int(match.group(2)), annotation=match.group(4)))
|
||||
# or an operator
|
||||
elif not match.group(5):
|
||||
self.parts.append(Operator(op=match.group(3), annotation=match.group(4)))
|
||||
|
||||
if match.group(5):
|
||||
self.parts.append(Comment(match.group(5) + ''.join(dice_set[index + 1:])))
|
||||
break
|
||||
|
||||
# calculate total
|
||||
crit = self.get_crit()
|
||||
try:
|
||||
total = self.get_total()
|
||||
except SyntaxError:
|
||||
raise errors.InvalidArgument("No dice found to roll.")
|
||||
rolled = ' '.join(str(res) for res in self.parts if not isinstance(res, Comment))
|
||||
if rollFor =='':
|
||||
rollFor = ''.join(str(c) for c in self.parts if isinstance(c, Comment))
|
||||
# return final solution
|
||||
if not inline:
|
||||
# Builds end result while showing rolls
|
||||
reply = ' '.join(
|
||||
str(res) for res in self.parts if not isinstance(res, Comment)) + '\n**Total:** ' + str(
|
||||
floor(total))
|
||||
skeletonReply = reply
|
||||
rollFor = rollFor if rollFor != '' else 'Result'
|
||||
reply = '**{}:** '.format(rollFor) + reply
|
||||
if show_blurbs:
|
||||
if adv == 1:
|
||||
reply += '\n**Rolled with Advantage**'
|
||||
elif adv == -1:
|
||||
reply += '\n**Rolled with Disadvantage**'
|
||||
if crit == 1:
|
||||
critStr = "\n_**Critical Hit!**_ "
|
||||
reply += critStr
|
||||
elif crit == 2:
|
||||
critStr = "\n_**Critical Fail!**_ "
|
||||
reply += critStr
|
||||
else:
|
||||
# Builds end result while showing rolls
|
||||
reply = ' '.join(str(res) for res in self.parts if not isinstance(res, Comment)) + ' = `' + str(
|
||||
floor(total)) + '`'
|
||||
skeletonReply = reply
|
||||
rollFor = rollFor if rollFor != '' else 'Result'
|
||||
reply = '**{}:** '.format(rollFor) + reply
|
||||
if show_blurbs:
|
||||
if adv == 1:
|
||||
reply += '\n**Rolled with Advantage**'
|
||||
elif adv == -1:
|
||||
reply += '\n**Rolled with Disadvantage**'
|
||||
if crit == 1:
|
||||
critStr = "\n_**Critical Hit!**_ "
|
||||
reply += critStr
|
||||
elif crit == 2:
|
||||
critStr = "\n_**Critical Fail!**_ "
|
||||
reply += critStr
|
||||
reply = re.sub(' +', ' ', reply)
|
||||
skeletonReply = re.sub(' +', ' ', str(skeletonReply))
|
||||
return DiceResult(result=int(floor(total)), verbose_result=reply, crit=crit, rolled=rolled,
|
||||
skeleton=skeletonReply, raw_dice=self)
|
||||
except Exception as ex:
|
||||
if not isinstance(ex, (SyntaxError, KeyError, errors.AvraeException)):
|
||||
#logThis('Error in roll() caused by roll {}:'.format(rollStr))
|
||||
traceback.print_exc()
|
||||
return DiceResult(verbose_result="Invalid input: {}".format(ex))
|
||||
|
||||
def roll_one(self, dice, adv: int = 0):
|
||||
result = SingleDiceGroup()
|
||||
result.rolled = []
|
||||
# splits dice and comments
|
||||
split = re.match(r'^([^\[\]]*?)\s*(\[.*\])?\s*$', dice)
|
||||
dice = split.group(1).strip()
|
||||
annotation = split.group(2)
|
||||
result.annotation = annotation if annotation != None else ''
|
||||
# Recognizes dice
|
||||
obj = re.findall('\d+', dice)
|
||||
obj = [int(x) for x in obj]
|
||||
numArgs = len(obj)
|
||||
|
||||
ops = []
|
||||
if numArgs == 1:
|
||||
if not dice.startswith('d'):
|
||||
raise errors.InvalidArgument('Please pass in the value of the dice.')
|
||||
numDice = 1
|
||||
diceVal = obj[0]
|
||||
if adv != 0 and diceVal == 20:
|
||||
numDice = 2
|
||||
ops = ['k', 'h1'] if adv ==1 else ['k', 'l1']
|
||||
elif numArgs == 2:
|
||||
numDice = obj[0]
|
||||
diceVal = obj[-1]
|
||||
if adv != 0 and diceVal == 20:
|
||||
ops = ['k', 'h' + str(numDice)] if adv ==1 else ['k', 'l' + str(numDice)]
|
||||
numDice = numDice * 2
|
||||
else: # split into xdy and operators
|
||||
numDice = obj[0]
|
||||
diceVal = obj[1]
|
||||
dice = re.split('(\d+d\d+)', dice)[-1]
|
||||
ops = VALID_OPERATORS_2.split(dice)
|
||||
ops = [a for a in ops if a != None]
|
||||
|
||||
# dice repair/modification
|
||||
if numDice > 300 or diceVal < 1:
|
||||
raise errors.InvalidArgument('Too many dice rolled.')
|
||||
|
||||
result.max_value = diceVal
|
||||
result.num_dice = numDice
|
||||
result.operators = ops
|
||||
|
||||
for _ in range(numDice):
|
||||
try:
|
||||
tempdice = SingleDice()
|
||||
tempdice.value = random.randint(1, diceVal)
|
||||
tempdice.rolls = [tempdice.value]
|
||||
tempdice.max_value = diceVal
|
||||
tempdice.kept = True
|
||||
result.rolled.append(tempdice)
|
||||
except:
|
||||
result.rolled.append(SingleDice())
|
||||
|
||||
if ops != None:
|
||||
|
||||
rerollList = []
|
||||
reroll_once = []
|
||||
keep = None
|
||||
to_explode = []
|
||||
to_reroll_add = []
|
||||
|
||||
valid_operators = VALID_OPERATORS_ARRAY
|
||||
last_operator = None
|
||||
for index, op in enumerate(ops):
|
||||
if last_operator != None and op in valid_operators and not op == last_operator:
|
||||
result.reroll(reroll_once, 1)
|
||||
reroll_once = []
|
||||
result.reroll(rerollList, greedy=True)
|
||||
rerollList = []
|
||||
result.keep(keep)
|
||||
keep = None
|
||||
result.reroll(to_reroll_add, 1, keep_rerolled=True, unique=True)
|
||||
to_reroll_add = []
|
||||
result.reroll(to_explode, greedy=True, keep_rerolled=True)
|
||||
to_explode = []
|
||||
if op == 'rr':
|
||||
rerollList += parse_selectors([list_get(index + 1, 0, ops)], result, greedy=True)
|
||||
if op == 'k':
|
||||
keep = [] if keep ==None else keep
|
||||
keep += parse_selectors([list_get(index + 1, 0, ops)], result)
|
||||
if op == 'p':
|
||||
keep = [] if keep ==None else keep
|
||||
keep += parse_selectors([list_get(index + 1, 0, ops)], result, inverse=True)
|
||||
if op == 'ro':
|
||||
reroll_once += parse_selectors([list_get(index + 1, 0, ops)], result)
|
||||
if op == 'mi':
|
||||
_min = list_get(index + 1, 0, ops)
|
||||
for r in result.rolled:
|
||||
if r.value < int(_min):
|
||||
r.update(int(_min))
|
||||
if op == 'ma':
|
||||
_max = list_get(index + 1, 0, ops)
|
||||
for r in result.rolled:
|
||||
if r.value > int(_max):
|
||||
r.update(int(_max))
|
||||
if op == 'ra':
|
||||
to_reroll_add += parse_selectors([list_get(index + 1, 0, ops)], result)
|
||||
if op == 'e':
|
||||
to_explode += parse_selectors([list_get(index + 1, 0, ops)], result, greedy=True)
|
||||
if op in valid_operators:
|
||||
last_operator = op
|
||||
result.reroll(reroll_once, 1)
|
||||
result.reroll(rerollList, greedy=True)
|
||||
result.keep(keep)
|
||||
result.reroll(to_reroll_add, 1, keep_rerolled=True, unique=True)
|
||||
result.reroll(to_explode, greedy=True, keep_rerolled=True)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class Part:
|
||||
"""Class to hold one part of the roll string."""
|
||||
pass
|
||||
|
||||
|
||||
class SingleDiceGroup(Part):
|
||||
def __init__(self, num_dice: int = 0, max_value: int = 0, rolled=None, annotation: str = "", result: str = "",
|
||||
operators=None):
|
||||
if operators ==None:
|
||||
operators = []
|
||||
if rolled ==None:
|
||||
rolled = []
|
||||
self.num_dice = num_dice
|
||||
self.max_value = max_value
|
||||
self.rolled = rolled # list of SingleDice
|
||||
self.annotation = annotation
|
||||
self.result = result
|
||||
self.operators = operators
|
||||
|
||||
def keep(self, rolls_to_keep):
|
||||
if rolls_to_keep ==None: return
|
||||
for _roll in self.rolled:
|
||||
if not _roll.value in rolls_to_keep:
|
||||
_roll.kept = False
|
||||
elif _roll.kept:
|
||||
rolls_to_keep.remove(_roll.value)
|
||||
|
||||
def reroll(self, rerollList, max_iterations=1000, greedy=False, keep_rerolled=False, unique=False):
|
||||
if not rerollList: return # don't reroll nothing - minor optimization
|
||||
if unique:
|
||||
rerollList = list(set(rerollList)) # remove duplicates
|
||||
if len(rerollList) > 100:
|
||||
raise OverflowError("Too many dice to reroll (max 100)")
|
||||
last_index = 0
|
||||
count = 0
|
||||
should_continue = True
|
||||
while should_continue: # let's only iterate 250 times for sanity
|
||||
should_continue = False
|
||||
if any(d.value in set(rerollList) for d in self.rolled[last_index:] if d.kept and not d.exploded):
|
||||
should_continue = True
|
||||
to_extend = []
|
||||
for r in self.rolled[last_index:]: # no need to recheck everything
|
||||
count += 1
|
||||
if count > max_iterations:
|
||||
should_continue = False
|
||||
if r.value in rerollList and r.kept and not r.exploded:
|
||||
try:
|
||||
tempdice = SingleDice()
|
||||
tempdice.value = random.randint(1, self.max_value)
|
||||
tempdice.rolls = [tempdice.value]
|
||||
tempdice.max_value = self.max_value
|
||||
tempdice.kept = True
|
||||
to_extend.append(tempdice)
|
||||
if not keep_rerolled:
|
||||
r.drop()
|
||||
else:
|
||||
r.explode()
|
||||
except:
|
||||
to_extend.append(SingleDice())
|
||||
if not keep_rerolled:
|
||||
r.drop()
|
||||
else:
|
||||
r.explode()
|
||||
if not greedy:
|
||||
rerollList.remove(r.value)
|
||||
last_index = len(self.rolled)
|
||||
self.rolled.extend(to_extend)
|
||||
|
||||
def get_total(self):
|
||||
"""Returns:
|
||||
int - The total value of the dice."""
|
||||
return sum(r.value for r in self.rolled if r.kept)
|
||||
|
||||
def get_eval(self):
|
||||
return str(self.get_total())
|
||||
|
||||
def get_num_kept(self):
|
||||
return sum(1 for r in self.rolled if r.kept)
|
||||
|
||||
def get_crit(self):
|
||||
"""Returns:
|
||||
int - 0 for no crit, 1 for crit, 2 for crit fail."""
|
||||
if self.get_num_kept() == 1 and self.max_value == 20:
|
||||
if self.get_total() == 20:
|
||||
return 1
|
||||
elif self.get_total() == 1:
|
||||
return 2
|
||||
return 0
|
||||
|
||||
def __str__(self):
|
||||
return "{0.num_dice}d{0.max_value}{1} ({2}) {0.annotation}".format(
|
||||
self, ''.join(self.operators), ', '.join(str(r) for r in self.rolled))
|
||||
|
||||
def to_dict(self):
|
||||
return {'type': 'dice', 'dice': [d.to_dict() for d in self.rolled], 'annotation': self.annotation,
|
||||
'value': self.get_total(), 'is_crit': self.get_crit(), 'num_kept': self.get_num_kept(),
|
||||
'text': str(self), 'num_dice': self.num_dice, 'dice_size': self.max_value, 'operators': self.operators}
|
||||
|
||||
|
||||
class SingleDice:
|
||||
def __init__(self, value: int = 0, max_value: int = 0, kept: bool = True, exploded: bool = False):
|
||||
self.value = value
|
||||
self.max_value = max_value
|
||||
self.kept = kept
|
||||
self.rolls = [value] # list of ints (for X -> Y -> Z)
|
||||
self.exploded = exploded
|
||||
|
||||
def drop(self):
|
||||
self.kept = False
|
||||
|
||||
def explode(self):
|
||||
self.exploded = True
|
||||
|
||||
def update(self, new_value):
|
||||
self.value = new_value
|
||||
self.rolls.append(new_value)
|
||||
|
||||
def __str__(self):
|
||||
formatted_rolls = [str(r) for r in self.rolls]
|
||||
if int(formatted_rolls[-1]) == self.max_value or int(formatted_rolls[-1]) == 1:
|
||||
formatted_rolls[-1] = '**' + formatted_rolls[-1] + '**'
|
||||
if self.exploded:
|
||||
formatted_rolls[-1] = '__' + formatted_rolls[-1] + '__'
|
||||
if self.kept:
|
||||
return ' -> '.join(formatted_rolls)
|
||||
if node.comment == None:
|
||||
resultText = "Result"
|
||||
else:
|
||||
return '~~' + ' -> '.join(formatted_rolls) + '~~'
|
||||
resultText = node.comment.capitalize()
|
||||
|
||||
def __repr__(self):
|
||||
return "<SingleDice object: value={0.value}, max_value={0.max_value}, kept={0.kept}, rolls={0.rolls}>".format(
|
||||
self)
|
||||
return f"**{resultText}**: {self._stringify(node.roll)}\n**Total**: {int(node.total)}"
|
||||
|
||||
def to_dict(self):
|
||||
return {'type': 'single_dice', 'value': self.value, 'size': self.max_value, 'is_kept': self.kept,
|
||||
'rolls': self.rolls, 'exploded': self.exploded}
|
||||
def roll_dice(user, rollString):
|
||||
while len(rollString) > 1 and rollString[0] == " ":
|
||||
rollString = rollString[1:]
|
||||
return user+" :game_die:\n"+str(d20.roll(rollString, allow_comments=True,stringifier=MyStringifier()))
|
||||
|
||||
|
||||
class Constant(Part):
|
||||
def __init__(self, value: int = 0, annotation: str = ""):
|
||||
self.value = value
|
||||
self.annotation = annotation if annotation != None else ''
|
||||
|
||||
def __str__(self):
|
||||
return "{0.value} {0.annotation}".format(self)
|
||||
|
||||
def get_eval(self):
|
||||
return str(self.value)
|
||||
|
||||
def to_dict(self):
|
||||
return {'type': 'constant', 'value': self.value, 'annotation': self.annotation}
|
||||
|
||||
|
||||
class Operator(Part):
|
||||
def __init__(self, op: str = "+", annotation: str = ""):
|
||||
self.op = op if op != None else ''
|
||||
self.annotation = annotation if annotation != None else ''
|
||||
|
||||
def __str__(self):
|
||||
return "{0.op} {0.annotation}".format(self)
|
||||
|
||||
def get_eval(self):
|
||||
return self.op
|
||||
|
||||
def to_dict(self):
|
||||
return {'type': 'operator', 'value': self.op, 'annotation': self.annotation}
|
||||
|
||||
|
||||
class Comment(Part):
|
||||
def __init__(self, comment: str = ""):
|
||||
self.comment = comment
|
||||
|
||||
def __str__(self):
|
||||
return self.comment.strip()
|
||||
|
||||
def to_dict(self):
|
||||
return {'type': 'comment', 'value': self.comment}
|
||||
|
||||
|
||||
def parse_selectors(opts, res, greedy=False, inverse=False):
|
||||
"""Returns a list of ints."""
|
||||
for o in range(len(opts)):
|
||||
if opts[o][0] =='h':
|
||||
opts[o] = nlargest(int(opts[o].split('h')[1]), (d.value for d in res.rolled if d.kept))
|
||||
elif opts[o][0] =='l':
|
||||
opts[o] = nsmallest(int(opts[o].split('l')[1]), (d.value for d in res.rolled if d.kept))
|
||||
elif opts[o][0] =='>':
|
||||
if greedy:
|
||||
opts[o] = list(range(int(opts[o].split('>')[1]) + 1, res.max_value + 1))
|
||||
else:
|
||||
opts[o] = [d.value for d in res.rolled if d.value > int(opts[o].split('>')[1])]
|
||||
elif opts[o][0] =='<':
|
||||
if greedy:
|
||||
opts[o] = list(range(1, int(opts[o].split('<')[1])))
|
||||
else:
|
||||
opts[o] = [d.value for d in res.rolled if d.value < int(opts[o].split('<')[1])]
|
||||
out = []
|
||||
for o in opts:
|
||||
if isinstance(o, list):
|
||||
out.extend(int(l) for l in o)
|
||||
elif not greedy:
|
||||
out.extend(int(o) for a in res.rolled if a.value ==int(o) and a.kept)
|
||||
else:
|
||||
out.append(int(o))
|
||||
|
||||
if not inverse:
|
||||
return out
|
||||
|
||||
inverse_out = []
|
||||
for rolled in res.rolled:
|
||||
if rolled.kept and rolled.value in out:
|
||||
out.remove(rolled.value)
|
||||
elif rolled.kept:
|
||||
inverse_out.append(rolled.value)
|
||||
return inverse_out
|
||||
|
||||
|
||||
class DiceResult:
|
||||
"""Class to hold the output of a dice roll."""
|
||||
|
||||
def __init__(self, result: int = 0, verbose_result: str = '', crit: int = 0, rolled: str = '', skeleton: str = '',
|
||||
raw_dice: Roll = None):
|
||||
self.plain = result
|
||||
self.total = result
|
||||
self.result = verbose_result
|
||||
self.crit = crit
|
||||
self.rolled = rolled
|
||||
self.skeleton = skeleton if skeleton != '' else verbose_result
|
||||
self.raw_dice = raw_dice # Roll
|
||||
|
||||
def __str__(self):
|
||||
return self.result
|
||||
|
||||
def __repr__(self):
|
||||
return '<DiceResult object: total={}>'.format(self.total)
|
||||
|
||||
def consolidated(self):
|
||||
"""Gets the most simplified version of the roll string."""
|
||||
if self.raw_dice ==None:
|
||||
return "0"
|
||||
parts = [] # list of (part, annotation)
|
||||
last_part = ""
|
||||
for p in self.raw_dice.parts:
|
||||
if isinstance(p, SingleDiceGroup):
|
||||
last_part += str(p.get_total())
|
||||
else:
|
||||
last_part += str(p)
|
||||
if not isinstance(p, Comment) and p.annotation:
|
||||
parts.append((last_part, p.annotation))
|
||||
last_part = ""
|
||||
if last_part:
|
||||
parts.append((last_part, ""))
|
||||
|
||||
to_roll = ""
|
||||
last_annotation = ""
|
||||
out = ""
|
||||
for numbers, annotation in parts:
|
||||
if annotation and annotation != last_annotation and to_roll:
|
||||
out += f"{roll(to_roll).total:+} {last_annotation}"
|
||||
to_roll = ""
|
||||
if annotation:
|
||||
last_annotation = annotation
|
||||
to_roll += numbers
|
||||
if to_roll:
|
||||
out += f"{roll(to_roll).total:+} {last_annotation}"
|
||||
out = out.strip('+ ')
|
||||
return out
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
while True:
|
||||
print(roll(input().strip()))
|
||||
|
@ -1,162 +0,0 @@
|
||||
class AvraeException(Exception):
|
||||
"""A base exception class."""
|
||||
|
||||
def __init__(self, msg):
|
||||
super().__init__(msg)
|
||||
|
||||
|
||||
class NoCharacter(AvraeException):
|
||||
"""Raised when a user has no active character."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("You have no character active.")
|
||||
|
||||
|
||||
class NoActiveBrew(AvraeException):
|
||||
"""Raised when a user has no active homebrew of a certain type."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("You have no homebrew of this type active.")
|
||||
|
||||
|
||||
class ExternalImportError(AvraeException):
|
||||
"""Raised when something fails to import."""
|
||||
|
||||
def __init__(self, msg):
|
||||
super().__init__(msg)
|
||||
|
||||
|
||||
class InvalidArgument(AvraeException):
|
||||
"""Raised when an argument is invalid."""
|
||||
pass
|
||||
|
||||
|
||||
class EvaluationError(AvraeException):
|
||||
"""Raised when a cvar evaluation causes an error."""
|
||||
|
||||
def __init__(self, original):
|
||||
super().__init__(f"Error evaluating expression: {original}")
|
||||
self.original = original
|
||||
|
||||
|
||||
class FunctionRequiresCharacter(AvraeException):
|
||||
"""
|
||||
Raised when a function that requires a character is called without one.
|
||||
"""
|
||||
|
||||
def __init__(self, msg=None):
|
||||
super().__init__(msg or "This alias requires an active character.")
|
||||
|
||||
|
||||
class OutdatedSheet(AvraeException):
|
||||
"""Raised when a feature is used that requires an updated sheet."""
|
||||
|
||||
def __init__(self, msg=None):
|
||||
super().__init__(msg or "This command requires an updated character sheet. Try running `!update`.")
|
||||
|
||||
|
||||
class NoSpellDC(AvraeException):
|
||||
def __init__(self):
|
||||
super().__init__("No spell save DC found.")
|
||||
|
||||
|
||||
class NoSpellAB(AvraeException):
|
||||
def __init__(self):
|
||||
super().__init__("No spell attack bonus found.")
|
||||
|
||||
|
||||
class InvalidSaveType(AvraeException):
|
||||
def __init__(self):
|
||||
super().__init__("Invalid save type.")
|
||||
|
||||
|
||||
class ConsumableException(AvraeException):
|
||||
"""A base exception for consumable exceptions to stem from."""
|
||||
pass
|
||||
|
||||
|
||||
class ConsumableNotFound(ConsumableException):
|
||||
"""Raised when a consumable is not found."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("The requested counter does not exist.")
|
||||
|
||||
|
||||
class CounterOutOfBounds(ConsumableException):
|
||||
"""Raised when a counter is set to a value out of bounds."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("The new value is out of bounds.")
|
||||
|
||||
|
||||
class NoReset(ConsumableException):
|
||||
"""Raised when a consumable without a reset is reset."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("The counter does not have a reset value.")
|
||||
|
||||
|
||||
class InvalidSpellLevel(ConsumableException):
|
||||
"""Raised when a spell level is invalid."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("The spell level is invalid.")
|
||||
|
||||
|
||||
class SelectionException(AvraeException):
|
||||
"""A base exception for message awaiting exceptions to stem from."""
|
||||
pass
|
||||
|
||||
|
||||
class NoSelectionElements(SelectionException):
|
||||
"""Raised when get_selection() is called with no choices."""
|
||||
|
||||
def __init__(self, msg=None):
|
||||
super().__init__(msg or "There are no choices to select from.")
|
||||
|
||||
|
||||
class SelectionCancelled(SelectionException):
|
||||
"""Raised when get_selection() is cancelled or times out."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("Selection timed out or was cancelled.")
|
||||
|
||||
|
||||
class CombatException(AvraeException):
|
||||
"""A base exception for combat-related exceptions to stem from."""
|
||||
pass
|
||||
|
||||
|
||||
class CombatNotFound(CombatException):
|
||||
"""Raised when a channel is not in combat."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("This channel is not in combat.")
|
||||
|
||||
|
||||
class RequiresContext(CombatException):
|
||||
"""Raised when a combat is committed without context."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("Combat not contextualized.")
|
||||
|
||||
|
||||
class ChannelInCombat(CombatException):
|
||||
"""Raised when a combat is started with an already active combat."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("Channel already in combat.")
|
||||
|
||||
|
||||
class CombatChannelNotFound(CombatException):
|
||||
"""Raised when a combat's channel is not in the channel list."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("Combat channel does not exist.")
|
||||
|
||||
|
||||
class NoCombatants(CombatException):
|
||||
"""Raised when a combat tries to advance turn with no combatants."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("There are no combatants.")
|
Reference in New Issue
Block a user