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
import enum
import os
import sys
from typing import List
import traceback
from time import sleep
from typing import List, Dict
import discord
from discord.ext import commands
@ -25,6 +27,9 @@ GUILD = "690934836696973404"
ORGA_ROLE = "Orga"
CAPTAIN_ROLE = "Capitaine"
TIRAGE_ORDER = 0
PASSAGE_ORDER = 1
class TfjmError(Exception):
def __init__(self, msg):
@ -35,22 +40,105 @@ class TfjmError(Exception):
class Team:
def __init__(self, name):
def __init__(self, ctx, name):
self.name = name
self.role = get(ctx.guild.roles, name=name)
self.tirage_order = None
self.passage_order = None
class Tirage:
def __init__(self, *teams):
def __init__(self, ctx, channel, teams):
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(
"!", help_command=commands.DefaultHelpCommand(no_category="Commandes")
)
draws = {}
tirages: Dict[int, Tirage] = {}
@bot.command(
@ -63,7 +151,7 @@ async def start_draw(ctx: Context, *teams):
guild: discord.Guild = ctx.guild
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.")
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 "
"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(
"Nous allons d'abord tirer au sort l'ordre de tirage des problèmes, "
"puis l'ordre de passage lors du tour."
)
sleep(0.5)
await ctx.send(
f"Les {captain.mention}s, vous pouvez désormais lancer un dé 100 "
"comme ceci `!dice 100`. "
"L'ordre des tirages suivants sera l'ordre croissant des lancers. "
)
tirages[channel] = Tirage(ctx, channel, teams)
@bot.event
async def on_ready():
@ -112,6 +204,14 @@ async def dice(ctx: Context, n: int):
dice = random.randint(1, n)
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(
name="choose",
@ -139,11 +239,12 @@ async def random_problem(ctx: Context):
@bot.event
async def on_command_error(ctx: Context, error, *args, **kwargs):
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:
msg = str(error)
print(repr(error), file=sys.stderr)
print(repr(error), dir(error), file=sys.stderr)
await ctx.send(msg)