1
Fork 0
mirror of https://github.com/RYGhub/royal-mifia.git synced 2024-11-22 13:54:19 +00:00
royal-mifia/main.py

764 lines
31 KiB
Python
Raw Normal View History

2016-05-26 09:52:01 +00:00
#!/usr/bin/env python3.5
2016-04-25 16:13:16 +00:00
# -*- coding: utf-8 -*-
2016-05-29 15:12:23 +00:00
import pickle
2016-04-25 16:21:38 +00:00
from telegram.ext import Updater, CommandHandler
from telegram import ParseMode
import filemanager
import random
2016-05-25 11:57:15 +00:00
import strings as s
2016-04-21 20:14:35 +00:00
import logging
logger = logging.getLogger()
2016-05-22 15:13:26 +00:00
logger.setLevel(logging.WARN)
logging.basicConfig(level=logging.WARN,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
2016-04-21 20:14:35 +00:00
token = filemanager.readfile('telegramapi.txt')
updater = Updater(token)
freenames = s.names_list.copy()
2016-05-27 22:13:34 +00:00
2016-04-21 17:52:01 +00:00
# Ruoli possibili per i giocatori
# Base di un ruolo
class Role:
"""Classe base di un ruolo. Da qui si sviluppano tutti gli altri ruoli."""
2016-05-22 15:13:26 +00:00
def __init__(self):
2016-05-25 09:52:53 +00:00
self.icon = "-" # Icona del ruolo, da visualizzare di fianco al nome
2016-05-22 15:13:26 +00:00
self.team = 'None' # Squadra: 'None', 'Good', 'Evil'
2016-05-27 11:42:25 +00:00
self.name = "UNDEFINED" # Nome del ruolo, viene visualizzato dall'investigatore e durante l'assegnazione
self.powerdesc = None # Ha un potere? Se sì, inviagli le info su come usarlo.
2016-05-27 09:46:54 +00:00
def __repr__(self) -> str:
2016-05-27 11:42:25 +00:00
r = "<undefined Role>"
2016-05-26 09:08:50 +00:00
return r
2016-04-21 17:52:01 +00:00
2016-05-26 09:30:31 +00:00
def power(self, bot, game, player, arg):
2016-05-25 09:52:53 +00:00
"""Il potere del ruolo. Si attiva quando il bot riceve un /power in chat privata."""
2016-04-21 17:52:01 +00:00
pass
2016-05-26 09:30:31 +00:00
def onendday(self, bot, game):
2016-05-25 09:52:53 +00:00
"""Metodo chiamato alla fine di ogni giorno, per attivare o ripristinare allo stato iniziale il potere."""
2016-04-21 17:52:01 +00:00
pass
class Royal(Role):
2016-05-25 09:52:53 +00:00
"""Un membro della Royal Games. Il ruolo principale, non ha alcun potere se non quello di votare."""
2016-05-22 15:13:26 +00:00
def __init__(self):
super().__init__()
2016-05-25 11:57:15 +00:00
self.icon = s.royal_icon
2016-05-22 15:13:26 +00:00
self.team = 'Good'
2016-05-25 11:57:15 +00:00
self.name = s.royal_name
2016-04-21 17:52:01 +00:00
2016-05-27 09:46:54 +00:00
def __repr__(self) -> str:
2016-05-27 11:42:25 +00:00
r = "<Role: Royal>"
2016-05-26 09:08:50 +00:00
return r
2016-04-21 17:52:01 +00:00
class Mifioso(Role):
2016-05-25 11:57:15 +00:00
"""Il nemico globale. Può impostare come bersaglio una persona al giorno, per poi ucciderla alla fine."""
2016-05-22 15:13:26 +00:00
def __init__(self):
super().__init__()
2016-05-25 11:57:15 +00:00
self.icon = s.mifia_icon
2016-05-22 15:13:26 +00:00
self.team = 'Evil'
self.target = None
2016-05-25 11:57:15 +00:00
self.name = s.mifia_name
self.powerdesc = s.mifia_power_description
2016-05-27 09:46:54 +00:00
def __repr__(self) -> str:
2016-05-26 09:08:50 +00:00
if self.target is None:
2016-05-27 11:42:25 +00:00
r = "<Role: Mifioso>"
2016-05-26 09:08:50 +00:00
else:
2016-05-27 11:42:25 +00:00
r = "<Role: Mifioso, targeting {target}>".format(target=self.target.tusername)
2016-05-26 09:08:50 +00:00
return r
2016-04-21 17:52:01 +00:00
2016-05-26 09:30:31 +00:00
def power(self, bot, game, player, arg):
2016-05-25 09:52:53 +00:00
# Imposta una persona come bersaglio da uccidere.
selected = game.findplayerbyusername(arg)
2016-05-27 08:39:12 +00:00
if selected is not None:
self.target = selected
2016-05-25 11:57:15 +00:00
player.message(bot, s.mifia_target_selected.format(target=self.target.tusername))
else:
player.message(bot, s.error_username)
2016-04-21 17:52:01 +00:00
2016-05-26 09:30:31 +00:00
def onendday(self, bot, game):
2016-05-26 13:12:49 +00:00
if not game.votingmifia:
# Uccidi il bersaglio se non è protetto da un Angelo.
if self.target is not None:
if self.target.protectedby is None:
self.target.kill()
2016-05-27 11:42:25 +00:00
game.message(bot, s.mifia_target_killed.format(target=self.target.tusername,
icon=self.target.role.icon,
role=self.target.role.name))
2016-05-26 13:12:49 +00:00
else:
2016-05-27 11:42:25 +00:00
game.message(bot, s.mifia_target_protected.format(target=self.target.tusername,
icon=self.target.protectedby.role.icon,
protectedby=self.target.protectedby.tusername))
2016-05-26 13:12:49 +00:00
self.target = None
else:
2016-05-03 11:29:29 +00:00
self.target = None
2016-04-21 17:52:01 +00:00
class Investigatore(Role):
2016-05-25 09:52:53 +00:00
"""L'investigatore può indagare sul vero ruolo di una persona una volta al giorno."""
2016-05-22 15:13:26 +00:00
def __init__(self):
super().__init__()
2016-05-25 11:57:15 +00:00
self.icon = s.detective_icon
2016-05-22 15:13:26 +00:00
self.team = 'Good'
self.poweruses = 1
2016-05-25 11:57:15 +00:00
self.name = s.detective_name
2016-05-27 14:22:28 +00:00
self.powerdesc = s.detective_power_description
2016-05-27 09:46:54 +00:00
def __repr__(self) -> str:
2016-05-27 11:42:25 +00:00
r = "<Role: Investigatore, {uses} uses left>".format(uses=self.poweruses)
2016-05-26 09:08:50 +00:00
return r
2016-04-21 17:52:01 +00:00
2016-05-26 09:30:31 +00:00
def power(self, bot, game, player, arg):
2016-05-25 09:52:53 +00:00
# Indaga sul vero ruolo di una persona, se sono ancora disponibili usi del potere.
2016-04-23 15:12:52 +00:00
if self.poweruses > 0:
target = game.findplayerbyusername(arg)
if target is not None:
self.poweruses -= 1
2016-05-27 11:42:25 +00:00
player.message(bot, s.detective_discovery.format(target=target.tusername,
icon=target.role.icon,
role=target.role.name,
left=self.poweruses))
2016-04-23 15:12:52 +00:00
else:
2016-05-25 11:57:15 +00:00
player.message(bot, s.error_username)
2016-04-23 15:12:52 +00:00
else:
2016-05-25 11:57:15 +00:00
player.message(bot, s.error_no_uses)
2016-04-21 21:04:53 +00:00
2016-05-26 09:30:31 +00:00
def onendday(self, bot, game):
2016-04-21 21:04:53 +00:00
# Ripristina il potere
self.poweruses = 1
2016-05-03 11:29:29 +00:00
class Angelo(Role):
2016-05-27 11:42:25 +00:00
"""L'angelo può proteggere una persona al giorno dalla Mifia.
Se ha successo nella protezione, il suo ruolo sarà rivelato a tutti."""
2016-05-22 15:13:26 +00:00
def __init__(self):
super().__init__()
2016-05-25 11:57:15 +00:00
self.icon = s.angel_icon
2016-05-22 15:13:26 +00:00
self.team = 'Good' # Squadra: 'None', 'Good', 'Evil'
2016-05-25 11:57:15 +00:00
self.name = s.angel_name
2016-05-25 09:52:53 +00:00
self.protecting = None # La persona che questo angelo sta proteggendo
self.powerdesc = s.angel_power_description
2016-05-27 09:46:54 +00:00
def __repr__(self) -> str:
2016-05-27 22:13:34 +00:00
if self.protecting is None:
2016-05-27 11:42:25 +00:00
r = "<Role: Angelo>"
2016-05-26 09:08:50 +00:00
else:
2016-05-27 11:42:25 +00:00
r = "<Role: Angelo, protecting {target}>".format(target=self.protecting.tusername)
2016-05-26 09:08:50 +00:00
return r
2016-05-03 11:29:29 +00:00
2016-05-26 09:30:31 +00:00
def power(self, bot, game, player, arg):
2016-05-25 09:52:53 +00:00
# Imposta qualcuno come protetto
2016-05-03 11:29:29 +00:00
selected = game.findplayerbyusername(arg)
if selected is not None:
if selected is not Player:
# Togli la protezione a quello che stavi proteggendo prima
if self.protecting is not None:
self.protecting.protectedby = None
selected.protectedby = player
self.protecting = selected
player.message(bot, s.angel_target_selected.format(target=self.protecting.tusername))
else:
2016-05-27 22:13:34 +00:00
player.message(bot, s.error_angel_no_selfprotect)
else:
2016-05-27 22:13:34 +00:00
player.message(bot, s.error_username)
2016-05-03 11:29:29 +00:00
2016-05-26 09:30:31 +00:00
def onendday(self, bot, game):
2016-05-03 11:29:29 +00:00
# Resetta la protezione
if self.protecting is not None:
self.protecting.protectedby = None
2016-05-03 11:29:29 +00:00
self.protecting = None
2016-05-03 19:49:39 +00:00
2016-04-21 18:20:26 +00:00
class Player:
2016-05-27 11:42:25 +00:00
"""Classe di un giocatore. Contiene tutti i dati riguardanti un giocatore all'interno di una partita, come il ruolo,
e i dati riguardanti telegram, come ID e username."""
2016-05-26 09:30:31 +00:00
def __init__(self, tid, tusername):
2016-05-25 09:52:53 +00:00
self.tid = tid # ID di Telegram
self.tusername = tusername # Username di Telegram
2016-05-22 15:13:26 +00:00
self.role = Role() # Di base, ogni giocatore è un ruolo indefinito
self.alive = True
self.votingfor = None # Diventa un player se ha votato
2016-05-25 09:52:53 +00:00
self.votes = 0 # Voti che sta ricevendo questo giocatore. Aggiornato da updatevotes()
self.protectedby = None # Protettore. Oggetto player che protegge questo giocatore dalla mifia.
2016-05-26 13:12:49 +00:00
self.mifiavotes = 0 # Voti che sta ricevendo questo giocatore dalla mifia. Aggiornato da updatemifiavotes()
2016-04-21 18:20:26 +00:00
2016-05-27 09:46:54 +00:00
def __repr__(self) -> str:
2016-05-27 11:42:25 +00:00
r = "<Player {username}>".format(username=self.tusername)
2016-05-27 09:46:54 +00:00
return r
2016-05-26 09:30:31 +00:00
def message(self, bot, text):
"""Manda un messaggio privato al giocatore."""
bot.sendMessage(self.tid, text, parse_mode=ParseMode.MARKDOWN)
def kill(self):
"""Uccidi il giocatore."""
# Perchè questo esiste?
self.alive = False
2016-05-25 09:52:53 +00:00
2016-05-27 22:13:34 +00:00
2016-04-21 18:20:26 +00:00
class Game:
2016-05-27 11:42:25 +00:00
"""Classe di una partita, contenente parametri riguardanti stato della partita
e informazioni sul gruppo di Telegram."""
2016-05-26 09:30:31 +00:00
def __init__(self, groupid, adminid):
2016-05-25 09:52:53 +00:00
self.groupid = groupid # ID del gruppo in cui si sta svolgendo una partita
self.adminid = adminid # ID telegram dell'utente che ha creato la partita con /newgame
self.players = list() # Lista dei giocatori in partita
2016-05-22 15:13:26 +00:00
self.tokill = list() # Giocatori che verranno uccisi all'endday
self.phase = 'Join' # Fase di gioco: 'Join', 'Config', 'Voting'
self.configstep = 0 # Passo attuale di configurazione
self.totalmifiosi = 0 # Numero di mifiosi da inserire
self.totaldetectives = 0 # Numero di detective da inserire
self.totalangels = 0 # Numero di angeli da inserire
2016-05-26 13:12:49 +00:00
self.votingmifia = False # Seguire le regole originali della mifia che vota?
# Liste di ruoli in gioco, per velocizzare gli endday
self.mifiosiingame = list()
self.detectivesingame = list()
self.angelsingame = list()
# Trova un nome per la partita
if len(freenames) > 0:
2016-05-26 09:49:40 +00:00
random.shuffle(freenames)
2016-05-26 09:08:50 +00:00
self.name = freenames.pop()
else:
2016-05-26 09:08:50 +00:00
self.name = str(groupid)
def __del__(self):
2016-05-26 09:08:50 +00:00
# Rimetti il nome che si è liberato in disponibili.
try:
int(self.name)
2016-05-26 09:10:52 +00:00
except ValueError:
2016-05-26 09:08:50 +00:00
freenames.append(self.name)
2016-05-26 09:08:50 +00:00
def __repr__(self):
2016-05-27 11:42:25 +00:00
r = "<Game {name} in group {groupid} with {nplayers} players in phase {phase}>" \
.format(name=self.name, groupid=self.groupid, nplayers=len(self.players), phase=self.phase)
2016-05-26 09:08:50 +00:00
return r
2016-04-21 18:20:26 +00:00
2016-05-26 09:30:31 +00:00
def message(self, bot, text):
2016-05-25 09:52:53 +00:00
"""Manda un messaggio nel gruppo."""
bot.sendMessage(self.groupid, text, parse_mode=ParseMode.MARKDOWN)
2016-04-21 18:20:26 +00:00
2016-05-26 09:30:31 +00:00
def adminmessage(self, bot, text):
2016-05-25 09:52:53 +00:00
"""Manda un messaggio privato al creatore della partita."""
bot.sendMessage(self.adminid, text, parse_mode=ParseMode.MARKDOWN)
2016-04-21 18:20:26 +00:00
2016-05-26 09:30:31 +00:00
def mifiamessage(self, bot, text):
2016-05-25 09:52:53 +00:00
"""Manda un messaggio privato a tutti i Mifiosi nella partita."""
2016-04-21 18:20:26 +00:00
# Trova tutti i mifiosi nell'elenco dei giocatori
for player in self.players:
if isinstance(player.role, Mifioso):
player.message(bot, text)
2016-05-26 09:30:31 +00:00
def findplayerbyid(self, tid) -> Player:
2016-05-25 09:52:53 +00:00
"""Trova il giocatore con un certo id."""
for player in self.players:
if player.tid == tid:
return player
else:
return None
2016-05-26 09:30:31 +00:00
def findplayerbyusername(self, tusername) -> Player:
2016-05-25 09:52:53 +00:00
"""Trova il giocatore con un certo username."""
for player in self.players:
2016-04-23 15:07:09 +00:00
if player.tusername.lower() == tusername.lower():
return player
else:
return None
def assignroles(self, bot):
2016-05-25 09:52:53 +00:00
"""Assegna ruoli casuali a tutti i giocatori."""
2016-04-22 17:55:24 +00:00
random.seed()
playersleft = self.players.copy()
random.shuffle(playersleft)
2016-04-23 16:26:32 +00:00
# Seleziona mifiosi
while self.totalmifiosi > 0:
2016-05-26 09:08:50 +00:00
selected = playersleft.pop()
self.mifiosiingame.append(selected)
2016-05-26 09:08:50 +00:00
selected.role = Mifioso()
self.totalmifiosi -= 1
2016-04-23 16:26:32 +00:00
# Seleziona detective
while self.totaldetectives > 0:
2016-05-26 09:08:50 +00:00
selected = playersleft.pop()
self.detectivesingame.append(selected)
2016-05-26 09:08:50 +00:00
selected.role = Investigatore()
self.totaldetectives -= 1
2016-05-25 09:52:53 +00:00
# Seleziona angeli
while self.totalangels > 0:
2016-05-26 09:08:50 +00:00
selected = playersleft.pop()
self.angelsingame.append(selected)
2016-05-26 09:08:50 +00:00
selected.role = Angelo()
self.totalangels -= 1
2016-04-22 17:55:24 +00:00
# Assegna il ruolo di Royal a tutti gli altri
for player in playersleft:
player.role = Royal()
2016-04-23 16:26:32 +00:00
# Manda i ruoli assegnati a tutti
for player in self.players:
2016-05-25 11:57:15 +00:00
player.message(bot, s.role_assigned.format(icon=player.role.icon, name=player.role.name))
2016-05-26 09:40:59 +00:00
if player.role.powerdesc is not None:
player.message(bot, player.role.powerdesc.format(gamename=self.name))
2016-04-22 17:55:24 +00:00
2016-04-22 19:14:14 +00:00
def updatevotes(self):
2016-05-25 09:52:53 +00:00
"""Aggiorna il conteggio dei voti di tutti i giocatori."""
2016-04-22 19:14:14 +00:00
for player in self.players:
player.votes = 0
for player in self.players:
2016-05-25 14:27:11 +00:00
if player.votingfor is not None and player.alive:
2016-04-23 15:37:43 +00:00
player.votingfor.votes += 1
2016-04-22 19:14:14 +00:00
2016-05-27 08:51:52 +00:00
def updatemifiavotes(self):
2016-05-26 13:12:49 +00:00
"""Aggiorna il conteggio dei voti mifiosi di tutti i giocatori."""
for player in self.players:
player.mifiavotes = 0
for player in self.mifiosiingame:
if player.alive:
2016-05-26 13:12:49 +00:00
if player.role.target is not None:
player.role.target.mifiavotes += 1
2016-05-25 14:27:11 +00:00
def mostvotedplayer(self) -> list:
2016-05-25 09:52:53 +00:00
"""Trova il giocatore più votato."""
2016-05-25 14:27:11 +00:00
mostvoted = list()
currenttop = 0
2016-04-22 19:14:14 +00:00
self.updatevotes()
for player in self.players:
2016-05-25 14:27:11 +00:00
if player.votes > currenttop:
2016-05-27 09:51:57 +00:00
mostvoted = list()
mostvoted.append(player)
currenttop = player.votes
2016-05-25 14:27:11 +00:00
elif player.votes == currenttop:
mostvoted.append(player)
2016-05-26 13:12:49 +00:00
if currenttop > 0:
return mostvoted
else:
2016-05-27 08:51:52 +00:00
return list()
2016-05-26 13:12:49 +00:00
def mostvotedmifia(self) -> list:
"""Trova il giocatore più votato dalla mifia."""
mostvoted = list()
currenttop = 0
2016-05-27 08:51:52 +00:00
self.updatemifiavotes()
2016-05-26 13:12:49 +00:00
for player in self.players:
2016-05-27 09:51:57 +00:00
if player.mifiavotes > currenttop:
mostvoted = list()
mostvoted.append(player)
currenttop = player.mifiavotes
elif player.votes == currenttop:
2016-05-26 13:12:49 +00:00
mostvoted.append(player)
if currenttop > 0:
return mostvoted
else:
2016-05-27 08:51:52 +00:00
return list()
2016-05-26 13:12:49 +00:00
2016-04-22 19:14:14 +00:00
def endday(self, bot):
2016-05-25 14:27:11 +00:00
"""Finisci la giornata, uccidi il più votato del giorno ed esegui gli endday di tutti i giocatori."""
# Conta i voti ed elimina il più votato.
topvotes = self.mostvotedplayer()
if len(topvotes) > 0:
# In caso di pareggio, elimina un giocatore casuale.
random.seed()
random.shuffle(topvotes)
lynched = topvotes.pop()
2016-05-26 09:59:58 +00:00
if lynched.alive:
2016-05-27 11:42:25 +00:00
self.message(bot, s.player_lynched.format(name=lynched.tusername,
icon=lynched.role.icon,
role=lynched.role.name))
2016-05-26 09:59:58 +00:00
lynched.kill()
2016-05-25 14:27:11 +00:00
else:
self.message(bot, s.no_players_lynched)
# Fai gli endday in un certo ordine.
# Si potrebbe fare più velocemente, credo.
2016-05-25 14:27:11 +00:00
# Ma non sto ho voglia di ottimizzare ora.
# Mifiosi
2016-05-26 13:12:49 +00:00
if self.votingmifia:
# Trova il più votato dai mifiosi e uccidilo
2016-05-27 09:16:02 +00:00
killlist = self.mostvotedmifia()
2016-05-26 13:12:49 +00:00
if len(killlist) > 0:
# In caso di pareggio, elimina un giocatore casuale.
random.seed()
random.shuffle(killlist)
killed = killlist.pop()
if killed.alive:
2016-05-27 22:40:30 +00:00
if killed.protectedby is None:
killed.kill()
self.message(bot, s.mifia_target_killed.format(target=killed.tusername,
icon=killed.role.icon,
role=killed.role.name))
else:
self.message(bot, s.mifia_target_protected.format(target=killed.tusername,
icon=killed.protectedby.role.icon,
protectedby=killed.protectedby.tusername))
2016-05-27 09:16:02 +00:00
# Attiva il onendday dei mifiosi
for player in self.mifiosiingame:
2016-05-25 14:27:11 +00:00
if isinstance(player.role, Mifioso) and player.alive:
2016-05-22 15:13:26 +00:00
player.role.onendday(bot, self)
# Investigatori
for player in self.detectivesingame:
2016-05-25 14:27:11 +00:00
if isinstance(player.role, Investigatore) and player.alive:
2016-05-22 15:13:26 +00:00
player.role.onendday(bot, self)
2016-05-03 11:29:29 +00:00
# Angeli
for player in self.angelsingame:
2016-05-25 14:27:11 +00:00
if isinstance(player.role, Angelo) and player.alive:
2016-05-22 15:13:26 +00:00
player.role.onendday(bot, self)
# Cancella tutti i voti
2016-04-23 15:37:43 +00:00
for player in self.players:
player.votingfor = None
2016-04-23 16:26:32 +00:00
# Condizioni di vittoria
royal = 0
mifiosi = 0
for player in self.players:
if player.alive and player.role.team == 'Evil':
2016-04-23 16:26:32 +00:00
mifiosi += 1
2016-05-03 19:49:17 +00:00
elif player.alive and player.role.team == 'Good':
2016-04-23 16:26:32 +00:00
royal += 1
if mifiosi >= royal:
2016-05-25 11:57:15 +00:00
self.message(bot, s.victory_mifia)
2016-04-23 16:26:32 +00:00
self.endgame()
elif mifiosi == 0:
2016-05-25 11:57:15 +00:00
self.message(bot, s.victory_royal)
2016-04-23 16:26:32 +00:00
self.endgame()
2016-05-27 13:53:06 +00:00
def endconfig(self, bot):
2016-05-27 13:34:23 +00:00
"""Fine della fase di config, inizio assegnazione ruoli"""
2016-05-27 13:39:17 +00:00
self.phase = 'Voting'
2016-05-27 13:34:23 +00:00
try:
2016-05-27 13:39:17 +00:00
self.assignroles(bot)
2016-05-27 13:34:23 +00:00
except IndexError:
2016-05-27 13:39:17 +00:00
self.message(bot, s.error_not_enough_players)
self.endgame()
2016-05-27 13:34:23 +00:00
else:
2016-05-27 13:39:17 +00:00
self.message(bot, s.roles_assigned_successfully)
2016-05-27 13:34:23 +00:00
2016-04-23 16:26:32 +00:00
def endgame(self):
inprogress.remove(self)
2016-04-22 19:14:14 +00:00
2016-05-29 15:12:23 +00:00
def save(self):
# Crea il file.
file = open(str(self.groupid) + ".p", 'x')
file.close()
# Scrivi sul file.
file = open(str(self.groupid) + ".p", 'wb')
pickle.dump(self, file)
file.close()
2016-04-21 20:14:35 +00:00
# Partite in corso
inprogress = list()
2016-04-21 18:20:26 +00:00
2016-05-26 09:30:31 +00:00
def findgamebyid(gid) -> Game:
2016-05-25 09:52:53 +00:00
"""Trova una partita con un certo id."""
2016-04-21 21:04:53 +00:00
for game in inprogress:
if game.groupid == gid:
return game
2016-05-26 09:30:31 +00:00
def findgamebyname(name) -> Game:
2016-05-26 09:08:50 +00:00
"""Trova una partita con un certo nome."""
for game in inprogress:
if game.name.lower() == name.lower():
2016-05-26 10:10:07 +00:00
return game
2016-05-27 22:13:34 +00:00
2016-04-21 17:52:01 +00:00
# Comandi a cui risponde il bot
def ping(bot, update):
2016-05-25 09:52:53 +00:00
"""Ping!"""
bot.sendMessage(update.message.chat['id'], s.pong, parse_mode=ParseMode.MARKDOWN)
2016-04-21 20:14:35 +00:00
def newgame(bot, update):
2016-05-25 09:52:53 +00:00
"""Crea una nuova partita."""
2016-04-21 20:14:35 +00:00
if update.message.chat['type'] != 'private':
game = findgamebyid(update.message.chat['id'])
if game is None:
game = Game(update.message.chat['id'], update.message.from_user['id'])
inprogress.append(game)
game.message(bot, s.new_game.format(groupid=game.groupid, name=game.name))
else:
bot.sendMessage(update.message.chat['id'], s.error_game_in_progress, parse_mode=ParseMode.MARKDOWN)
2016-04-21 20:14:35 +00:00
else:
bot.sendMessage(update.message.chat['id'], s.error_chat_type, parse_mode=ParseMode.MARKDOWN)
2016-04-21 21:04:53 +00:00
def join(bot, update):
2016-05-25 09:52:53 +00:00
"""Unisciti a una partita."""
2016-04-21 21:04:53 +00:00
game = findgamebyid(update.message.chat['id'])
if game is not None:
if game.phase == 'Join':
2016-04-22 18:39:16 +00:00
p = game.findplayerbyid(update.message.from_user['id'])
if p is None:
p = Player(update.message.from_user['id'], update.message.from_user['username'])
game.players.append(p)
game.message(bot, s.player_joined.format(name=p.tusername))
2016-04-22 18:39:16 +00:00
else:
game.message(bot, s.error_player_already_joined)
else:
2016-05-26 09:08:50 +00:00
game.message(bot, s.error_join_phase_ended)
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
2016-04-23 15:37:43 +00:00
def debug(bot, update):
2016-05-25 09:52:53 +00:00
"""Visualizza tutti i ruoli e gli id."""
2016-04-23 15:37:43 +00:00
game = findgamebyid(update.message.chat['id'])
if game is not None:
2016-04-23 15:37:43 +00:00
if game.adminid == update.message.from_user['id']:
2016-05-25 11:57:15 +00:00
text = s.status_header.format(name=game.groupid, admin=game.adminid, phase=game.phase)
2016-04-23 15:37:43 +00:00
game.updatevotes()
# Aggiungi l'elenco dei giocatori
for player in game.players:
if not player.alive:
2016-05-25 11:57:15 +00:00
text += s.status_dead_player.format(name=player.tusername)
2016-04-23 15:37:43 +00:00
elif player.votingfor is not None:
2016-05-27 11:42:25 +00:00
text += s.status_voting_player.format(icon=player.role.icon,
name=player.tusername,
votes=str(player.votes),
voting=player.votingfor.tusername)
2016-04-23 15:37:43 +00:00
else:
2016-05-27 11:42:25 +00:00
text += s.status_idle_player.format(icon=player.role.icon,
name=player.tusername,
votes=str(player.votes))
game.adminmessage(bot, text)
game.message(bot, s.check_private)
else:
2016-05-26 09:08:50 +00:00
game.message(bot, s.error_not_admin)
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
2016-04-23 15:37:43 +00:00
def status(bot, update):
2016-05-25 09:52:53 +00:00
"""Visualizza lo stato della partita."""
game = findgamebyid(update.message.chat['id'])
if game is not None:
2016-05-26 10:12:14 +00:00
text = s.status_header.format(name=game.name, admin=game.adminid, phase=game.phase)
2016-04-23 15:37:43 +00:00
game.updatevotes()
# Aggiungi l'elenco dei giocatori
for player in game.players:
2016-04-23 15:07:09 +00:00
if not player.alive:
2016-05-26 09:52:01 +00:00
text += s.status_dead_player.format(name=player.tusername)
2016-04-23 15:07:09 +00:00
elif player.votingfor is not None:
2016-05-27 11:42:25 +00:00
text += s.status_voting_player.format(icon="\U0001F610",
name=player.tusername,
votes=str(player.votes),
voting=player.votingfor.tusername)
else:
text += s.status_idle_player.format(icon="\U0001F610", name=player.tusername, votes=str(player.votes))
game.message(bot, text)
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
def endjoin(bot, update):
2016-05-25 09:52:53 +00:00
"""Termina la fase di join e inizia quella di votazione."""
game = findgamebyid(update.message.chat['id'])
if game is not None and game.phase is 'Join':
2016-05-26 09:08:50 +00:00
if update.message.from_user['id'] == game.adminid:
# Inizio fase di configurazione
game.phase = 'Config'
2016-05-26 09:08:50 +00:00
game.message(bot, s.join_phase_ended)
game.message(bot, s.config_list[0])
2016-05-26 09:08:50 +00:00
else:
game.message(bot, s.error_not_admin)
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
2016-05-25 11:57:15 +00:00
2016-05-27 22:13:34 +00:00
def config(bot, update):
"""Configura il parametro richiesto."""
game = findgamebyid(update.message.chat['id'])
if game is not None and game.phase is 'Config':
if update.message.from_user['id'] == game.adminid:
cmd = update.message.text.split(' ', 1)
2016-05-27 09:46:54 +00:00
if len(cmd) >= 2:
if game.configstep == 0:
try:
game.totalmifiosi = int(cmd[1])
except ValueError:
game.message(bot, s.error_invalid_config)
else:
game.configstep += 1
game.message(bot, s.config_list[game.configstep])
elif game.configstep == 1:
try:
game.totaldetectives = int(cmd[1])
except ValueError:
game.message(bot, s.error_invalid_config)
else:
game.configstep += 1
game.message(bot, s.config_list[game.configstep])
elif game.configstep == 2:
try:
game.totalangels = int(cmd[1])
except ValueError:
game.message(bot, s.error_invalid_config)
2016-05-26 13:12:49 +00:00
else:
game.configstep += 1
game.message(bot, s.config_list[game.configstep])
elif game.configstep == 3:
2016-05-27 13:16:47 +00:00
if cmd[1].lower() == 'testa':
game.votingmifia = False
2016-05-27 13:53:06 +00:00
game.endconfig(bot)
2016-05-27 13:16:47 +00:00
elif cmd[1].lower() == 'unica':
game.votingmifia = True
2016-05-27 13:53:06 +00:00
game.endconfig(bot)
else:
2016-05-27 13:34:23 +00:00
game.message(bot, s.error_invalid_config)
else:
game.message(bot, s.config_list[game.configstep])
2016-05-26 11:50:16 +00:00
else:
game.message(bot, s.error_not_admin)
else:
game.message(bot, s.error_no_games_found)
def vote(bot, update):
2016-05-25 09:52:53 +00:00
"""Vota per uccidere una persona."""
game = findgamebyid(update.message.chat['id'])
if game is not None and game.phase is 'Voting':
player = game.findplayerbyid(update.message.from_user['id'])
2016-05-26 09:18:07 +00:00
if player is not None:
2016-05-26 09:08:50 +00:00
if player.alive:
target = game.findplayerbyusername(update.message.text.split(' ')[1])
if target is not None:
player.votingfor = target
game.message(bot, s.vote.format(voted=target.tusername))
else:
game.message(bot, s.error_username)
else:
game.message(bot, s.error_dead)
else:
game.message(bot, s.error_not_in_game)
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
2016-04-21 21:04:53 +00:00
2016-04-21 20:14:35 +00:00
2016-04-22 19:14:14 +00:00
def endday(bot, update):
2016-05-25 09:52:53 +00:00
"""Termina la giornata attuale."""
2016-04-22 19:14:14 +00:00
game = findgamebyid(update.message.chat['id'])
if game is not None and game.phase is 'Voting' and update.message.from_user['id'] == game.adminid:
game.endday(bot)
2016-04-23 15:07:09 +00:00
def power(bot, update):
2016-05-25 09:52:53 +00:00
"""Attiva il potere del tuo ruolo."""
2016-04-23 15:07:09 +00:00
if update.message.chat['type'] == 'private':
cmd = update.message.text.split(' ', 2)
game = findgamebyname(cmd[1])
# Se non lo trovi con il nome, prova con l'id
if game is None:
2016-05-26 09:08:50 +00:00
game = findgamebyid(int(cmd[1]))
2016-04-23 15:07:09 +00:00
if game is not None:
2016-05-26 10:12:14 +00:00
player = game.findplayerbyid(int(update.message.from_user['id']))
if player is not None:
2016-05-26 09:08:50 +00:00
if player.alive:
player.role.power(bot, game, player, cmd[2])
else:
player.message(bot, s.error_dead)
else:
bot.sendMessage(update.message.chat['id'], s.error_not_in_game, parse_mode=ParseMode.MARKDOWN)
2016-04-23 15:07:09 +00:00
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
2016-04-23 15:07:09 +00:00
else:
bot.sendMessage(update.message.chat['id'], s.error_private_required, parse_mode=ParseMode.MARKDOWN)
2016-04-23 15:07:09 +00:00
2016-05-27 22:13:34 +00:00
def role(bot, update):
2016-05-26 09:08:50 +00:00
"""Visualizza il tuo ruolo."""
game = findgamebyid(update.message.chat['id'])
if game is not None and game.phase is 'Voting':
player = game.findplayerbyid(update.message.from_user['id'])
if player is not None:
2016-05-26 09:08:50 +00:00
if player.alive:
2016-06-01 07:19:37 +00:00
player.message(bot, s.role_assigned.format(icon=player.role.icon, name=player.role.name))
2016-05-26 09:08:50 +00:00
game.message(bot, s.check_private)
else:
game.message(bot, s.error_dead)
else:
bot.sendMessage(update.message.chat['id'], s.error_not_in_game, parse_mode=ParseMode.MARKDOWN)
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
2016-04-25 17:44:40 +00:00
def debuggameslist(bot, update):
2016-05-25 09:52:53 +00:00
"""Visualizza l'elenco delle partite in corso."""
bot.sendMessage(update.message.from_user['id'], repr(inprogress), parse_mode=ParseMode.MARKDOWN)
2016-05-26 09:49:40 +00:00
def kill(bot, update):
2016-05-26 09:08:50 +00:00
"""Uccidi un giocatore in partita."""
game = findgamebyid(update.message.chat['id'])
if game is not None and game.phase is 'Voting':
2016-05-26 09:08:50 +00:00
if update.message.from_user['id'] == game.adminid:
target = game.findplayerbyusername(update.message.text.split(' ')[1])
if target is not None:
target.kill()
2016-05-27 11:42:25 +00:00
game.message(bot, s.admin_killed.format(name=target.tusername,
icon=target.role.icon,
role=target.role.name))
2016-05-26 09:08:50 +00:00
else:
2016-05-26 12:55:02 +00:00
game.message(bot, s.error_username)
2016-05-26 09:08:50 +00:00
else:
2016-05-26 12:55:02 +00:00
game.message(bot, s.error_not_admin)
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
2016-04-25 17:44:40 +00:00
2016-05-26 12:55:02 +00:00
def fakerole(bot, update):
"""Manda un finto messaggio di ruolo."""
if update.message.chat['type'] == 'private':
2016-05-27 11:42:25 +00:00
bot.sendMessage(update.message.chat['id'], s.role_assigned.format(icon=s.royal_icon, name=s.royal_name),
parse_mode=ParseMode.MARKDOWN)
bot.sendMessage(update.message.chat['id'], s.role_assigned.format(icon=s.mifia_icon, name=s.mifia_name),
parse_mode=ParseMode.MARKDOWN)
bot.sendMessage(update.message.chat['id'], s.role_assigned.format(icon=s.detective_icon, name=s.detective_name),
parse_mode=ParseMode.MARKDOWN)
bot.sendMessage(update.message.chat['id'], s.role_assigned.format(icon=s.angel_icon, name=s.angel_name),
parse_mode=ParseMode.MARKDOWN)
2016-05-26 12:55:02 +00:00
else:
bot.sendMessage(update.message.chat['id'], s.error_private_required, parse_mode=ParseMode.MARKDOWN)
2016-05-26 12:55:02 +00:00
2016-05-29 15:12:23 +00:00
def load(bot, update):
"""Carica una partita salvata."""
file = open(str(update.message.chat['id']) + ".p", "rb")
game = pickle.load(file)
inprogress.append(game)
game.message(bot, s.game_loaded)
def save(bot, update):
"""Salva una partita su file."""
game = findgamebyid(update.message.chat['id'])
if game is not None:
game.save()
else:
bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN)
2016-04-25 16:21:38 +00:00
updater.dispatcher.addHandler(CommandHandler('ping', ping))
updater.dispatcher.addHandler(CommandHandler('newgame', newgame))
updater.dispatcher.addHandler(CommandHandler('join', join))
updater.dispatcher.addHandler(CommandHandler('endjoin', endjoin))
updater.dispatcher.addHandler(CommandHandler('vote', vote))
updater.dispatcher.addHandler(CommandHandler('endday', endday))
updater.dispatcher.addHandler(CommandHandler('power', power))
updater.dispatcher.addHandler(CommandHandler('status', status))
2016-05-26 09:40:59 +00:00
updater.dispatcher.addHandler(CommandHandler('role', role))
updater.dispatcher.addHandler(CommandHandler('debug', debug))
2016-04-25 17:44:40 +00:00
updater.dispatcher.addHandler(CommandHandler('debuggameslist', debuggameslist))
2016-05-26 09:49:40 +00:00
updater.dispatcher.addHandler(CommandHandler('kill', kill))
2016-05-26 11:50:16 +00:00
updater.dispatcher.addHandler(CommandHandler('config', config))
2016-05-27 11:42:25 +00:00
updater.dispatcher.addHandler(CommandHandler('fakerole', fakerole))
2016-05-29 15:12:23 +00:00
updater.dispatcher.addHandler(CommandHandler('save', save))
updater.dispatcher.addHandler(CommandHandler('load', load))
2016-04-21 20:14:35 +00:00
updater.start_polling()
2016-05-27 09:34:06 +00:00
print("Bot avviato!")
if __name__ == "__main__":
updater.idle()