Draw and enact policies for legislative step

This commit is contained in:
Elnath 2021-06-11 00:45:13 +02:00
parent fa28e10f27
commit 4e825e10ce
3 changed files with 73 additions and 2 deletions

View File

@ -1,13 +1,20 @@
import logging
import random
from typing import Dict, Callable, List, Union
from functools import wraps
from collections import defaultdict
from enum import Enum
import discord
logger = logging.getLogger(__name__)
class Policy(Enum):
LIBERAL = "L"
FASCIST = "F"
def game_started(func):
"""
Decorator for *methods* of Game that need the game to be started.
@ -113,6 +120,14 @@ class Game:
def get_votes_channel(self) -> discord.TextChannel:
return self.guild.get_channel(self.get_votes_channel_id())
@game_started
def get_gm_channel_id(self) -> int:
return self.config["admin_chan"]
@game_started
def get_gm_channel(self) -> discord.TextChannel:
return self.guild.get_channel(self.get_gm_channel_id())
@game_started
def is_vote_running(self) -> bool:
return self.config["vote"] is not None
@ -143,6 +158,11 @@ class Game:
self.config["players"] = [member.id for member in player_role.members]
self.config["player_info"] = {str(player): {} for player in self.config["players"]}
self.config["vote"] = None
self.config["deck"] = [Policy.FASCIST.value] * 11 + [Policy.LIBERAL.value] * 6
random.shuffle(self.config["deck"])
self.config["discard"] = []
self.config["drawn"] = None
self.config["enacted"] = []
permissions = {
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
@ -266,3 +286,28 @@ class Game:
await self.get_announcements_channel().send("\n".join(announcement_content), allowed_mentions = discord.AllowedMentions(roles = True))
self.config["vote"] = None
self.save_function()
@game_started
async def draw_policies(self) -> List[Policy]:
self.config["drawn"] = [self.config["deck"].pop() for _ in range(3)]
self.save_function()
return [Policy(p) for p in self.config["drawn"]]
async def enact_drawn_policy(self, index: int):
if self.config["drawn"] is None:
raise RuntimeError("Can only enact a policy when they have been drawn")
if not (0 <= index < len(self.config["drawn"])):
raise IndexError(f"Expected policy index between 0 and {len(self.config['drawn'])}, got {index}")
for i, policy_str in enumerate(self.config["drawn"]):
if i == index:
self.config["enacted"].append(policy_str)
else:
self.config["discard"].append(policy_str)
self.config["drawn"] = None
if len(self.config["deck"]) < 3:
self.config["deck"].extend(self.config["discard"])
self.config["discard"] = []
random.shuffle(self.config["deck"])
self.save_function()
enacted = Policy(self.config["enacted"][-1])
await self.get_announcements_channel().send(f"{self.get_player_role().mention} A **{enacted.name}** policy has been enacted!")

View File

@ -1,2 +1,2 @@
from .Game import Game
from .Game import Game, Policy
from .GamesFile import GamesFile

View File

@ -9,7 +9,7 @@ import discord.utils
from discord.ext import commands
import utils
from GameFiles import Game, GamesFile
from GameFiles import Game, GamesFile, Policy
logger = logging.getLogger("SecretBot")
@ -174,6 +174,32 @@ class SecretBot(commands.Cog):
await game.stop_vote()
await ctx.message.delete()
@commands.command("Legislate")
async def draw_policies(self, ctx: commands.Context):
game = await self.get_running_game_or_error_message(ctx)
await self.check_is_administrator_or_gm(ctx)
if ctx.channel != game.get_gm_channel():
await ctx.reply(":warning: You should do this in your own channel!")
return
policies = await game.draw_policies()
message_content = [
"The following policies have been drawn:",
" ".join([f"{num + 1}) {':blue_square:' if policy == Policy.LIBERAL else ':red_square:'} " for num, policy in enumerate(policies)]),
"Send them to the president and chancellor and type `!Enact <number>` to enact one of them when you are finished"
]
await ctx.reply("\n".join(message_content))
@commands.command("Enact")
async def enact_drawn_policy(self, ctx: commands.Context, policy_number: int):
game = await self.get_running_game_or_error_message(ctx)
await self.check_is_administrator_or_gm(ctx)
if ctx.channel != game.get_gm_channel():
await ctx.reply(":warning: You should do this in your own channel!")
return
policy_number = policy_number - 1
await game.enact_drawn_policy(policy_number)
await ctx.reply(":white_check_mark: Done")
if __name__ == '__main__':
argparser = argparse.ArgumentParser(description = "Secret Hitler helper bot", formatter_class = argparse.ArgumentDefaultsHelpFormatter)