mirror of
https://github.com/RYGhub/royal-mifia.git
synced 2024-11-25 07:04:18 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
c8f3d1681a
2 changed files with 140 additions and 73 deletions
166
main.py
166
main.py
|
@ -25,11 +25,11 @@ class Role:
|
|||
def __init__(self):
|
||||
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.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.
|
||||
|
||||
def __repr__(self):
|
||||
r = "< undefined Role >"
|
||||
def __repr__(self) -> str:
|
||||
r = "<undefined Role>"
|
||||
return r
|
||||
|
||||
def power(self, bot, game, player, arg):
|
||||
|
@ -49,8 +49,8 @@ class Royal(Role):
|
|||
self.team = 'Good'
|
||||
self.name = s.royal_name
|
||||
|
||||
def __repr__(self):
|
||||
r = "< Role: Royal >"
|
||||
def __repr__(self) -> str:
|
||||
r = "<Role: Royal>"
|
||||
return r
|
||||
|
||||
|
||||
|
@ -64,17 +64,17 @@ class Mifioso(Role):
|
|||
self.name = s.mifia_name
|
||||
self.powerdesc = s.mifia_power_description
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
if self.target is None:
|
||||
r = "< Role: Mifioso >"
|
||||
r = "<Role: Mifioso>"
|
||||
else:
|
||||
r = "< Role: Mifioso, targeting {target} >".format(target=target.tusername)
|
||||
r = "<Role: Mifioso, targeting {target}>".format(target=self.target.tusername)
|
||||
return r
|
||||
|
||||
def power(self, bot, game, player, arg):
|
||||
# Imposta una persona come bersaglio da uccidere.
|
||||
selected = game.findplayerbyusername(arg)
|
||||
if self.target is not None:
|
||||
if selected is not None:
|
||||
self.target = selected
|
||||
player.message(bot, s.mifia_target_selected.format(target=self.target.tusername))
|
||||
else:
|
||||
|
@ -86,10 +86,13 @@ class Mifioso(Role):
|
|||
if self.target is not None:
|
||||
if self.target.protectedby is None:
|
||||
self.target.kill()
|
||||
game.message(bot, s.mifia_target_killed.format(target=self.target.tusername, icon=self.target.role.icon, role=self.target.role.name))
|
||||
game.message(bot, s.mifia_target_killed.format(target=self.target.tusername,
|
||||
icon=self.target.role.icon,
|
||||
role=self.target.role.name))
|
||||
else:
|
||||
game.message(bot, s.mifia_target_protected.format(target=self.target.tusername, icon=self.target.protectedby.role.icon,
|
||||
protectedby=self.target.protectedby.tusername))
|
||||
game.message(bot, s.mifia_target_protected.format(target=self.target.tusername,
|
||||
icon=self.target.protectedby.role.icon,
|
||||
protectedby=self.target.protectedby.tusername))
|
||||
self.target = None
|
||||
else:
|
||||
self.target = None
|
||||
|
@ -103,10 +106,10 @@ class Investigatore(Role):
|
|||
self.team = 'Good'
|
||||
self.poweruses = 1
|
||||
self.name = s.detective_name
|
||||
self.powerdesc = s.detective_power_description.format(maxuses=self.poweruses)
|
||||
self.powerdesc = s.detective_power_description
|
||||
|
||||
def __repr__(self):
|
||||
r = "< Role: Investigatore, {uses} uses left >".format(uses=self.poweruses)
|
||||
def __repr__(self) -> str:
|
||||
r = "<Role: Investigatore, {uses} uses left>".format(uses=self.poweruses)
|
||||
return r
|
||||
|
||||
def power(self, bot, game, player, arg):
|
||||
|
@ -115,8 +118,10 @@ class Investigatore(Role):
|
|||
target = game.findplayerbyusername(arg)
|
||||
if target is not None:
|
||||
self.poweruses -= 1
|
||||
player.message(bot, s.detective_discovery
|
||||
.format(target=target.tusername, icon=target.role.icon, role=target.role.name, left=self.poweruses))
|
||||
player.message(bot, s.detective_discovery.format(target=target.tusername,
|
||||
icon=target.role.icon,
|
||||
role=target.role.name,
|
||||
left=self.poweruses))
|
||||
else:
|
||||
player.message(bot, s.error_username)
|
||||
else:
|
||||
|
@ -128,7 +133,8 @@ class Investigatore(Role):
|
|||
|
||||
|
||||
class Angelo(Role):
|
||||
"""L'angelo può proteggere una persona al giorno dalla Mifia. Se ha successo nella protezione, il suo ruolo sarà rivelato a tutti."""
|
||||
"""L'angelo può proteggere una persona al giorno dalla Mifia.
|
||||
Se ha successo nella protezione, il suo ruolo sarà rivelato a tutti."""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.icon = s.angel_icon
|
||||
|
@ -137,11 +143,11 @@ class Angelo(Role):
|
|||
self.protecting = None # La persona che questo angelo sta proteggendo
|
||||
self.powerdesc = s.angel_power_description
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
if protecting is None:
|
||||
r = "< Role: Angelo >"
|
||||
r = "<Role: Angelo>"
|
||||
else:
|
||||
r = "< Role: Angelo, protecting {target}".format(target=self.protecting.tusername)
|
||||
r = "<Role: Angelo, protecting {target}>".format(target=self.protecting.tusername)
|
||||
return r
|
||||
|
||||
def power(self, bot, game, player, arg):
|
||||
|
@ -169,7 +175,8 @@ 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."""
|
||||
"""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 __init__(self, tid, tusername):
|
||||
self.tid = tid # ID di Telegram
|
||||
self.tusername = tusername # Username di Telegram
|
||||
|
@ -180,8 +187,9 @@ class Player:
|
|||
self.protectedby = None # Protettore. Oggetto player che protegge questo giocatore dalla mifia.
|
||||
self.mifiavotes = 0 # Voti che sta ricevendo questo giocatore dalla mifia. Aggiornato da updatemifiavotes()
|
||||
|
||||
def __repr__(self):
|
||||
r = "< Player {username} >".format(username=self.tusername)
|
||||
def __repr__(self) -> str:
|
||||
r = "<Player {username}>".format(username=self.tusername)
|
||||
return r
|
||||
|
||||
def message(self, bot, text):
|
||||
"""Manda un messaggio privato al giocatore."""
|
||||
|
@ -193,7 +201,8 @@ class Player:
|
|||
self.alive = False
|
||||
|
||||
class Game:
|
||||
"""Classe di una partita, contenente parametri riguardanti stato della partita e informazioni sul gruppo di Telegram."""
|
||||
"""Classe di una partita, contenente parametri riguardanti stato della partita
|
||||
e informazioni sul gruppo di Telegram."""
|
||||
def __init__(self, groupid, adminid):
|
||||
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
|
||||
|
@ -227,7 +236,8 @@ class Game:
|
|||
freenames.append(self.name)
|
||||
|
||||
def __repr__(self):
|
||||
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)
|
||||
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)
|
||||
return r
|
||||
|
||||
def message(self, bot, text):
|
||||
|
@ -301,12 +311,12 @@ class Game:
|
|||
if player.votingfor is not None and player.alive:
|
||||
player.votingfor.votes += 1
|
||||
|
||||
def updatevotes(self):
|
||||
def updatemifiavotes(self):
|
||||
"""Aggiorna il conteggio dei voti mifiosi di tutti i giocatori."""
|
||||
for player in self.players:
|
||||
player.mifiavotes = 0
|
||||
for player in self.players:
|
||||
if isinstance(player.role, Mifioso) and player.alive:
|
||||
for player in self.mifiosiingame:
|
||||
if player.alive:
|
||||
if player.role.target is not None:
|
||||
player.role.target.mifiavotes += 1
|
||||
|
||||
|
@ -317,28 +327,32 @@ class Game:
|
|||
self.updatevotes()
|
||||
for player in self.players:
|
||||
if player.votes > currenttop:
|
||||
mostvoted = [player]
|
||||
mostvoted = list()
|
||||
mostvoted.append(player)
|
||||
currenttop = player.votes
|
||||
elif player.votes == currenttop:
|
||||
mostvoted.append(player)
|
||||
if currenttop > 0:
|
||||
return mostvoted
|
||||
else:
|
||||
return None
|
||||
return list()
|
||||
|
||||
def mostvotedmifia(self) -> list:
|
||||
"""Trova il giocatore più votato dalla mifia."""
|
||||
mostvoted = list()
|
||||
currenttop = 0
|
||||
self.updatevotes()
|
||||
self.updatemifiavotes()
|
||||
for player in self.players:
|
||||
if player.mifiavotes > currenttop:
|
||||
mostvoted = [player]
|
||||
elif player.votes == currenttop:
|
||||
if player.mifiavotes > currenttop:
|
||||
mostvoted = list()
|
||||
mostvoted.append(player)
|
||||
currenttop = player.mifiavotes
|
||||
elif player.votes == currenttop:
|
||||
mostvoted.append(player)
|
||||
if currenttop > 0:
|
||||
return mostvoted
|
||||
else:
|
||||
return None
|
||||
return list()
|
||||
|
||||
|
||||
def endday(self, bot):
|
||||
|
@ -351,7 +365,9 @@ class Game:
|
|||
random.shuffle(topvotes)
|
||||
lynched = topvotes.pop()
|
||||
if lynched.alive:
|
||||
self.message(bot, s.player_lynched.format(name=lynched.tusername, icon=lynched.role.icon, role=lynched.role.name))
|
||||
self.message(bot, s.player_lynched.format(name=lynched.tusername,
|
||||
icon=lynched.role.icon,
|
||||
role=lynched.role.name))
|
||||
lynched.kill()
|
||||
else:
|
||||
self.message(bot, s.no_players_lynched)
|
||||
|
@ -361,14 +377,18 @@ class Game:
|
|||
# Mifiosi
|
||||
if self.votingmifia:
|
||||
# Trova il più votato dai mifiosi e uccidilo
|
||||
killlist = mostvotedmifia()
|
||||
killlist = self.mostvotedmifia()
|
||||
if len(killlist) > 0:
|
||||
# In caso di pareggio, elimina un giocatore casuale.
|
||||
random.seed()
|
||||
random.shuffle(killlist)
|
||||
killed = killlist.pop()
|
||||
if killed.alive:
|
||||
self.message(bot, s.mifia_target_killed.format(name=killed.tusername, icon=killed.role.icon, role=killed.role.name))
|
||||
self.message(bot, s.mifia_target_killed.format(target=killed.tusername,
|
||||
icon=killed.role.icon,
|
||||
role=killed.role.name))
|
||||
killed.kill()
|
||||
# Attiva il onendday dei mifiosi
|
||||
for player in self.mifiosiingame:
|
||||
if isinstance(player.role, Mifioso) and player.alive:
|
||||
player.role.onendday(bot, self)
|
||||
|
@ -398,6 +418,17 @@ class Game:
|
|||
self.message(bot, s.victory_royal)
|
||||
self.endgame()
|
||||
|
||||
def endconfig(self, bot):
|
||||
"""Fine della fase di config, inizio assegnazione ruoli"""
|
||||
self.phase = 'Voting'
|
||||
try:
|
||||
self.assignroles(bot)
|
||||
except IndexError:
|
||||
self.message(bot, s.error_not_enough_players)
|
||||
self.endgame()
|
||||
else:
|
||||
self.message(bot, s.roles_assigned_successfully)
|
||||
|
||||
def endgame(self):
|
||||
inprogress.remove(self)
|
||||
|
||||
|
@ -468,9 +499,14 @@ 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=str(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=str(player.votes))
|
||||
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:
|
||||
|
@ -490,7 +526,10 @@ def status(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="\U0001F610", name=player.tusername, votes=str(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=str(player.votes))
|
||||
game.message(bot, text)
|
||||
|
@ -518,7 +557,7 @@ def config(bot, update):
|
|||
if game is not None and game.phase is 'Config':
|
||||
if update.message.from_user['id'] == game.adminid:
|
||||
cmd = update.message.text.split(' ', 1)
|
||||
if len(cmd) >= 1:
|
||||
if len(cmd) >= 2:
|
||||
if game.configstep == 0:
|
||||
try:
|
||||
game.totalmifiosi = int(cmd[1])
|
||||
|
@ -544,20 +583,14 @@ def config(bot, update):
|
|||
game.configstep += 1
|
||||
game.message(bot, s.config_list[game.configstep])
|
||||
elif game.configstep == 3:
|
||||
try:
|
||||
game.votingmifia = bool(cmd[1])
|
||||
except ValueError:
|
||||
game.message(bot, s.error_invalid_config)
|
||||
if cmd[1].lower() == 'testa':
|
||||
game.votingmifia = False
|
||||
game.endconfig(bot)
|
||||
elif cmd[1].lower() == 'unica':
|
||||
game.votingmifia = True
|
||||
game.endconfig(bot)
|
||||
else:
|
||||
# Fine del config, inizio assegnazione ruoli
|
||||
game.phase = 'Voting'
|
||||
try:
|
||||
game.assignroles(bot)
|
||||
except IndexError:
|
||||
game.message(bot, s.error_not_enough_players)
|
||||
game.endgame()
|
||||
else:
|
||||
game.message(bot, s.roles_assigned_successfully)
|
||||
game.message(bot, s.error_invalid_config)
|
||||
else:
|
||||
game.message(bot, s.config_list[game.configstep])
|
||||
else:
|
||||
|
@ -647,7 +680,9 @@ def kill(bot, update):
|
|||
target = game.findplayerbyusername(update.message.text.split(' ')[1])
|
||||
if target is not None:
|
||||
target.kill()
|
||||
game.message(bot, s.admin_killed.format(name=target.tusername, icon=target.role.icon, role=target.role.name))
|
||||
game.message(bot, s.admin_killed.format(name=target.tusername,
|
||||
icon=target.role.icon,
|
||||
role=target.role.name))
|
||||
else:
|
||||
game.message(bot, s.error_username)
|
||||
else:
|
||||
|
@ -659,10 +694,14 @@ def kill(bot, update):
|
|||
def fakerole(bot, update):
|
||||
"""Manda un finto messaggio di ruolo."""
|
||||
if update.message.chat['type'] == 'private':
|
||||
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)
|
||||
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)
|
||||
else:
|
||||
bot.sendMessage(update.message.chat['id'], s.error_private_required, parse_mode=ParseMode.MARKDOWN)
|
||||
|
||||
|
@ -679,5 +718,8 @@ updater.dispatcher.addHandler(CommandHandler('debug', debug))
|
|||
updater.dispatcher.addHandler(CommandHandler('debuggameslist', debuggameslist))
|
||||
updater.dispatcher.addHandler(CommandHandler('kill', kill))
|
||||
updater.dispatcher.addHandler(CommandHandler('config', config))
|
||||
updater.dispatcher.addHandler(CommandHandler('fakerole', fakerole))
|
||||
updater.start_polling()
|
||||
updater.idle()
|
||||
print("Bot avviato!")
|
||||
if __name__ == "__main__":
|
||||
updater.idle()
|
||||
|
|
47
strings.py
47
strings.py
|
@ -25,7 +25,7 @@ mifia_target_killed = "@{target} è stato ucciso dalla Mifia.\n" \
|
|||
mifia_target_protected = "@{target} è stato protetto dalla Mifia da {icon} @{protectedby}!"
|
||||
|
||||
# Mifioso: descrizione del potere
|
||||
mifia_power_description = "Puoi uccidere una persona una volta al giorno.\n" \
|
||||
mifia_power_description = "Puoi selezionare come bersaglio di un'assassinio una personas.\n" \
|
||||
"Per selezionare un bersaglio, scrivi in questa chat:\n" \
|
||||
"`/power {gamename} nomeutentebersaglio`\n" \
|
||||
"Alla fine del giorno, tutti i bersagli dei Mifiosi saranno eliminati!"
|
||||
|
@ -41,7 +41,7 @@ detective_discovery = "@{target} è un *{icon} {role}*.\n" \
|
|||
"Puoi usare il tuo potere ancora *{left}* volte oggi."
|
||||
|
||||
# Investigatore: descrizione del potere
|
||||
detective_power_description = "Puoi indagare sul vero ruolo di una persona *{maxuses}* volte al giorno.\n" \
|
||||
detective_power_description = "Puoi indagare sul vero ruolo di una persona una volta al giorno.\n" \
|
||||
"Per indagare su qualcuno, scrivi in questa chat:\n" \
|
||||
"`/power {gamename} nomeutentebersaglio`\n"
|
||||
|
||||
|
@ -101,11 +101,11 @@ check_private = "Messaggio inviato in chat privata.\n" \
|
|||
|
||||
# Vittoria: team Mifia
|
||||
victory_mifia = "I Mifiosi rimasti sono più dei Royal.\n" \
|
||||
"*_La Mifia vince!_*"
|
||||
"*La Mifia vince!*"
|
||||
|
||||
# Vittoria: team Royal
|
||||
victory_royal = "Tutti i Mifiosi sono stati eliminati.\n" \
|
||||
"*_La Royal Games vince!_*"
|
||||
"*La Royal Games vince!*"
|
||||
|
||||
# Status: parte aggiunta prima dell'elenco dei giocatori (deve terminare con \n)
|
||||
status_header = "*ID:* {name}\n" \
|
||||
|
@ -140,15 +140,15 @@ error_game_in_progress = "\U000026A0 In questo gruppo è già in corso una parti
|
|||
# Errore: tipo di chat non supportato
|
||||
error_chat_type = "\U000026A0 Non puoi creare una partita in questo tipo di chat."
|
||||
|
||||
# Errore: per usare power, devi scrivere in chat privata
|
||||
error_private_required = "\U000026A0 Non puoi usare /power in un gruppo.\n" \
|
||||
# Errore: per usare questo comando, devi scrivere in chat privata
|
||||
error_private_required = "\U000026A0 Non puoi usare questo comando in un gruppo.\n" \
|
||||
"Scrivimi in chat privata a @mifiabot."
|
||||
|
||||
# Errore: giocatore già presente nella partita.
|
||||
error_player_already_joined = "\U000026A0 Ti sei già unito alla partita."
|
||||
|
||||
# Errore: nessuna partita in corso
|
||||
error_no_games_found = "\U000026A0 In questo gruppo non ci sono partite in corso."
|
||||
# Errore: nessuna partita trovata
|
||||
error_no_games_found = "\U000026A0 Non è stata trovata una partita su cui usare il comando."
|
||||
|
||||
# Errore: sei morto
|
||||
error_dead = "\U000026A0 Sei morto."
|
||||
|
@ -170,11 +170,36 @@ error_invalid_config = "\U000026A0 Configurazione non valida."
|
|||
|
||||
# Lista dei possibili nomi di una partita
|
||||
names_list = ["Modena",
|
||||
"Bologna",
|
||||
"Castelfranco"]
|
||||
"Nonantola",
|
||||
"Sassuolo",
|
||||
"Vignola",
|
||||
"Carpi",
|
||||
"Formigine",
|
||||
"Mirandola",
|
||||
"Castelfranco",
|
||||
"Pavullo",
|
||||
"Maranello",
|
||||
"Fiorano",
|
||||
"Finale",
|
||||
"Soliera",
|
||||
"Castelnuovo",
|
||||
"Spilamberto",
|
||||
"Castelvetro",
|
||||
"Novi",
|
||||
"Bomporto",
|
||||
"Savignano",
|
||||
"Campogalliano",
|
||||
"Concordia",
|
||||
"Serramazzoni",
|
||||
"Cavezzo",
|
||||
"Medolla",
|
||||
"Ravarino",
|
||||
"Marano",
|
||||
"Zocca",
|
||||
"Guiglia"]
|
||||
|
||||
# Lista dei passi di configurazione da eseguire
|
||||
config_list = ["Quanti Mifiosi devono essere nella partita?",
|
||||
"Quanti Investigatori devono essere nella partita?",
|
||||
"Quanti Angeli devono essere nella partita?",
|
||||
"Le uccisioni della Mifia sono come nel gioco classico (True) o ogni Mifioso può uccidere un giocatore come nella versione di Steffo (False) ?"]
|
||||
"I mifiosi possono uccidere una persona a `testa` al giorno o votano e decidono un'`unica` persona da uccidere per tutta la squadra?"]
|
||||
|
|
Loading…
Reference in a new issue