mirror of https://github.com/stijndcl/didier
258 lines
9.9 KiB
Python
258 lines
9.9 KiB
Python
|
from converters.numbers import Abbreviated, abbreviated
|
||
|
from decorators import help
|
||
|
import discord
|
||
|
from discord.ext import commands
|
||
|
from enums.help_categories import Category
|
||
|
from functions import checks, dinks
|
||
|
from functions.database import currency, stats
|
||
|
import json
|
||
|
import math
|
||
|
import random
|
||
|
|
||
|
|
||
|
class Games(commands.Cog):
|
||
|
def __init__(self, client):
|
||
|
self.client = client
|
||
|
|
||
|
# Don't allow any commands to work when locked
|
||
|
def cog_check(self, ctx):
|
||
|
return not self.client.locked
|
||
|
|
||
|
@commands.group(name="Coinflip", aliases=["Cf"], usage="[Inzet]* [Aantal]*", case_insensitive=True, invoke_without_command=True)
|
||
|
@commands.check(checks.allowedChannels)
|
||
|
@help.Category(category=Category.Gamble)
|
||
|
async def coinflip(self, ctx, *args):
|
||
|
"""
|
||
|
Command to flip a coin, optionally for Didier Dinks.
|
||
|
:param ctx: Discord Context
|
||
|
:param args: bet & wager
|
||
|
"""
|
||
|
args = list(args)
|
||
|
choices = ["Kop", "Munt"]
|
||
|
result = random.choice(choices)
|
||
|
|
||
|
# No choice made & no wager
|
||
|
if len(args) == 0:
|
||
|
await ctx.send("**{}**!".format(result))
|
||
|
self.updateStats("cf", "h" if result == "Kop" else "t")
|
||
|
return
|
||
|
|
||
|
# Check for invalid args
|
||
|
if len(args) == 1 or args[0][0].lower() not in "kmht":
|
||
|
return await ctx.send("Controleer je argumenten.")
|
||
|
|
||
|
args[1] = abbreviated(args[1])
|
||
|
valid = checks.isValidAmount(ctx, args[1])
|
||
|
|
||
|
# Invalid amount
|
||
|
if not valid[0]:
|
||
|
return await ctx.send(valid[1])
|
||
|
|
||
|
# Allow full words, abbreviations, and English alternatives
|
||
|
args[0] = "k" if args[0][0].lower() == "k" or args[0][0].lower() == "h" else "m"
|
||
|
won = await self.gamble(ctx, args[0], result, valid[1], 2)
|
||
|
|
||
|
if won:
|
||
|
s = stats.getOrAddUser(ctx.author.id)
|
||
|
stats.update(ctx.author.id, "cf_wins", int(s[8]) + 1)
|
||
|
stats.update(ctx.author.id, "cf_profit", float(s[9]) + float(valid[1]))
|
||
|
|
||
|
self.updateStats("cf", "h" if result == "Kop" else "t")
|
||
|
|
||
|
@coinflip.command(name="Stats", hidden=True)
|
||
|
async def cf_stats(self, ctx):
|
||
|
return await self.client.get_cog("Stats").callStats("cf", ctx)
|
||
|
|
||
|
@commands.group(name="Dice", aliases=["Roll"], usage="[Inzet]* [Aantal]*", case_insensitive=True, invoke_without_command=True)
|
||
|
@commands.check(checks.allowedChannels)
|
||
|
@help.Category(category=Category.Gamble)
|
||
|
async def dice(self, ctx, *args):
|
||
|
"""
|
||
|
Command to roll a dice, optionally for Didier Dinks.
|
||
|
:param ctx: Discord Context
|
||
|
:param args: bet & wager
|
||
|
"""
|
||
|
args = list(args)
|
||
|
result = random.randint(1, 6)
|
||
|
|
||
|
# No choice made & no wager
|
||
|
if len(args) == 0:
|
||
|
self.updateStats("dice", result)
|
||
|
return await ctx.send(":game_die: **{}**!".format(result))
|
||
|
|
||
|
# Check for invalid args
|
||
|
if len(args) == 1 or not args[0].isdigit() or not 0 < int(args[0]) < 7:
|
||
|
return await ctx.send("Controleer je argumenten.")
|
||
|
|
||
|
args[1] = abbreviated(args[1])
|
||
|
valid = checks.isValidAmount(ctx, args[1])
|
||
|
|
||
|
# Invalid amount
|
||
|
if not valid[0]:
|
||
|
return await ctx.send(valid[1])
|
||
|
|
||
|
await self.gamble(ctx, args[0], str(result), valid[1], 6, ":game_die: ")
|
||
|
self.updateStats("dice", result)
|
||
|
|
||
|
@dice.command(name="Stats", hidden=True)
|
||
|
async def dice_stats(self, ctx):
|
||
|
await self.client.get_cog("Stats").callStats("dice", ctx)
|
||
|
|
||
|
async def gamble(self, ctx, bet, result, wager, factor, pre="", post=""):
|
||
|
"""
|
||
|
Function for gambling because it's the same thing every time.
|
||
|
:param ctx: Discord Context
|
||
|
:param bet: the option the user bet on
|
||
|
:param result: randomly generated result
|
||
|
:param wager: size of the bet of the user
|
||
|
:param factor: the factor by which the person's wager is amplified
|
||
|
:param pre: any string that might have to be pre-pended to the output string
|
||
|
:param post: any string that might have to be appended to the output string
|
||
|
:return: a boolean indicating whether or not the user has won
|
||
|
"""
|
||
|
# Code no longer first removes your bet to then add profit,
|
||
|
# resulting in triple coinflip profit (@Clement).
|
||
|
# Subtract one off of the factor to compensate for the initial wager
|
||
|
factor -= 1
|
||
|
answer = "**{}**! ".format(result)
|
||
|
won = False
|
||
|
|
||
|
# Check if won
|
||
|
if result[0].lower() == bet[0].lower():
|
||
|
won = True
|
||
|
answer += "Je wint **{:,}** Didier Dink{}"
|
||
|
currency.update(ctx.author.id, "dinks", float(currency.dinks(ctx.author.id)) + (float(wager) * factor))
|
||
|
else:
|
||
|
answer += "Je hebt je inzet (**{:,}** Didier Dink{}) verloren"
|
||
|
currency.update(ctx.author.id, "dinks", float(currency.dinks(ctx.author.id)) - float(wager))
|
||
|
self.loseDinks(round(float(wager)))
|
||
|
|
||
|
# If won -> multiple dinkS, if lost, it's possible that the user only bet on 1 dinK
|
||
|
await ctx.send(pre + answer.format(round(float(wager) * factor if won else float(wager)),
|
||
|
checks.pluralS(float(wager) * factor if won else float(wager))) +
|
||
|
", **{}**!".format(ctx.author.display_name))
|
||
|
return won
|
||
|
|
||
|
@commands.group(name="Slots", usage="[Aantal]", case_insensitive=True, invoke_without_command=True)
|
||
|
@commands.check(checks.allowedChannels)
|
||
|
@help.Category(category=Category.Gamble)
|
||
|
async def slots(self, ctx, wager: Abbreviated = None):
|
||
|
"""
|
||
|
Command to play slot machines.
|
||
|
:param ctx: Discord Context
|
||
|
:param wager: the amount of Didier Dinks to bet with
|
||
|
"""
|
||
|
valid = checks.isValidAmount(ctx, wager)
|
||
|
# Invalid amount
|
||
|
if not valid[0]:
|
||
|
return await ctx.send(valid[1])
|
||
|
|
||
|
ratios = dinks.getRatios()
|
||
|
|
||
|
def randomKey():
|
||
|
return random.choice(list(ratios.keys()))
|
||
|
|
||
|
def generateResults():
|
||
|
return [randomKey(), randomKey(), randomKey()]
|
||
|
|
||
|
# Generate the result
|
||
|
result = generateResults()
|
||
|
|
||
|
textFormatted = "{}\n{}\n:yellow_square:{}:yellow_square:\n:arrow_right:{}:arrow_left::part_alternation_mark:\n" \
|
||
|
":yellow_square:{}:yellow_square: :red_circle:\n{}\n{}".format(
|
||
|
dinks.slotsHeader, dinks.slotsEmptyRow,
|
||
|
"".join(generateResults()), "".join(result), "".join(generateResults()),
|
||
|
dinks.slotsEmptyRow, dinks.slotsFooter)
|
||
|
|
||
|
await ctx.send(textFormatted)
|
||
|
|
||
|
# Everything different -> no profit
|
||
|
if len(set(result)) == 3:
|
||
|
await ctx.send("Je hebt je inzet (**{:,}** Didier Dinks) verloren, **{}**.".format(
|
||
|
math.floor(float(valid[1])), ctx.author.display_name
|
||
|
))
|
||
|
currency.update(ctx.author.id, "dinks", float(currency.dinks(ctx.author.id)) - math.floor(float(valid[1])))
|
||
|
return
|
||
|
|
||
|
# Calculate the profit multiplier
|
||
|
multiplier = 1.0
|
||
|
for symbol in set(result):
|
||
|
multiplier *= ratios[symbol][result.count(symbol) - 1]
|
||
|
|
||
|
await ctx.send(":moneybag: Je wint **{:,}** Didier Dinks, **{}**! :moneybag:".format(
|
||
|
round(float(valid[1]) * multiplier, 2), ctx.author.display_name
|
||
|
))
|
||
|
currency.update(ctx.author.id, "dinks",
|
||
|
float(currency.dinks(ctx.author.id)) + (float(valid[1]) * multiplier) - math.floor(
|
||
|
float(valid[1])))
|
||
|
# Current Dinks - wager + profit
|
||
|
|
||
|
# Returns list of profits
|
||
|
@slots.command(name="Chart", aliases=["Symbols", "Profit"])
|
||
|
async def chart(self, ctx):
|
||
|
"""
|
||
|
Command to show the profit distributions for the Didier Slotmachines.
|
||
|
:param ctx: Discord Context
|
||
|
"""
|
||
|
embed = discord.Embed(colour=discord.Colour.blue())
|
||
|
embed.set_author(name="Slots Profit Chart")
|
||
|
ratios = dinks.getRatios()
|
||
|
|
||
|
# Add every symbol into the embed
|
||
|
for ratio in ratios:
|
||
|
embed.add_field(name=ratio, value="1: x{}\n2: x{}\n3: x{}".format(
|
||
|
str(ratios[ratio][0]), str(ratios[ratio][1]), str(ratios[ratio][2])
|
||
|
))
|
||
|
|
||
|
await ctx.send(embed=embed)
|
||
|
|
||
|
@commands.group(name="Lost", case_insensitive=True, invoke_without_command=True)
|
||
|
@commands.check(checks.allowedChannels)
|
||
|
@help.Category(category=Category.Gamble)
|
||
|
async def lost(self, ctx):
|
||
|
"""
|
||
|
Command that shows the amount of Didier Dinks that have been lost due to gambling.
|
||
|
:param ctx: Discord Context
|
||
|
"""
|
||
|
await ctx.send("Er zijn al **{:,}** Didier Dinks verloren sinds 13/03/2020."
|
||
|
.format(dinks.lost()))
|
||
|
|
||
|
@lost.command(name="Today")
|
||
|
async def today(self, ctx):
|
||
|
"""
|
||
|
Command that shows the amount of Didier Dinks lost today.
|
||
|
:param ctx: Discord Context
|
||
|
"""
|
||
|
await ctx.send("Er zijn vandaag al **{:,}** Didier Dinks verloren."
|
||
|
.format(dinks.lostToday()))
|
||
|
|
||
|
def updateStats(self, game, key):
|
||
|
"""
|
||
|
Function to update the stats file for a game.
|
||
|
:param game: the game to change the stats for
|
||
|
:param key: the key in the game's dict to update
|
||
|
"""
|
||
|
with open("files/stats.json", "r") as fp:
|
||
|
s = json.load(fp)
|
||
|
|
||
|
s[game][str(key)] += 1
|
||
|
|
||
|
with open("files/stats.json", "w") as fp:
|
||
|
json.dump(s, fp)
|
||
|
|
||
|
def loseDinks(self, amount):
|
||
|
"""
|
||
|
Function that adds Didier Dinks to the lost file.
|
||
|
:param amount: the amount of Didier Dinks lost
|
||
|
"""
|
||
|
with open("files/lost.json", "r") as fp:
|
||
|
fc = json.load(fp)
|
||
|
fc["lost"] = fc["lost"] + round(amount)
|
||
|
fc["today"] = fc["today"] + round(amount)
|
||
|
with open("files/lost.json", "w") as fp:
|
||
|
json.dump(fc, fp)
|
||
|
|
||
|
|
||
|
def setup(client):
|
||
|
client.add_cog(Games(client))
|