Commit 84b4bb3e authored by Ferdinand Schober's avatar Ferdinand Schober 💬
Browse files

finished

parent fd554471
from roles import Role from roles import Role
import asyncio from asyncio import create_task
from asyncio import Event
liebespaar_id = 696323604605960213 liebespaar_id = 696323604605960213
class Amor(Role): class Amor(Role):
@classmethod
def get_team(cls): return 'Dorfbewohner'
@classmethod @classmethod
def get_name(cls): return 'Amor' def get_name(cls): return 'Amor'
@classmethod @classmethod
def get_channel_id(cls): return 697047699006029884 def get_channel_id(cls): return 697047699006029884
def __init__(self, game): def __init__(self, game, member):
Role.__init__(self, game) Role.__init__(self, game, member)
self.amor_event = asyncio.Event() self.amor_event = Event()
async def task(self): async def task(self):
if not self.amor_event.is_set(): if not self.amor_event.is_set():
self.channel.send('Wähle das Liebespaar, mit $love @p1 @p2') l = list()
await self.amor_event.wait() l.append(create_task(self.game.channel.send('Amor erwacht, er verschießt seine Liebespfeile...')))
l.append(create_task(self.channel.send('Schreibe $love @name1 @name2 um deine Liebespfeile zu verschießen und das Liebespaar zu wählen!')))
l.append(create_task(self.amor_event.wait()))
for t in l: await t
l = list()
l.append(create_task(self.channel.send('Volltreffer!')))
l.append(create_task(self.game.channel.send('Die Liebenden werden dem channel "Liebespaar" hinzugefügt,\n'
'Sie verlieben sich sofort und schreiben sie sich romantische Nachrichten...')))
for t in l: await t
async def love(self, p1, p2): async def love(self, p1, p2):
if p1 == p2: if not self.amor_event.is_set():
self.game.amor_channel.send('Da muss ich dich enttäuschen, das Liebespaar muss aus zwei verschiedenen Personen bestehen!') if p1 in self.game.players and p2 in self.game.players:
self.game.couple = { p1, p2 } if p1 == p2:
await self.game.server.get_channel(liebespaar_id).set_permissions(p1, read_messages=True, send_messages=True) self.game.amor_channel.send('Ein Liebespaar kann nicht aus zweimal der gleichen Person bestehen!')
await self.game.server.get_channel(liebespaar_id).set_permissions(p2, read_messages=True, send_messages=True) self.game.couple = { p1, p2 }
self.amor_event.set() l = list()
\ No newline at end of file l.append(create_task(self.game.server.get_channel(liebespaar_id).set_permissions(p1, read_messages=True, send_messages=True)))
l.append(create_task(self.game.server.get_channel(liebespaar_id).set_permissions(p2, read_messages=True, send_messages=True)))
for t in l: await t
await self.game.server.get_channel(liebespaar_id).send(f'Ihr seid ja ein süßes Paar {[m.mention for m in self.game.couple]} <3')
self.amor_event.set()
else:
await self.channel.send('Mindestends einer der Spieler ist nicht am Leben!\n'
'Sende $alive um zu sehen, wer noch lebt.')
\ No newline at end of file
...@@ -2,7 +2,7 @@ import asyncio ...@@ -2,7 +2,7 @@ import asyncio
from pprint import pprint from pprint import pprint
from discord.ext import commands from discord.ext import commands
client = commands.Bot(command_prefix='.') client = commands.Bot(command_prefix='$')
client.load_extension('utility_commands') client.load_extension('utility_commands')
client.load_extension('cog_werewolf') client.load_extension('cog_werewolf')
......
from discord.ext import commands from discord.ext import commands
import asyncio import asyncio
import random
import roles import roles
from discord import Permissions from discord import Permissions
from discord import Member from discord import Member
...@@ -14,14 +13,13 @@ from amor import Amor ...@@ -14,14 +13,13 @@ from amor import Amor
from whore import Whore from whore import Whore
from girl import Girl from girl import Girl
from game import Game from game import Game
from day import Day
welcome_id = 696079221684175005
lobby_id = 696130304884211733
guild_id = 696079221684175001 guild_id = 696079221684175001
role_alive_id = 697048340889731134 welcome_channel_id = 696079221684175005
role_dead_id = 697048466978897990 lobby_channel_id = 696130304884211733
village_id = 696105930336632963
class Werwolf(commands.Cog): class Werwolf(commands.Cog):
def __init__(self, client): def __init__(self, client):
...@@ -38,12 +36,10 @@ class Werwolf(commands.Cog): ...@@ -38,12 +36,10 @@ class Werwolf(commands.Cog):
@commands.Cog.listener() @commands.Cog.listener()
async def on_ready(self): async def on_ready(self):
self.server = self.client.guilds[0] self.server = self.client.guilds[0]
self.role_alive = self.server.get_role(role_alive_id) self.welcome_channel = self.server.get_channel(welcome_channel_id)
self.role_dead = self.server.get_role(role_dead_id) self.lobby_channel = self.server.get_channel(lobby_channel_id)
self.welcome_channel = self.server.get_channel(welcome_id)
self.lobby_channel = self.server.get_channel(lobby_id)
self.village_channel = self.server.get_channel(village_id)
self.init_event.set() self.init_event.set()
await self.welcome_channel.send('[status] ready') await self.welcome_channel.send('[status] ready')
@commands.command() @commands.command()
...@@ -56,36 +52,38 @@ class Werwolf(commands.Cog): ...@@ -56,36 +52,38 @@ class Werwolf(commands.Cog):
self.game_event.set() self.game_event.set()
members = self.server.get_channel(lobby_id).members members = self.server.get_channel(lobby_channel_id).members
random.shuffle(members) self.game = Game(self.server, members)
self.game = Game() await self.game.play(ctx)
await self.game.play(members, self.server, self.role_alive, self.role_dead, self.village_channel)
self.game_event.clear() self.game_event.clear()
@commands.command() @commands.command()
async def accuse(self, ctx, player:Member): async def accuse(self, ctx, player:Member):
await self.game.accuse(ctx, player) await self.game.day.accuse(ctx, player)
@commands.command()
async def withdraw(self, ctx, player:Member):
await self.game.day.withdraw(ctx, player)
@commands.command() @commands.command()
async def confirm(self, ctx): async def confirm(self, ctx):
await self.game.confirm(ctx) await self.game.day.confirm(ctx)
@commands.command() @commands.command()
async def vote(self, ctx, player:Member): async def vote(self, ctx, player:Member):
if ctx.channel.id == Werewolf.get_channel_id(): if ctx.channel.id == Werewolf.get_channel_id():
await self.game.role[ctx.message.author].vote(player) await self.game.role[ctx.message.author].vote(ctx, player)
elif ctx.channel == self.village_channel: elif ctx.channel.id == Day.get_channel_id():
await self.game.vote(ctx, ctx.message.author, player) await self.game.day.vote(ctx, ctx.message.author, player)
@commands.command() @commands.command()
async def captain(self, ctx): async def captain(self, ctx):
await self.village_channel.send(f'Captain: {self.game.captain}') await self.game.day.print_captain(ctx)
@commands.command() @commands.command()
async def heal(self, ctx): async def heal(self, ctx):
if ctx.channel.id == Witch.get_channel_id(): if ctx.channel.id == Witch.get_channel_id():
self.game.role[ctx.message.author].heal() await self.game.role[ctx.message.author].heal()
@commands.command() @commands.command()
async def poison(self, ctx, player:Member): async def poison(self, ctx, player:Member):
...@@ -95,12 +93,14 @@ class Werwolf(commands.Cog): ...@@ -95,12 +93,14 @@ class Werwolf(commands.Cog):
@commands.command() @commands.command()
async def see(self, ctx, player:Member): async def see(self, ctx, player:Member):
if ctx.channel.id == Seer.get_channel_id(): if ctx.channel.id == Seer.get_channel_id():
self.game.role[ctx.message.author].see(player) await self.game.role[ctx.message.author].see(player)
@commands.command() @commands.command()
async def kill(self, ctx, player:Member): async def kill(self, ctx, player:Member):
if isinstance(self.game.role[ctx.message.author], Hunter):#TODO hunter only kill when dead! if ctx.channel.id == Witch.get_channel_id():
await self.game.role[ctx.message.author].kill(player) await self.game.role[ctx.message.author].kill(player)
if isinstance(self.game.role[ctx.message.author], Hunter):
await self.game.role[ctx.message.author].kill(ctx, player)
@commands.command() @commands.command()
async def love(self, ctx, p1:Member, p2:Member): async def love(self, ctx, p1:Member, p2:Member):
...@@ -114,8 +114,21 @@ class Werwolf(commands.Cog): ...@@ -114,8 +114,21 @@ class Werwolf(commands.Cog):
@commands.command() @commands.command()
async def tasks(self, ctx): async def tasks(self, ctx):
for task in self.game.tasks: for task in self.game.night.task_list:
await ctx.send(str(task)) await ctx.send(str(task))
@commands.command()
async def no(self, ctx):
if ctx.channel.id == Witch.get_channel_id():
await self.game.role[ctx.message.author].no()
@commands.command()
async def alive(self, ctx):
await self.game.print_living(ctx)
@commands.command()
async def votes(self, ctx):
await self.game.day.print_votes(ctx)
def setup(client): def setup(client):
client.add_cog(Werwolf(client)) client.add_cog(Werwolf(client))
\ No newline at end of file
from asyncio import Event
village_channel_id = 696105930336632963
class Day():
@classmethod
def get_channel_id(cls):
return village_channel_id
def __init__(self, game):
self.game = game
self.channel = game.server.get_channel(village_channel_id)
self.accusations_event = Event()
self.accusations_event.set()
self.confirm_event = Event()
self.confirm_event.set()
self.votes_event = Event()
self.votes_event.set()
self.captain = None
self.day = 1
async def tasks(self):
if await self.game.check_winconditions(): return True
await self.game.channel.send(f'Der {self.day}te Tag beginnt...\n')
await self.captain_voting()
await self.victim_voting()
async def captain_voting(self):
if not self.captain in self.game.players:
await self.channel.send('Ein neuer Hauptmann muss gewählt werden!\n'
'Dazu gibt jeder seine Stimme mit $vote @name ab!')
self.votes = dict()
self.vote_type = 'captain'
self.votes_event.clear()
await self.votes_event.wait()
votes = { player : list(self.votes.values()).count(player) for player in set(self.votes.values()) }
self.captain = max(votes, key=votes.get)
await self.channel.send(f'Der neue Hauptmann ist {self.captain.mention}')
async def victim_voting(self):
await self.channel.send('Und nun zur Anklage:\n'
'Anklagen können mit $accuse @name vorgeschlagen werden\n'
'Mit $withdraw @name können Angklagen zurück gezogen werden!\n'
'Nachdem mindestes zwei Leute angeklagt sind kann mit $confirm die Anklage bestätigt werden')
self.accused = set()
self.can_accuse = True
while True:
self.confirm_event.clear()
await self.confirm_event.wait()
if len(self.accused) > 1:
self.can_accuse = False
break
else:
await self.channel.send('Es müssen mindestens 2 Personen angeklagt werden!')
await self.channel.send('Jetzt muss jeder noch lebende Spieler mit $vote @name seine Stimme abgeben!')
self.vote_type = 'victim'
self.votes = dict()
self.votes_event.clear()
await self.votes_event.wait()
votes = { player : list(self.votes.values()).count(player) for player in set(self.votes.values()) }
await self.channel.send(f'Ergebnis: { { k.mention : v for k,v in votes.items() } }')
max_v = max(set(votes.values()))
self.accused = { k for k,v in votes.items() if v == max_v }
if len(self.accused) > 1:
await self.channel.send(f'Es gibt eine Stichwahl mit {[m.mention for m in self.accused]}')
self.votes = dict()
self.votes_event.clear()
await self.votes_event.wait()
votes = { player : list(self.votes.values()).count(player) for player in set(self.votes.values()) }
await self.channel.send(f'Ergebnis: { { k.mention : v for k,v in votes.items() } }')
max_v = max(set(votes.values()))
if len({ k for k,v in votes.items() if v == max_v }) > 1:
votes[self.votes[self.captain]] += 1
await self.channel.send(f'Die Stimme des Hauptmanns entschied die Wahl!')
victim = max(votes, key=votes.get)
await self.channel.send(f'{victim.mention} wird hingerichtet!')
await self.game.kill(victim)
async def accuse(self, ctx, player):
if ctx.channel == self.channel:
if self.can_accuse:
if player in self.game.players:
if player in self.accused:
await self.channel.send(f'{player.mention} ist bereits angeklagt!')
elif len(self.accused) == 3:
await self.channel.send(f'Es können nicht mehr als 3 Leute aufgestellt werden!')
else:
self.accused.add(player)
await self.channel.send(f'Aufgestellt sind: {[member.mention for member in self.accused]}')
else:
await self.channel.send(f'{player.mention} ist bereits tot!')
async def withdraw(self, ctx, player):
if ctx.channel == self.channel:
if self.can_accuse:
if player not in self.accused:
await self.channel.send(f'{player.mention} ist nicht angeklagt!')
else:
self.accused.remove(player)
await self.channel.send(f'Angeklagt sind: {[member.mention for member in self.accused]}')
async def confirm(self, ctx):
self.confirm_event.set()
async def vote(self, ctx, voter, player):
if not self.votes_event.is_set():
if self.vote_type == 'captain':
await self.captain_vote(ctx, voter, player)
elif self.vote_type == 'victim':
await self.victim_vote(ctx, voter, player)
async def captain_vote(self, ctx, voter, player):
self.votes[voter] = player
if self.votes.keys() == self.game.players:
self.votes_event.set()
async def victim_vote(self, ctx, voter, player):
if player not in self.accused:
await self.channel.send(f'{player.mention} ist nicht angeklagt!')
else:
self.votes[voter] = player
if set(self.votes.keys()) == self.game.players:
self.votes_event.set()
async def print_captain(self, ctx):
await ctx.send(f'Captain: {self.captain}')
async def print_votes(self, ctx):
await ctx.send(f'Stimmen: {[f"{k.mention}: {v.mention}" for k, v in self.game.day.votes.items()]}')
\ No newline at end of file
...@@ -2,59 +2,63 @@ from asyncio import Event ...@@ -2,59 +2,63 @@ from asyncio import Event
from asyncio import create_task from asyncio import create_task
import roles import roles
from werewolf import Werewolf from werewolf import Werewolf
import random
from day import Day
from night import Night
game_category_id = 696079221684175004 game_category_id = 696079221684175004
class Game():
async def play(self, members, server, role_alive, role_dead, village_channel):
self.accusations_event = Event() village_channel_id = 696105930336632963
self.accusations_event.set()
self.proposed_event = Event()
self.proposed_event.set()
self.confirm_event = Event()
self.confirm_event.set()
self.votes_event = Event()
self.votes_event.set()
self.couple = {} role_alive_id = 697048340889731134
role_dead_id = 697048466978897990
class Game():
def __init__(self, server, members):
self.server = server self.server = server
self.village_channel = village_channel
self.players = set(members) self.players = set(members)
self.role = dict(zip(members, roles.get_roles(self))) self.role = roles.distribute_roles(self, members)
self.role_by_name = { self.role[player].get_name() for player in self.players } self.player = { v: k for k, v in self.role.items() }
self.captain = None self.couple = {}
self.role_alive = self.server.get_role(role_alive_id)
self.role_dead = self.server.get_role(role_dead_id)
self.game_over = False self.channel = self.server.get_channel(village_channel_id)
self.day = Day(self)
self.night = Night(self)
async def play(self, ctx):
l = list() l = list()
for player in self.players: for player in self.players:
l.append(create_task(player.remove_roles(role_dead))) l.append(create_task(player.remove_roles(self.role_dead)))
l.append(create_task(player.add_roles(role_alive))) l.append(create_task(player.add_roles(self.role_alive)))
l.append(create_task(self.set_channel_for_member(self.role[player].get_channel_id(), player))) l.append(create_task(self.set_channel_for_member(self.role[player].get_channel_id(), player)))
for channel in self.server.get_channel(game_category_id).text_channels: for channel in self.server.get_channel(game_category_id).text_channels:
l.append(create_task(channel.purge())) l.append(create_task(channel.purge()))
for task in l: for task in l:
await task await task
await self.village_channel.send(f'Starte neues Spiel mit { [p.mention for p in self.players] }') await ctx.send(f'Starte neues Spiel mit { [p.mention for p in self.players] }')
await self.channel.send(f'Es spielen mit: {[role.get_name() for role in self.role.values()]}')
while True: while True:
await self.night() if await self.night.tasks(): break
if await self.check_winconditions(): return if await self.day.tasks(): break
await self.day()
if await self.check_winconditions(): return
async def check_winconditions(self): async def check_winconditions(self):
print({ self.role[p].get_team() for p in self.players})
if len(self.players) == 0: if len(self.players) == 0:
await self.village_channel.send('Somit ist das Spiel vorbei!\nNiemand hat gewonnen!') await self.channel.send('Somit ist das Spiel vorbei!\nNiemand hat gewonnen!')
return True return True
elif self.players == self.couple: elif self.players == self.couple:
await self.village_channel.send('Somit ist das Spiel vorbei!\nDas Liebespaar hat gewonnen!') await self.channel.send('Somit ist das Spiel vorbei!\nDas Liebespaar hat gewonnen!')
return True return True
elif len({ self.role[p].get_team() for p in self.players}) == 1: elif len({ self.role[p].get_team() for p in self.players}) == 1:
await self.village_channel.send(f'Somit ist das Spiel vorbei!\nDie {self.role[next(iter(self.players))].get_team()} haben gewonnen!') await self.channel.send(f'Somit ist das Spiel vorbei!\nDie {self.role[next(iter(self.players))].get_team()} haben gewonnen!')
return True return True
return False return False
...@@ -64,112 +68,29 @@ class Game(): ...@@ -64,112 +68,29 @@ class Game():
l.append(create_task(channel.set_permissions(member, overwrite=None))) l.append(create_task(channel.set_permissions(member, overwrite=None)))
channel = self.server.get_channel(channel_id) channel = self.server.get_channel(channel_id)
l.append(channel.set_permissions(member, read_messages=True, send_messages=True)) l.append(channel.set_permissions(member, read_messages=True, send_messages=True))
l.append(self.channel.set_permissions(member, send_messages=True))
for t in l: for t in l:
await t await t
async def kill(self, player):
async def day(self): self.players.remove(player)
self.victims = dict() if player in self.couple:
await self.village_channel.send(f'Das Dorf erwacht ... ohne {[player.mention for player in self.victims.values()]}') for p in self.couple:
if p in self.players:
await self.channel.send(f'Ohne {player.mention} hat für {p.mention} das Leben keinen Sinn mehr! {p.mention} begeht Selbstmord :(')
if not self.captain in self.players: self.couple = {}
await self.village_channel.send('Ein neuer Hauptmann muss gewählt werden!\n' await self.kill(p)
'Dazu gibt jeder seine Stimme mit $vote @name ab!') await self.role[player].on_kill()
l = list()
self.votes = dict() l.append(create_task(player.add_roles(self.role_dead)))
self.vote_type = 'captain' l.append(create_task(player.remove_roles(self.role_alive)))
for channel in self.server.get_channel(game_category_id).channels:
self.votes_event.clear() l.append(create_task(channel.set_permissions(player, read_messages=True, send_messages=False)))
await self.votes_event.wait() for t in l:
await t
votes = { player : self.votes.values().count(player) for player in set(self.votes.values()) }
self.captain = max(votes, key=votes.get)
await self.village_channel.send(f'Der neue Hauptmann ist {self.captain.mention}')
await self.village_channel.send('Und nun zur Anklage:\n'
'Anklagen können mit $accuse @name vorgeschlagen werden\n'
'Mit $withdraw @name können Angklagen zurück gezogen werden!\n'
'Nachdem mindestes zwei Leute angeklagt sind kann mit $confirm die Anklage bestätigt werden')
self.accused = set()
self.can_accuse = True
while True:
self.confirm_event.clear()