1
Fork 0
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:
Steffo 2016-05-28 00:09:49 +02:00
commit c8f3d1681a
2 changed files with 140 additions and 73 deletions

146
main.py
View file

@ -25,10 +25,10 @@ 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):
def __repr__(self) -> str:
r = "<undefined Role>"
return r
@ -49,7 +49,7 @@ class Royal(Role):
self.team = 'Good'
self.name = s.royal_name
def __repr__(self):
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>"
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,9 +86,12 @@ 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,
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:
@ -103,9 +106,9 @@ 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):
def __repr__(self) -> str:
r = "<Role: Investigatore, {uses} uses left>".format(uses=self.poweruses)
return r
@ -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>"
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):
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]
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:
if cmd[1].lower() == 'testa':
game.votingmifia = False
game.endconfig(bot)
elif cmd[1].lower() == 'unica':
game.votingmifia = True
game.endconfig(bot)
else:
game.message(bot, s.error_invalid_config)
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)
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()
print("Bot avviato!")
if __name__ == "__main__":
updater.idle()

View file

@ -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?"]