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 logging
import random
from typing import Dict, Callable, List, Union from typing import Dict, Callable, List, Union
from functools import wraps from functools import wraps
from collections import defaultdict from collections import defaultdict
from enum import Enum
import discord import discord
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Policy(Enum):
LIBERAL = "L"
FASCIST = "F"
def game_started(func): def game_started(func):
""" """
Decorator for *methods* of Game that need the game to be started. 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: def get_votes_channel(self) -> discord.TextChannel:
return self.guild.get_channel(self.get_votes_channel_id()) 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 @game_started
def is_vote_running(self) -> bool: def is_vote_running(self) -> bool:
return self.config["vote"] is not None 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["players"] = [member.id for member in player_role.members]
self.config["player_info"] = {str(player): {} for player in self.config["players"]} self.config["player_info"] = {str(player): {} for player in self.config["players"]}
self.config["vote"] = None 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 = { permissions = {
self.guild.default_role: discord.PermissionOverwrite(send_messages = False), 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)) await self.get_announcements_channel().send("\n".join(announcement_content), allowed_mentions = discord.AllowedMentions(roles = True))
self.config["vote"] = None self.config["vote"] = None
self.save_function() 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 from .GamesFile import GamesFile

View File

@ -9,7 +9,7 @@ import discord.utils
from discord.ext import commands from discord.ext import commands
import utils import utils
from GameFiles import Game, GamesFile from GameFiles import Game, GamesFile, Policy
logger = logging.getLogger("SecretBot") logger = logging.getLogger("SecretBot")
@ -174,6 +174,32 @@ class SecretBot(commands.Cog):
await game.stop_vote() await game.stop_vote()
await ctx.message.delete() 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__': if __name__ == '__main__':
argparser = argparse.ArgumentParser(description = "Secret Hitler helper bot", formatter_class = argparse.ArgumentDefaultsHelpFormatter) argparser = argparse.ArgumentParser(description = "Secret Hitler helper bot", formatter_class = argparse.ArgumentDefaultsHelpFormatter)