mirror of
https://github.com/RYGhub/royal-mifia.git
synced 2025-02-16 13:24:06 +00:00
In teoria. In pratica non posso compilarlo.
This commit is contained in:
parent
914fda606c
commit
fbb2a8bd2d
1 changed files with 179 additions and 80 deletions
259
main.py
259
main.py
|
@ -15,6 +15,7 @@ logging.basicConfig(level=logging.WARN,
|
|||
token = filemanager.readfile('telegramapi.txt')
|
||||
updater = Updater(token)
|
||||
|
||||
freenames = s.names_list.copy()
|
||||
|
||||
# Ruoli possibili per i giocatori
|
||||
# Base di un ruolo
|
||||
|
@ -24,6 +25,11 @@ class Role:
|
|||
self.icon = "-" # Icona del ruolo, da visualizzare di fianco al nome
|
||||
self.team = 'None' # Squadra: 'None', 'Good', 'Evil'
|
||||
self.name = "UNDEFINED" # Nome del ruolo, viene visualizzato dall'investigatore e durante l'assegnazione dei ruoli
|
||||
self.powerdesc = None # Ha un potere? Se sì, inviagli le info su come usarlo.
|
||||
|
||||
def __repr__(self):
|
||||
r = "< undefined Role >"
|
||||
return r
|
||||
|
||||
def power(self, bot, game: Game, player: Player, arg: str):
|
||||
"""Il potere del ruolo. Si attiva quando il bot riceve un /power in chat privata."""
|
||||
|
@ -42,6 +48,10 @@ class Royal(Role):
|
|||
self.team = 'Good'
|
||||
self.name = s.royal_name
|
||||
|
||||
def __repr__(self):
|
||||
r = "< Role: Royal >"
|
||||
return r
|
||||
|
||||
|
||||
class Mifioso(Role):
|
||||
"""Il nemico globale. Può impostare come bersaglio una persona al giorno, per poi ucciderla alla fine."""
|
||||
|
@ -51,6 +61,14 @@ class Mifioso(Role):
|
|||
self.team = 'Evil'
|
||||
self.target = None
|
||||
self.name = s.mifia_name
|
||||
self.powerdesc = s.mifia_power_description
|
||||
|
||||
def __repr__(self):
|
||||
if self.target is None:
|
||||
r = "< Role: Mifioso >"
|
||||
else:
|
||||
r = "< Role: Mifioso, targeting {target} >".format(target=target.tusername)
|
||||
return r
|
||||
|
||||
def power(self, bot, game: Game, player: Player, arg: str):
|
||||
# Imposta una persona come bersaglio da uccidere.
|
||||
|
@ -78,6 +96,11 @@ class Investigatore(Role):
|
|||
self.team = 'Good'
|
||||
self.poweruses = 1
|
||||
self.name = s.detective_name
|
||||
self.powerdesc = s.detective_power_description.format(maxuses=self.poweruses)
|
||||
|
||||
def __repr__(self):
|
||||
r = "< Role: Investigatore, {uses} uses left >".format(uses=self.poweruses)
|
||||
return r
|
||||
|
||||
def power(self, bot, game: Game, player: Player, arg: str):
|
||||
# Indaga sul vero ruolo di una persona, se sono ancora disponibili usi del potere.
|
||||
|
@ -105,11 +128,22 @@ class Angelo(Role):
|
|||
self.team = 'Good' # Squadra: 'None', 'Good', 'Evil'
|
||||
self.name = s.angel_name
|
||||
self.protecting = None # La persona che questo angelo sta proteggendo
|
||||
self.powerdesc = s.angel_power_description
|
||||
|
||||
def __repr__(self):
|
||||
if protecting is None:
|
||||
r = "< Role: Angelo >"
|
||||
else:
|
||||
r = "< Role: Angelo, protecting {target}".format(target=self.protecting.tusername)
|
||||
return r
|
||||
|
||||
def power(self, bot, game: Game, player: Player, arg: str):
|
||||
# Imposta qualcuno come protetto
|
||||
selected = game.findplayerbyusername(arg)
|
||||
if player is not selected and selected is not None:
|
||||
# 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))
|
||||
|
@ -123,15 +157,6 @@ class Angelo(Role):
|
|||
|
||||
class Player:
|
||||
"""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."""
|
||||
def message(self, bot, text: str):
|
||||
"""Manda un messaggio privato al giocatore."""
|
||||
bot.sendMessage(self.tid, text)
|
||||
|
||||
def kill(self):
|
||||
"""Uccidi il giocatore."""
|
||||
# Perchè questo esiste?
|
||||
self.alive = False
|
||||
|
||||
def __init__(self, tid: int, tusername: str):
|
||||
self.tid = tid # ID di Telegram
|
||||
self.tusername = tusername # Username di Telegram
|
||||
|
@ -141,6 +166,17 @@ class Player:
|
|||
self.votes = 0 # Voti che sta ricevendo questo giocatore. Aggiornato da updatevotes()
|
||||
self.protectedby = None # Protettore. Oggetto player che protegge questo giocatore dalla mifia.
|
||||
|
||||
def __repr__(self):
|
||||
r = "< Player {username} >".format(username=self.tusername)
|
||||
|
||||
def message(self, bot, text: str):
|
||||
"""Manda un messaggio privato al giocatore."""
|
||||
bot.sendMessage(self.tid, text)
|
||||
|
||||
def kill(self):
|
||||
"""Uccidi il giocatore."""
|
||||
# Perchè questo esiste?
|
||||
self.alive = False
|
||||
|
||||
class Game:
|
||||
"""Classe di una partita, contenente parametri riguardanti stato della partita e informazioni sul gruppo di Telegram."""
|
||||
|
@ -150,6 +186,23 @@ class Game:
|
|||
self.players = list() # Lista dei giocatori in partita
|
||||
self.tokill = list() # Giocatori che verranno uccisi all'endday
|
||||
self.phase = 'Join' # Fase di gioco: 'Join', 'Voting', 'Ended'
|
||||
# Trova un nome per la partita
|
||||
if len(freenames) > 0:
|
||||
self.name = freenames.pop()
|
||||
else:
|
||||
self.name = str(groupid)
|
||||
|
||||
def __del__(self):
|
||||
# Rimetti il nome che si è liberato in disponibili.
|
||||
try:
|
||||
int(self.name)
|
||||
# Qual è quello giusto dei due? Non ho un interprete qui
|
||||
except TypeError, ValueError:
|
||||
freenames.append(self.name)
|
||||
|
||||
def __repr__(self):
|
||||
r = "< Game in group {groupid} with {nplayers} players in phase {phase} >".format(groupid=self.groupid, nplayers=len(self.players), phase=self.phase)
|
||||
return r
|
||||
|
||||
def message(self, bot, text: str):
|
||||
"""Manda un messaggio nel gruppo."""
|
||||
|
@ -165,8 +218,6 @@ class Game:
|
|||
for player in self.players:
|
||||
if isinstance(player.role, Mifioso):
|
||||
player.message(bot, text)
|
||||
# Inoltra il messaggio all'admin
|
||||
self.adminmessage(bot, text)
|
||||
|
||||
def findplayerbyid(self, tid: int) -> Player:
|
||||
"""Trova il giocatore con un certo id."""
|
||||
|
@ -191,37 +242,26 @@ class Game:
|
|||
random.shuffle(playersleft)
|
||||
# Seleziona mifiosi
|
||||
while mifia > 0:
|
||||
try:
|
||||
selected = playersleft.pop()
|
||||
except IndexError:
|
||||
raise IndexError(s.error_not_enough_players)
|
||||
else:
|
||||
selected.role = Mifioso()
|
||||
mifia -= 1
|
||||
selected = playersleft.pop()
|
||||
selected.role = Mifioso()
|
||||
mifia -= 1
|
||||
# Seleziona detective
|
||||
while investigatore > 0:
|
||||
try:
|
||||
selected = playersleft.pop()
|
||||
except IndexError:
|
||||
raise IndexError(s.error_not_enough_players)
|
||||
else:
|
||||
selected.role = Investigatore()
|
||||
investigatore -= 1
|
||||
selected = playersleft.pop()
|
||||
selected.role = Investigatore()
|
||||
investigatore -= 1
|
||||
# Seleziona angeli
|
||||
while angelo > 0:
|
||||
try:
|
||||
selected = playersleft.pop()
|
||||
except IndexError:
|
||||
raise IndexError(s.error_not_enough_players)
|
||||
else:
|
||||
selected.role = Angelo()
|
||||
angelo -= 1
|
||||
selected = playersleft.pop()
|
||||
selected.role = Angelo()
|
||||
angelo -= 1
|
||||
# Assegna il ruolo di Royal a tutti gli altri
|
||||
for player in playersleft:
|
||||
player.role = Royal()
|
||||
# Manda i ruoli assegnati a tutti
|
||||
for player in self.players:
|
||||
player.message(bot, s.role_assigned.format(icon=player.role.icon, name=player.role.name))
|
||||
player.message(bot, player.role.powerdesc.format(gamename=self.name))
|
||||
|
||||
def updatevotes(self):
|
||||
"""Aggiorna il conteggio dei voti di tutti i giocatori."""
|
||||
|
@ -303,6 +343,12 @@ def findgamebyid(gid: int) -> Game:
|
|||
return game
|
||||
|
||||
|
||||
def findgamebyname(name: str) -> Game:
|
||||
"""Trova una partita con un certo nome."""
|
||||
for game in inprogress:
|
||||
if game.name.lower() == name.lower():
|
||||
return name
|
||||
|
||||
# Comandi a cui risponde il bot
|
||||
def ping(bot, update):
|
||||
"""Ping!"""
|
||||
|
@ -312,11 +358,11 @@ def ping(bot, update):
|
|||
def newgame(bot, update):
|
||||
"""Crea una nuova partita."""
|
||||
if update.message.chat['type'] != 'private':
|
||||
g = findgamebyid(update.message.chat['id'])
|
||||
if g is None:
|
||||
g = Game(update.message.chat['id'], update.message.from_user['id'])
|
||||
inprogress.append(g)
|
||||
bot.sendMessage(update.message.chat['id'], s.new_game.format(g.groupid))
|
||||
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)
|
||||
else:
|
||||
|
@ -332,17 +378,19 @@ def join(bot, update):
|
|||
if p is None:
|
||||
p = Player(update.message.from_user['id'], update.message.from_user['username'])
|
||||
game.players.append(p)
|
||||
bot.sendMessage(update.message.chat['id'], s.player_joined.format(name=p.tusername))
|
||||
game.message(bot, s.player_joined.format(name=p.tusername))
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_player_already_joined)
|
||||
game.message(bot, s.error_player_already_joined)
|
||||
else:
|
||||
game.message(bot, s.error_join_phase_ended)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_no_games_found)
|
||||
|
||||
|
||||
def debug(bot, update):
|
||||
"""Visualizza tutti i ruoli e gli id."""
|
||||
game = findgamebyid(update.message.chat['id'])
|
||||
if game is None:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_no_games_found)
|
||||
else:
|
||||
if game is not None:
|
||||
if game.adminid == update.message.from_user['id']:
|
||||
text = s.status_header.format(name=game.groupid, admin=game.adminid, phase=game.phase)
|
||||
game.updatevotes()
|
||||
|
@ -351,18 +399,21 @@ def debug(bot, update):
|
|||
if not player.alive:
|
||||
text += s.status_dead_player.format(name=player.tusername)
|
||||
elif player.votingfor is not None:
|
||||
text += s.status_voting_player.format(icon=player.role.icon, name=player.tusername, votes=player.votes, voting=player.votingfor.tusername)
|
||||
text += s.status_voting_player.format(icon=player.role.icon, name=player.tusername, votes=str(player.votes), voting=player.votingfor.tusername)
|
||||
else:
|
||||
text += s.status_idle_player.format(icon=player.role.icon, name=player.tusername, votes=player.votes)
|
||||
bot.sendMessage(update.message.from_user['id'], text)
|
||||
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:
|
||||
game.message(bot, s.error_not_admin)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_no_games_found)
|
||||
|
||||
|
||||
def status(bot, update):
|
||||
"""Visualizza lo stato della partita."""
|
||||
game = findgamebyid(update.message.chat['id'])
|
||||
if game is None:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_no_games_found)
|
||||
else:
|
||||
if game is not None:
|
||||
text = s.status_header.format(name=game.groupid, admin=game.adminid, phase=game.phase)
|
||||
game.updatevotes()
|
||||
# Aggiungi l'elenco dei giocatori
|
||||
|
@ -370,25 +421,32 @@ def status(bot, update):
|
|||
if not player.alive:
|
||||
text += s.status_dead_player.format(player.tusername)
|
||||
elif player.votingfor is not None:
|
||||
text += s.status_voting_player.format(icon="\U0001F610", name=player.tusername, votes=player.votes, voting=player.votingfor.tusername)
|
||||
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=player.votes)
|
||||
bot.sendMessage(update.message.chat['id'], text)
|
||||
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)
|
||||
|
||||
|
||||
def endjoin(bot, update):
|
||||
"""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' and update.message.from_user['id'] == game.adminid:
|
||||
game.phase = 'Voting'
|
||||
game.message(bot, s.join_phase_ended)
|
||||
try:
|
||||
game.assignroles(bot, mifia=1, investigatore=0, angelo=1)
|
||||
except IndexError:
|
||||
game.message(bot, s.error_not_enough_players)
|
||||
game.endgame()
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.roles_assigned_successfully)
|
||||
if game is not None and game.phase is 'Join':
|
||||
if update.message.from_user['id'] == game.adminid:
|
||||
game.phase = 'Voting'
|
||||
game.message(bot, s.join_phase_ended)
|
||||
try:
|
||||
game.assignroles(bot, mifia=0, investigatore=0, angelo=0)
|
||||
except IndexError:
|
||||
game.message(bot, s.error_not_enough_players)
|
||||
game.endgame()
|
||||
else:
|
||||
game.message(bot, s.roles_assigned_successfully)
|
||||
else:
|
||||
game.message(bot, s.error_not_admin)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_no_games_found)
|
||||
|
||||
|
||||
|
||||
|
@ -397,15 +455,18 @@ def vote(bot, update):
|
|||
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 and player.alive:
|
||||
target = game.findplayerbyusername(update.message.text.split(' ')[1])
|
||||
if target is not None:
|
||||
player.votingfor = target
|
||||
bot.sendMessage(update.message.chat['id'], s.vote.format(voted=target.tusername))
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_username)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_dead)
|
||||
if player is not None
|
||||
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)
|
||||
|
||||
|
@ -420,36 +481,74 @@ def endday(bot, update):
|
|||
def power(bot, update):
|
||||
"""Attiva il potere del tuo ruolo."""
|
||||
if update.message.chat['type'] == 'private':
|
||||
# Ho un'idea su come farlo meglio. Forse.
|
||||
cmd = update.message.text.split(' ', 2)
|
||||
game = findgamebyid(int(cmd[1]))
|
||||
game = findgamebyname(cmd[1])
|
||||
# Se non lo trovi con il nome, prova con l'id
|
||||
if game is None:
|
||||
game = findgamebyid(int(cmd[1]))
|
||||
if game is not None:
|
||||
player = game.findplayerbyid(update.message.from_user['id'])
|
||||
if player.alive:
|
||||
player.role.power(bot, game, player, cmd[2])
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_dead)
|
||||
if player is not None:
|
||||
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)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_no_games_found)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_private_required)
|
||||
|
||||
def role(bot, update):
|
||||
"""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:
|
||||
if player.alive:
|
||||
player.message(bot, s.display_role.format(icon=player.role.icon, name=player.role.name))
|
||||
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)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_no_games_found)
|
||||
|
||||
|
||||
|
||||
def debuggameslist(bot, update):
|
||||
"""Visualizza l'elenco delle partite in corso."""
|
||||
bot.sendMessage(repr(inprogress))
|
||||
bot.sendMessage(update.message.from_user['id'], repr(inprogress))
|
||||
|
||||
|
||||
def debugkill(bot, update):
|
||||
"""Uccidi un giocatore in partita."""
|
||||
game = findgamebyid(update.message.chat['id'])
|
||||
if game is not None and game.phase is 'Voting':
|
||||
if update.message.from_user['id'] == game.adminid:
|
||||
target = game.findplayerbyusername(update.message.text.split(' ')[1])
|
||||
if target is not None:
|
||||
target.kill()
|
||||
bot.sendMessage(update.message.chat['id'], s.admin_killed.format(name=target.name, icon=target.role.icon, role=target.role.name))
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_username)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_not_admin)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_no_games_found)
|
||||
|
||||
updater.dispatcher.addHandler(CommandHandler('ping', ping))
|
||||
updater.dispatcher.addHandler(CommandHandler('newgame', newgame))
|
||||
updater.dispatcher.addHandler(CommandHandler('join', join))
|
||||
updater.dispatcher.addHandler(CommandHandler('debug', debug))
|
||||
updater.dispatcher.addHandler(CommandHandler('endjoin', endjoin))
|
||||
updater.dispatcher.addHandler(CommandHandler('vote', vote))
|
||||
updater.dispatcher.addHandler(CommandHandler('v', vote))
|
||||
updater.dispatcher.addHandler(CommandHandler('endday', endday))
|
||||
updater.dispatcher.addHandler(CommandHandler('power', power))
|
||||
updater.dispatcher.addHandler(CommandHandler('status', status))
|
||||
updater.dispatcher.addHandler(CommandHandler('s', status))
|
||||
updater.dispatcher.addHandler(CommandHandler('debug', debug))
|
||||
updater.dispatcher.addHandler(CommandHandler('debuggameslist', debuggameslist))
|
||||
updater.dispatcher.addHandler(CommandHandler('debugkill', debugkill))
|
||||
updater.start_polling()
|
||||
updater.idle()
|
||||
|
|
Loading…
Add table
Reference in a new issue