add first phase

This commit is contained in:
ddorn 2020-04-25 20:19:45 +02:00
parent 55e5de95c6
commit 96bde31bb4
1 changed files with 110 additions and 9 deletions

View File

@ -1,8 +1,10 @@
#!/bin/python #!/bin/python
import enum
import os import os
import sys import sys
from typing import List import traceback
from time import sleep
from typing import List, Dict
import discord import discord
from discord.ext import commands from discord.ext import commands
@ -25,6 +27,9 @@ GUILD = "690934836696973404"
ORGA_ROLE = "Orga" ORGA_ROLE = "Orga"
CAPTAIN_ROLE = "Capitaine" CAPTAIN_ROLE = "Capitaine"
TIRAGE_ORDER = 0
PASSAGE_ORDER = 1
class TfjmError(Exception): class TfjmError(Exception):
def __init__(self, msg): def __init__(self, msg):
@ -35,22 +40,105 @@ class TfjmError(Exception):
class Team: class Team:
def __init__(self, name): def __init__(self, ctx, name):
self.name = name self.name = name
self.role = get(ctx.guild.roles, name=name)
self.tirage_order = None
self.passage_order = None
class Tirage: class Tirage:
def __init__(self, *teams): def __init__(self, ctx, channel, teams):
assert len(teams) in (3, 4) assert len(teams) in (3, 4)
self.teams = {team: Team(team) for team in teams} self.channel = channel
self.teams = {team: Team(ctx, team) for team in teams}
self.phase = OrderPhase(self)
def team_for(self, author):
for team in self.teams:
if get(author.roles, name=team):
return self.teams[team]
# Should theoretically not happen
raise TfjmError(
"Tu n'es pas dans une des équipes qui font le tirage, "
"merci de ne pas intervenir."
)
async def dice(self, ctx, author, dice):
await self.phase.dice(ctx, author, dice)
await self.update_phase(ctx)
async def update_phase(self, ctx):
if self.phase.finished():
self.phase = await self.phase.next(ctx)
if self.phase is None:
await ctx.send("Le tirage est fini ! Bonne chance à tous pour la suite !")
del tirages[self.channel]
class Phase:
NEXT = None
def __init__(self, tirage):
self.tirage = tirage
async def fais_pas_chier(self, ctx):
await ctx.send(
"Merci d'envoyer seulement les commandes nécessaires et suffisantes."
)
def team_for(self, author):
return self.tirage.team_for(author)
@property
def teams(self):
return self.tirage.teams
async def dice(self, ctx: Context, author, dice):
await self.fais_pas_chier(ctx)
async def choose_problem(self, ctx: Context, author, problem):
await self.fais_pas_chier(ctx)
async def accept(self, ctx: Context, author, yes):
await self.fais_pas_chier(ctx)
def finished(self) -> bool:
return NotImplemented
async def next(self, ctx: Context) -> "Phase":
return self.NEXT(self.tirage)
class OrderPhase(Phase):
async def dice(self, ctx, author, dice):
team = self.team_for(author)
if team.tirage_order is None:
team.tirage_order = dice
print(f"Team {team.name} has rolled {dice}")
else:
await ctx.send(f"{author.mention}: merci de ne lancer qu'un dé.")
def finished(self) -> bool:
return all(team.tirage_order is not None for team in self.teams.values())
async def next(self, ctx) -> "Phase":
orders = [team.tirage_order for team in self.teams.values()]
# Check that order is unique
if len(set(orders)) == len(orders):
return self.NEXT
else:
await ctx.send("crotte.")
bot = commands.Bot( bot = commands.Bot(
"!", help_command=commands.DefaultHelpCommand(no_category="Commandes") "!", help_command=commands.DefaultHelpCommand(no_category="Commandes")
) )
draws = {} tirages: Dict[int, Tirage] = {}
@bot.command( @bot.command(
@ -63,7 +151,7 @@ async def start_draw(ctx: Context, *teams):
guild: discord.Guild = ctx.guild guild: discord.Guild = ctx.guild
channel = ctx.channel.id channel = ctx.channel.id
if channel in draws: if channel in tirages:
raise TfjmError("Il y a déjà un tirage en cours sur cette Channel.") raise TfjmError("Il y a déjà un tirage en cours sur cette Channel.")
if len(teams) not in (3, 4): if len(teams) not in (3, 4):
@ -83,16 +171,20 @@ async def start_draw(ctx: Context, *teams):
"Pour plus de détails sur le déroulement du tirgae au sort, le règlement " "Pour plus de détails sur le déroulement du tirgae au sort, le règlement "
"est accessible sur https://tfjm.org/reglement." "est accessible sur https://tfjm.org/reglement."
) )
sleep(0.5) # The bot is more human if it doesn't type at the speed of light
await ctx.send( await ctx.send(
"Nous allons d'abord tirer au sort l'ordre de tirage des problèmes, " "Nous allons d'abord tirer au sort l'ordre de tirage des problèmes, "
"puis l'ordre de passage lors du tour." "puis l'ordre de passage lors du tour."
) )
sleep(0.5)
await ctx.send( await ctx.send(
f"Les {captain.mention}s, vous pouvez désormais lancer un dé 100 " f"Les {captain.mention}s, vous pouvez désormais lancer un dé 100 "
"comme ceci `!dice 100`. " "comme ceci `!dice 100`. "
"L'ordre des tirages suivants sera l'ordre croissant des lancers. " "L'ordre des tirages suivants sera l'ordre croissant des lancers. "
) )
tirages[channel] = Tirage(ctx, channel, teams)
@bot.event @bot.event
async def on_ready(): async def on_ready():
@ -112,6 +204,14 @@ async def dice(ctx: Context, n: int):
dice = random.randint(1, n) dice = random.randint(1, n)
await ctx.send(f"Le dé à {n} faces s'est arrêté sur... **{dice}**") await ctx.send(f"Le dé à {n} faces s'est arrêté sur... **{dice}**")
# Here we seed the result to Tirage if needed
channel = ctx.channel.id
if n == 100 and channel in tirages:
# If it is a captain
author: discord.Member = ctx.author
if get(author.roles, name=CAPTAIN_ROLE) is not None:
await tirages[channel].dice(ctx, author, dice)
@bot.command( @bot.command(
name="choose", name="choose",
@ -139,11 +239,12 @@ async def random_problem(ctx: Context):
@bot.event @bot.event
async def on_command_error(ctx: Context, error, *args, **kwargs): async def on_command_error(ctx: Context, error, *args, **kwargs):
if isinstance(error, commands.CommandInvokeError): if isinstance(error, commands.CommandInvokeError):
msg = str(error.original) msg = str(error.original) or str(error)
traceback.print_tb(error.original.__traceback__, file=sys.stderr)
else: else:
msg = str(error) msg = str(error)
print(repr(error), file=sys.stderr) print(repr(error), dir(error), file=sys.stderr)
await ctx.send(msg) await ctx.send(msg)