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

finished

parent fd554471
from roles import Role
import asyncio
from asyncio import create_task
from asyncio import Event
liebespaar_id = 696323604605960213
class Amor(Role):
@classmethod
def get_team(cls): return 'Dorfbewohner'
@classmethod
def get_name(cls): return 'Amor'
@classmethod
def get_channel_id(cls): return 697047699006029884
def __init__(self, game):
Role.__init__(self, game)
self.amor_event = asyncio.Event()
def __init__(self, game, member):
Role.__init__(self, game, member)
self.amor_event = Event()
async def task(self):
if not self.amor_event.is_set():
self.channel.send('Wähle das Liebespaar, mit $love @p1 @p2')
await self.amor_event.wait()
l = list()
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):
if not self.amor_event.is_set():
if p1 in self.game.players and p2 in self.game.players:
if p1 == p2:
self.game.amor_channel.send('Da muss ich dich enttäuschen, das Liebespaar muss aus zwei verschiedenen Personen bestehen!')
self.game.amor_channel.send('Ein Liebespaar kann nicht aus zweimal der gleichen Person bestehen!')
self.game.couple = { p1, p2 }
await self.game.server.get_channel(liebespaar_id).set_permissions(p1, read_messages=True, send_messages=True)
await self.game.server.get_channel(liebespaar_id).set_permissions(p2, read_messages=True, send_messages=True)
l = list()
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
from pprint import pprint
from discord.ext import commands
client = commands.Bot(command_prefix='.')
client = commands.Bot(command_prefix='$')
client.load_extension('utility_commands')
client.load_extension('cog_werewolf')
......
from discord.ext import commands
import asyncio
import random
import roles
from discord import Permissions
from discord import Member
......@@ -14,14 +13,13 @@ from amor import Amor
from whore import Whore
from girl import Girl
from game import Game
from day import Day
welcome_id = 696079221684175005
lobby_id = 696130304884211733
guild_id = 696079221684175001
role_alive_id = 697048340889731134
role_dead_id = 697048466978897990
village_id = 696105930336632963
welcome_channel_id = 696079221684175005
lobby_channel_id = 696130304884211733
class Werwolf(commands.Cog):
def __init__(self, client):
......@@ -38,12 +36,10 @@ class Werwolf(commands.Cog):
@commands.Cog.listener()
async def on_ready(self):
self.server = self.client.guilds[0]
self.role_alive = self.server.get_role(role_alive_id)
self.role_dead = self.server.get_role(role_dead_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.welcome_channel = self.server.get_channel(welcome_channel_id)
self.lobby_channel = self.server.get_channel(lobby_channel_id)
self.init_event.set()
await self.welcome_channel.send('[status] ready')
@commands.command()
......@@ -56,36 +52,38 @@ class Werwolf(commands.Cog):
self.game_event.set()
members = self.server.get_channel(lobby_id).members
random.shuffle(members)
self.game = Game()
await self.game.play(members, self.server, self.role_alive, self.role_dead, self.village_channel)
members = self.server.get_channel(lobby_channel_id).members
self.game = Game(self.server, members)
await self.game.play(ctx)
self.game_event.clear()
@commands.command()
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()
async def confirm(self, ctx):
await self.game.confirm(ctx)
await self.game.day.confirm(ctx)
@commands.command()
async def vote(self, ctx, player:Member):
if ctx.channel.id == Werewolf.get_channel_id():
await self.game.role[ctx.message.author].vote(player)
elif ctx.channel == self.village_channel:
await self.game.vote(ctx, ctx.message.author, player)
await self.game.role[ctx.message.author].vote(ctx, player)
elif ctx.channel.id == Day.get_channel_id():
await self.game.day.vote(ctx, ctx.message.author, player)
@commands.command()
async def captain(self, ctx):
await self.village_channel.send(f'Captain: {self.game.captain}')
await self.game.day.print_captain(ctx)
@commands.command()
async def heal(self, ctx):
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()
async def poison(self, ctx, player:Member):
......@@ -95,12 +93,14 @@ class Werwolf(commands.Cog):
@commands.command()
async def see(self, ctx, player:Member):
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()
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)
if isinstance(self.game.role[ctx.message.author], Hunter):
await self.game.role[ctx.message.author].kill(ctx, player)
@commands.command()
async def love(self, ctx, p1:Member, p2:Member):
......@@ -114,8 +114,21 @@ class Werwolf(commands.Cog):
@commands.command()
async def tasks(self, ctx):
for task in self.game.tasks:
for task in self.game.night.task_list:
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):
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
from asyncio import create_task
import roles
from werewolf import Werewolf
import random
from day import Day
from night import Night
game_category_id = 696079221684175004
class Game():
async def play(self, members, server, role_alive, role_dead, village_channel):
game_category_id = 696079221684175004
self.accusations_event = Event()
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()
village_channel_id = 696105930336632963
self.couple = {}
role_alive_id = 697048340889731134
role_dead_id = 697048466978897990
class Game():
def __init__(self, server, members):
self.server = server
self.village_channel = village_channel
self.players = set(members)
self.role = dict(zip(members, roles.get_roles(self)))
self.role_by_name = { self.role[player].get_name() for player in self.players }
self.role = roles.distribute_roles(self, members)
self.player = { v: k for k, v in self.role.items() }
self.couple = {}
self.captain = None
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()
for player in self.players:
l.append(create_task(player.remove_roles(role_dead)))
l.append(create_task(player.add_roles(role_alive)))
l.append(create_task(player.remove_roles(self.role_dead)))
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)))
for channel in self.server.get_channel(game_category_id).text_channels:
l.append(create_task(channel.purge()))
for task in l:
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:
await self.night()
if await self.check_winconditions(): return
await self.day()
if await self.check_winconditions(): return
if await self.night.tasks(): break
if await self.day.tasks(): break
async def check_winconditions(self):
print({ self.role[p].get_team() for p in self.players})
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
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
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 False
......@@ -64,112 +68,29 @@ class Game():
l.append(create_task(channel.set_permissions(member, overwrite=None)))
channel = self.server.get_channel(channel_id)
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:
await t
async def day(self):
self.victims = dict()
await self.village_channel.send(f'Das Dorf erwacht ... ohne {[player.mention for player in self.victims.values()]}')
if not self.captain in self.players:
await self.village_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 : 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()
await self.confirm_event.wait()
if len(self.accused) > 1:
self.can_accuse = False
break
else:
await self.village_channel.send('Es müssen mindestens 2 Personen angeklagt werden!')
await self.village_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 : self.votes.values().count(player) for player in set(self.votes.values()) }
votes[self.captain] += 1
victim = max(votes, key=votes.get)
print(f'{victim.mention} wird hingerichtet!')
self.players.remove(victim)
async def accuse(self, ctx, player):
if ctx.channel == self.village_channel:
if self.can_accuse:
if len(self.accused) == 3:
await self.village_channel.send(f'Es können nicht mehr als 3 Leute aufgestellt werden!')
else:
self.accused.add(player)
await self.village_channel.send(f'Aufgestellt sind: {[member.mention for member in self.accused]}')
async def withdraw(self, ctx, player):
if ctx.chanel == self.village_channel:
if not self.proposed_event.is_set():
if player not in self.accused:
await self.village_channel.send(f'{player.mention} ist nicht angeklagt!')
else:
self.accused.remove(player)
await self.village_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':
self.captain_vote(ctx, voter, player)
elif self.vote_type == 'victim':
self.victim_vote(ctx, voter, player)
async def captain_vote(self, ctx, voter, player):
self.votes[voter] = player
if self.votes.keys() == self.players:
self.votes_event.set()
async def victim_vote(self, ctx, voter, player):
if player not in self.accused:
await self.village_channel.send(f'{player.mention} ist nicht angeklagt!')
else:
self.votes[voter] = player
if self.votes.keys() == self.players:
self.votes_event.set()
async def night(self):
self.tasks = list()
self.victims = dict()
await self.village_channel.send('Es wird dunkel im Düsterwald und das Dorf schläft ein')
for player in self.players:
self.tasks.append(create_task(self.role[player].task()))
for task in self.tasks:
await task
for v in self.victims.values():
self.players.remove(v)
async def kill(self, player):
self.players.remove(player)
if player in self.couple:
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 :(')
self.couple = {}
await self.kill(p)
await self.role[player].on_kill()
l = list()
l.append(create_task(player.add_roles(self.role_dead)))
l.append(create_task(player.remove_roles(self.role_alive)))
for channel in self.server.get_channel(game_category_id).channels:
l.append(create_task(channel.set_permissions(player, read_messages=True, send_messages=False)))
for t in l:
await t
def get_living(self):
return { p for p in self.players if isinstance(self.role[p], self) }
async def print_living(self, ctx):
await ctx.send(f'Es leben noch {[p.mention for p in self.players]}')
\ No newline at end of file
......@@ -12,17 +12,28 @@ class Hunter(Role):
@classmethod
def get_channel_id(cls): return 697409843551797351
def __init__(self, game):
Role.__init__(self, game)