From 658d36721a7cf9e394924a0b5cbb5a0165d399e4 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Fri, 27 Jan 2017 18:11:53 +0100 Subject: [PATCH 01/10] print stuff --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index f08020a..e7c8cfb 100644 --- a/main.py +++ b/main.py @@ -1124,6 +1124,7 @@ def selectpreset(bot, update): def handleerror(bot, update, error): + print("Error: " + error) try: bot.sendMessage(update.message.chat['id'], error) except AttributeError: From c7f360caf120562fca3cc5ed5eb62f005ba403aa Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sat, 28 Jan 2017 23:21:52 +0100 Subject: [PATCH 02/10] Aggiunto lo stagista! --- main.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++++------ strings.py | 16 ++++++++++++ 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index e7c8cfb..ebe1607 100644 --- a/main.py +++ b/main.py @@ -176,7 +176,7 @@ class Angelo(Role): # Imposta qualcuno come protetto selected = game.findplayerbyusername(arg) if selected is not None: - if selected is not Player: + if selected is not Player: # TODO: cavolo ho scritto qui? # Togli la protezione a quello che stavi proteggendo prima if self.protecting is not None: self.protecting.protectedby = None @@ -312,8 +312,41 @@ class Mamma(Role): role=target.role.name)) break + +class Stagista(Role): + """Lo stagista sceglie una persona da cui andare in stage e prende il suo ruolo.""" + icon = s.intern_icon + team = 'Good' + name = s.intern_name + powerdesc = s.intern_power_description + + def __init__(self, player): + super().__init__(player) + self.master = None + + def __repr__(self) -> str: + return "" + + def power(self, bot, game, arg): + target = game.findplayerbyusername(arg) + if target is not None and target is not self.player: + self.master = target + self.player.message(bot, s.intern_started_internship) + else: + self.player.message(bot, s.error_no_username) + + def onendday(self, bot, game): + if self.master is not None: + if self.master.alive: + game.message(bot, s.intern_changed_role) + game.changerole(self.player, self.master.role.__class__) + else: + game.message(bot, "easter egg. yey") + #TODO: mettere l'easter egg + + # Ordine in cui vengono eseguiti i onendday dei vari ruoli. -rolepriority = [Mifioso, Investigatore, Disastro, Angelo, Derek, Terrorista, Mamma] +rolepriority = [Mifioso, Investigatore, Disastro, Angelo, Derek, Stagista, Terrorista, Mamma] class Player: @@ -577,7 +610,22 @@ class Game: def loadpreset(self, bot, preset): """Fine della fase di preset: carica il preset selezionato o passa a config""" - if preset == "simple": + if __debug__: + # Debug dello stagista + self.roleconfig = { + "Mifioso": 1, + "Investigatore": 1, + "Angelo": 1, + "Terrorista": 1, + "Derek": 1, + "Disastro": 1, + "Mamma": 1, + "Stagista": 1 + } + self.votingmifia = True + self.missingmifia = False + self.endconfig(bot) + elif preset == "simple": # Preset semplice self.roleconfig = { "Mifioso": math.floor(len(self.players) / 8) + 1, # 1 Mifioso ogni 8 giocatori @@ -586,7 +634,8 @@ class Game: "Terrorista": 0, "Derek": 0, "Disastro": 0, - "Mamma": 0 + "Mamma": 0, + "Stagista": 0 } self.votingmifia = True self.missingmifia = False @@ -600,7 +649,8 @@ class Game: "Terrorista": 1 if random.randrange(0, 99) > 70 else 0, # 30% di avere un terrorista "Derek": 0, "Disastro": 0, - "Mamma": 0 + "Mamma": 0, + "Stagista": 0 } self.votingmifia = True self.missingmifia = False @@ -615,7 +665,8 @@ class Game: "Terrorista": math.floor(len(self.players) / 11) + 1, "Derek": math.floor(len(self.players) / 12) + 1, "Disastro": math.floor(len(self.players) / 13) + 1, - "Mamma": math.floor(len(self.players) / 14) + 1 + "Mamma": math.floor(len(self.players) / 14) + 1, + "Stagista": 0 } self.votingmifia = True self.missingmifia = True @@ -678,7 +729,7 @@ class Game: file.close() def victoryconditions(self, bot): - # Condizioni di vittoria + """Controlla se qualcuno ha completato le condizioni di vittoria.""" good = 0 evil = 0 for player in self.players: @@ -710,6 +761,14 @@ class Game: player.message(bot, s.end_mifia_killed + s.defeat) self.endgame() + def changerole(self, player, newrole): + """Cambia il ruolo di un giocatore, aggiornando tutti i valori""" + self.playersinrole[player.role].remove(player) + player.role = newrole(player) + self.playersinrole[newrole].append(player) + # TODO: controllare se basta fare così + + # Partite in corso inprogress = list() diff --git a/strings.py b/strings.py index 40ce986..3dec369 100644 --- a/strings.py +++ b/strings.py @@ -125,6 +125,22 @@ mom_power_description = "All'inizio della partita scoprirai il ruolo di un gioca # Mamma: scoperta di un ruolo mom_discovery = "@{target} è un *{icon} {role}*.\n" \ +#TODO: Mettere qualcosa qui +# Stagista: icona +intern_icon = "intern_icon" + +# Stagista: nome ruolo +intern_name = "Stagista" + +# Stagista: descrizione del potere +intern_power_description = "intern_power_description" + +# Stagista: inizia lo stage +intern_started_internship = "intern_started_internship" + +# Stagista: cambiato ruolo +intern_changed_role = "intern_changed_role" + # Generale: ruolo assegnato role_assigned = "Ti è stato assegnato il ruolo di *{icon} {name}*." From 44976143cf1a6592d86938a4911582f4846aa205 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Jan 2017 00:36:58 +0100 Subject: [PATCH 03/10] Finito lo stagista. E funziona! --- main.py | 67 +++++++++++++++++++++++++++++++----------------------- strings.py | 17 +++++++++----- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/main.py b/main.py index ebe1607..72d104a 100644 --- a/main.py +++ b/main.py @@ -329,16 +329,16 @@ class Stagista(Role): def power(self, bot, game, arg): target = game.findplayerbyusername(arg) - if target is not None and target is not self.player: + if target is not None and target is not self.player and target.alive: self.master = target - self.player.message(bot, s.intern_started_internship) + self.player.message(bot, s.intern_started_internship.format(master=self.master.tusername)) else: self.player.message(bot, s.error_no_username) def onendday(self, bot, game): if self.master is not None: if self.master.alive: - game.message(bot, s.intern_changed_role) + game.message(bot, s.intern_changed_role.format(icon=self.master.role.__class__.icon, role=self.master.role.__class__.name)) game.changerole(self.player, self.master.role.__class__) else: game.message(bot, "easter egg. yey") @@ -373,7 +373,7 @@ class Player: if not self.dummy: try: bot.sendMessage(self.tid, text, parse_mode=ParseMode.MARKDOWN) - except TelegramError: + except TelegramError as t: pass @@ -452,7 +452,7 @@ class Game: def findplayerbyusername(self, tusername) -> Player: """Trova il giocatore con un certo username.""" for player in self.players: - if player.tusername.lower() == tusername.lower(): + if player.tusername.lower() == tusername.strip("@").lower(): return player else: return None @@ -536,7 +536,7 @@ class Game: def endday(self, bot): """Finisci la giornata, uccidi il più votato del giorno ed esegui gli endday di tutti i giocatori.""" # SALVA LA PARTITA, così se crasha si riprende da qui - self.save() + self.save(bot) # Conta i voti ed elimina il più votato. topvotes = self.mostvotedplayer() if len(topvotes) > 0: @@ -625,6 +625,7 @@ class Game: self.votingmifia = True self.missingmifia = False self.endconfig(bot) + self.message(bot, "Utilizzo il preset di debug (uno di ogni ruolo)") elif preset == "simple": # Preset semplice self.roleconfig = { @@ -702,7 +703,7 @@ class Game: def endgame(self): inprogress.remove(self) - def save(self): + def save(self, bot): # Crea il file. try: file = open(str(self.groupid) + ".p", 'x') @@ -715,8 +716,8 @@ class Game: pickle.dump(self, file) file.close() # Crea un file uguale ma con un timestamp - # Non sono troppo sicuro che il timestamp si faccia così - t = datetime.datetime(0,0,0,0,0).now() + # Non sono troppo sicuro che il timestamp si faccia così però funziona + t = datetime.datetime(2000,1,1,1,1).now() try: file = open("{group}-{yy}-{mm}-{dd}-{hh}-{mi}.p".format(group=str(self.groupid), yy=t.year, mm=t.month, dd=t.day, hh=t.hour, mi=t.minute), 'x') except FileExistsError: @@ -726,6 +727,7 @@ class Game: # Scrivi sul file. file = open("{group}-{yy}-{mm}-{dd}-{hh}-{mi}.p".format(group=str(self.groupid), yy=t.year, mm=t.month, dd=t.day, hh=t.hour, mi=t.minute), 'wb') pickle.dump(self, file) + self.message(bot, s.game_saved) file.close() def victoryconditions(self, bot): @@ -763,9 +765,10 @@ class Game: def changerole(self, player, newrole): """Cambia il ruolo di un giocatore, aggiornando tutti i valori""" - self.playersinrole[player.role].remove(player) + if player.role.__class__ != Royal: + self.playersinrole[player.role.__class__.__name__].remove(player) player.role = newrole(player) - self.playersinrole[newrole].append(player) + self.playersinrole[newrole.__name__].append(player) # TODO: controllare se basta fare così @@ -1021,7 +1024,7 @@ def vote(bot, update): game.message(bot, s.error_username) return player.votingfor = target - game.message(bot, s.vote.format(voted=target.tusername)) + game.message(bot, s.vote.format(voting=player.tusername, voted=target.tusername)) def endday(bot, update): @@ -1139,7 +1142,7 @@ def save(bot, update): """Salva una partita su file.""" game = findgamebyid(update.message.chat['id']) if game is not None: - game.save() + game.save(bot) else: bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN) @@ -1149,21 +1152,28 @@ def debug(bot, update): if __debug__: game = findgamebyid(update.message.chat['id']) if game is not None: - if game.admin.tid == update.message.from_user['id']: - text = s.status_header.format(name=game.groupid, admin=game.admin.tid, phase=game.phase) - game.updatevotes() - # Aggiungi l'elenco dei giocatori - for player in game.players: - if not player.alive: - text += s.status_dead_player.format(name=player.tusername) - else: - text += s.status_alive_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) + text = s.status_header.format(name=game.groupid, admin=game.admin.tid, phase=game.phase) + game.updatevotes() + # Aggiungi l'elenco dei giocatori + for player in game.players: + if not player.alive: + text += s.status_dead_player.format(name=player.tusername) + else: + text += s.status_alive_player.format(icon=player.role.icon, + 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 debugchangerole(bot, update): + """Cambia il ruolo a un giocatore.""" + if __debug__: + game = findgamebyid(update.message.chat['id']) + if game is not None: + cmd = update.message.text.split(' ', 2) + game.changerole(game.findplayerbyusername(cmd[1]), globals()[cmd[2]]) else: bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN) @@ -1209,6 +1219,7 @@ updater.dispatcher.add_handler(CommandHandler('fakerole', fakerole)) updater.dispatcher.add_handler(CommandHandler('save', save)) updater.dispatcher.add_handler(CommandHandler('load', load)) updater.dispatcher.add_handler(CommandHandler('delete', delete)) +updater.dispatcher.add_handler(CommandHandler('debugchangerole', debugchangerole)) updater.dispatcher.add_handler(CallbackQueryHandler(selectpreset)) updater.dispatcher.add_error_handler(handleerror) updater.start_polling() diff --git a/strings.py b/strings.py index 3dec369..944927c 100644 --- a/strings.py +++ b/strings.py @@ -125,21 +125,23 @@ mom_power_description = "All'inizio della partita scoprirai il ruolo di un gioca # Mamma: scoperta di un ruolo mom_discovery = "@{target} è un *{icon} {role}*.\n" \ -#TODO: Mettere qualcosa qui # Stagista: icona -intern_icon = "intern_icon" +intern_icon = "\U0001F913" # Stagista: nome ruolo intern_name = "Stagista" # Stagista: descrizione del potere -intern_power_description = "intern_power_description" +intern_power_description = "In qualsiasi momento della partita puoi scegliere un altro giocatore.\n" \ + "Il tuo ruolo diventerà uguale al suo.\n" \ + "Ricordati che, qualsiasi cosa succeda, è sempre colpa dello stagista, cioè tua!" +# TODO: si dice in stage? # Stagista: inizia lo stage -intern_started_internship = "intern_started_internship" +intern_started_internship = "Stai andando in stage da @{master}." # Stagista: cambiato ruolo -intern_changed_role = "intern_changed_role" +intern_changed_role = "Lo stagista ha finito il tirocinio ed ha imparato i segreti del mestiere di *{icon} {role}*." # Generale: ruolo assegnato role_assigned = "Ti è stato assegnato il ruolo di *{icon} {name}*." @@ -176,7 +178,7 @@ mifia_team_intro = "I mifiosi in questa partita sono:\n" mifia_team_player = "{icon} {name}\n" # Generale: votazione completata -vote = "Hai votato per uccidere @{voted}." +vote = "@{voting} ha votato per uccidere @{voted}." # Generale: un admin ha ucciso un giocatore con /kill admin_killed = "{name} è morto _di infarto_.\n" \ @@ -186,6 +188,9 @@ admin_killed = "{name} è morto _di infarto_.\n" \ check_private = "Messaggio inviato in chat privata.\n" \ "Controlla @mifiabot." +# Generale: partita salvata +game_saved = "Partita salvata su file." + # Generale: partita caricata game_loaded = "Partita caricata da file." From e53f34ad6d76af9b1a4c56cd3ca6fc2249f18058 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Jan 2017 01:59:55 +0100 Subject: [PATCH 04/10] bugfics --- main.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main.py b/main.py index 72d104a..8e58c4c 100644 --- a/main.py +++ b/main.py @@ -340,6 +340,15 @@ class Stagista(Role): if self.master.alive: game.message(bot, s.intern_changed_role.format(icon=self.master.role.__class__.icon, role=self.master.role.__class__.name)) game.changerole(self.player, self.master.role.__class__) + self.player.message(bot, s.role_assigned.format(icon=self.player.role.icon, name=self.player.role.name)) + if self.player.role.powerdesc is not None: + self.player.message(bot, self.player.role.powerdesc.format(gamename=self.name)) + if self.__class__ == Mifioso: + text = s.mifia_team_intro + for player in game.playersinrole['Mifioso']: + text += s.mifia_team_player.format(icon=player.role.icon, name=player.tusername) + for player in game.playersinrole['Mifioso']: + player.message(bot, text) else: game.message(bot, "easter egg. yey") #TODO: mettere l'easter egg From b69dc0084275903895aa2021c61ef6792e0e20cd Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Jan 2017 14:22:00 +0100 Subject: [PATCH 05/10] yay cose --- main.py | 236 +++++++++++++++++++++++++++++++++++++---------------- strings.py | 67 ++++++++++++--- 2 files changed, 222 insertions(+), 81 deletions(-) diff --git a/main.py b/main.py index 8e58c4c..4ca2e53 100644 --- a/main.py +++ b/main.py @@ -339,23 +339,71 @@ class Stagista(Role): if self.master is not None: if self.master.alive: game.message(bot, s.intern_changed_role.format(icon=self.master.role.__class__.icon, role=self.master.role.__class__.name)) - game.changerole(self.player, self.master.role.__class__) - self.player.message(bot, s.role_assigned.format(icon=self.player.role.icon, name=self.player.role.name)) - if self.player.role.powerdesc is not None: - self.player.message(bot, self.player.role.powerdesc.format(gamename=self.name)) - if self.__class__ == Mifioso: - text = s.mifia_team_intro - for player in game.playersinrole['Mifioso']: - text += s.mifia_team_player.format(icon=player.role.icon, name=player.tusername) - for player in game.playersinrole['Mifioso']: - player.message(bot, text) + game.changerole(bot, self.player, self.master.role.__class__) else: - game.message(bot, "easter egg. yey") - #TODO: mettere l'easter egg + game.message(bot, s.intern_chaos_summoned) + self.master.alive = True + game.changerole(bot, self.master, Servitore) + game.changerole(bot, self.player, SignoreDelCaos) + + +class SignoreDelCaos(Role): + """Il Signore del Caos è un Derek negli ultimi secondi prima della morte. + Può cambiare la vita delle altre persone... Anche se non può decidere in cosa.""" + icon = s.chaos_lord_icon + team = 'Chaos' + name = s.chaos_lord_name + powerdesc = s.chaos_lord_power_description + + def __init__(self, player): + super().__init__(player) + self.target = None + + def __repr__(self) -> str: + return "" + + def power(self, bot, game, arg): + selected = game.findplayerbyusername(arg) + if selected is not None and selected is not self.player and selected.alive: + self.target = selected + self.player.message(bot, s.chaos_lord_target_selected.format(target=self.target.tusername)) + else: + self.player.message(bot, s.error_no_username) + + def onendday(self, bot, game): + if self.target is not None: + if self.target.alive: + if not isinstance(self.target.role, SignoreDelCaos) or not isinstance(self.target.role, Servitore): + randomrole = random.sample(rolepriority, 1) + game.changerole(bot, self.target, randomrole) + game.message(bot, s.chaos_lord_randomized) + else: + game.message(bot, s.chaos_lord_failed) + + + +class Servitore(Role): + """Il servitore del Caos è il sottoposto al Signore del Caos. + Se non ci sono Signori del Caos in partita diventa Signore del Caos.""" + icon = s.derek_icon + team = 'Chaos' + name = s.chaos_servant_name + powerdesc = s.chaos_servant_power_description + + def __repr__(self) -> str: + return "" + + def onendday(self, bot, game): + for chaoslord in game.playersinrole["SignoreDelCaos"]: + if chaoslord.alive: + break + else: + game.changerole(bot, self, SignoreDelCaos) + game.message(bot, s.chaos_servant_inherited) # Ordine in cui vengono eseguiti i onendday dei vari ruoli. -rolepriority = [Mifioso, Investigatore, Disastro, Angelo, Derek, Stagista, Terrorista, Mamma] +rolepriority = [Mifioso, Investigatore, Disastro, Angelo, Derek, Stagista, Terrorista, Mamma, SignoreDelCaos, Servitore] class Player: @@ -382,7 +430,7 @@ class Player: if not self.dummy: try: bot.sendMessage(self.tid, text, parse_mode=ParseMode.MARKDOWN) - except TelegramError as t: + except TelegramError: pass @@ -603,49 +651,54 @@ class Game: def startpreset(self, bot): """Inizio della fase di preset""" self.phase = 'Preset' - # Crea la tastiera - kbmarkup = InlineKeyboardMarkup([ - [ - InlineKeyboardButton(s.preset_simple, callback_data="simple"), - InlineKeyboardButton(s.preset_classic, callback_data="classic"), - InlineKeyboardButton(s.preset_full, callback_data="full") - ], - [ - InlineKeyboardButton(s.preset_custom, callback_data="custom") - ] - ]) - # Manda la tastiera - bot.sendMessage(self.groupid, s.preset_choose, parse_mode=ParseMode.MARKDOWN, reply_markup=kbmarkup) - - def loadpreset(self, bot, preset): - """Fine della fase di preset: carica il preset selezionato o passa a config""" if __debug__: - # Debug dello stagista + # Preset di debug self.roleconfig = { - "Mifioso": 1, - "Investigatore": 1, - "Angelo": 1, - "Terrorista": 1, - "Derek": 1, - "Disastro": 1, - "Mamma": 1, - "Stagista": 1 + "Mifioso": 0, + "Investigatore": 0, + "Angelo": 0, + "Terrorista": 0, + "Derek": 0, + "Disastro": 0, + "Mamma": 0, + "Stagista": 0, + "SignoreDelCaos": 0, + "Servitore": 0 } self.votingmifia = True self.missingmifia = False self.endconfig(bot) - self.message(bot, "Utilizzo il preset di debug (uno di ogni ruolo)") - elif preset == "simple": + self.message(bot, "Utilizzando il preset di debug (tutti royal, cambia ruolo con `/debugchangerole nomeutente ruolo`.") + else: + # Crea la tastiera + kbmarkup = InlineKeyboardMarkup([ + [ + InlineKeyboardButton(s.preset_simple, callback_data="simple"), + InlineKeyboardButton(s.preset_classic, callback_data="classic"), + InlineKeyboardButton(s.preset_full, callback_data="full") + ], + [ + InlineKeyboardButton(s.preset_custom, callback_data="custom") + ] + ]) + # Manda la tastiera + bot.sendMessage(self.groupid, s.preset_choose, parse_mode=ParseMode.MARKDOWN, reply_markup=kbmarkup) + + def loadpreset(self, bot, preset): + """Fine della fase di preset: carica il preset selezionato o passa a config""" + if preset == "simple": # Preset semplice self.roleconfig = { - "Mifioso": math.floor(len(self.players) / 8) + 1, # 1 Mifioso ogni 8 giocatori - "Investigatore": math.floor(len(self.players) / 12) + 1, # 1 Detective ogni 12 giocatori - "Angelo": 0, - "Terrorista": 0, - "Derek": 0, - "Disastro": 0, - "Mamma": 0, - "Stagista": 0 + "Mifioso": math.floor(len(self.players) / 8) + 1, # 1 Mifioso ogni 8 giocatori + "Investigatore": math.floor(len(self.players) / 12) + 1, # 1 Detective ogni 12 giocatori + "Angelo": 0, + "Terrorista": 0, + "Derek": 0, + "Disastro": 0, + "Mamma": 0, + "Stagista": 0, + "SignoreDelCaos": 0, + "Servitore": 0 } self.votingmifia = True self.missingmifia = False @@ -653,14 +706,16 @@ class Game: elif preset == "classic": # Preset classico self.roleconfig = { - "Mifioso": math.floor(len(self.players) / 8) + 1, # 1 Mifioso ogni 8 giocatori - "Investigatore": math.floor(len(self.players) / 12) + 1, # 1 Detective ogni 12 giocatori - "Angelo": math.floor(len(self.players) / 10) + 1, # 1 Angelo ogni 10 giocatori - "Terrorista": 1 if random.randrange(0, 99) > 70 else 0, # 30% di avere un terrorista - "Derek": 0, - "Disastro": 0, - "Mamma": 0, - "Stagista": 0 + "Mifioso": math.floor(len(self.players) / 8) + 1, # 1 Mifioso ogni 8 giocatori + "Investigatore": math.floor(len(self.players) / 12) + 1, # 1 Detective ogni 12 giocatori + "Angelo": math.floor(len(self.players) / 10) + 1, # 1 Angelo ogni 10 giocatori + "Terrorista": 1 if random.randrange(0, 99) > 70 else 0, # 30% di avere un terrorista + "Derek": 0, + "Disastro": 0, + "Mamma": 0, + "Stagista": 0, + "SignoreDelCaos": 0, + "Servitore": 0 } self.votingmifia = True self.missingmifia = False @@ -669,14 +724,16 @@ class Game: # Preset completo self.roleconfig = { # 1 di ogni ruolo - "Mifioso": math.floor(len(self.players) / 8) + 1, - "Investigatore": math.floor(len(self.players) / 9) + 1, - "Angelo": math.floor(len(self.players) / 10) + 1, - "Terrorista": math.floor(len(self.players) / 11) + 1, - "Derek": math.floor(len(self.players) / 12) + 1, - "Disastro": math.floor(len(self.players) / 13) + 1, - "Mamma": math.floor(len(self.players) / 14) + 1, - "Stagista": 0 + "Mifioso": math.floor(len(self.players) / 9) + 1, + "Investigatore": math.floor(len(self.players) / 10) + 1, + "Angelo": math.floor(len(self.players) / 11) + 1, + "Terrorista": math.floor(len(self.players) / 12) + 1, + "Derek": math.floor(len(self.players) / 13) + 1, + "Disastro": math.floor(len(self.players) / 14) + 1, + "Mamma": math.floor(len(self.players) / 15) + 1, + "Stagista": math.floor(len(self.players) / 16) + 1, + "SignoreDelCaos": 0, + "Servitore": 0 } self.votingmifia = True self.missingmifia = True @@ -772,13 +829,26 @@ class Game: player.message(bot, s.end_mifia_killed + s.defeat) self.endgame() - def changerole(self, player, newrole): + def changerole(self, bot, player, newrole): """Cambia il ruolo di un giocatore, aggiornando tutti i valori""" + # Aggiorna le liste dei ruoli if player.role.__class__ != Royal: self.playersinrole[player.role.__class__.__name__].remove(player) + if player.role.__class__ != Royal: + self.playersinrole[newrole.__name__].append(player) + # Cambia il ruolo al giocatore player.role = newrole(player) - self.playersinrole[newrole.__name__].append(player) - # TODO: controllare se basta fare così + # Manda i messaggi del nuovo ruolo + player.message(bot, s.role_assigned.format(icon=player.role.icon, name=player.role.name)) + if player.role.powerdesc is not None: + player.message(bot, player.role.powerdesc.format(gamename=self.name)) + # Aggiorna lo stato dei mifiosi + if newrole == Mifioso: + text = s.mifia_team_intro + for player in self.playersinrole['Mifioso']: + text += s.mifia_team_player.format(icon=player.role.icon, name=player.tusername) + for player in self.playersinrole['Mifioso']: + player.message(bot, text) # Partite in corso @@ -967,6 +1037,30 @@ def config(bot, update): game.configstep += 1 game.message(bot, s.config_list[game.configstep]) elif game.configstep == 7: + try: + game.roleconfig["Stagista"] = 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 == 8: + try: + game.roleconfig["SignoreDelCaos"] = 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 == 9: + try: + game.roleconfig["SignoreDelCaos"] = 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 == 10: if cmd[1].lower() == 'testa': game.votingmifia = False game.configstep += 1 @@ -977,7 +1071,7 @@ def config(bot, update): game.message(bot, s.config_list[game.configstep]) else: game.message(bot, s.error_invalid_config) - elif game.configstep == 8: + elif game.configstep == 11: if cmd[1].lower() == 'perfetti': game.missingmifia = False game.endconfig(bot) @@ -987,7 +1081,7 @@ def config(bot, update): game.message(bot, s.config_list[game.configstep]) else: game.message(bot, s.error_invalid_config) - elif game.configstep == 9: + elif game.configstep == 12: try: miss = int(cmd[1]) except ValueError: @@ -1182,7 +1276,7 @@ def debugchangerole(bot, update): game = findgamebyid(update.message.chat['id']) if game is not None: cmd = update.message.text.split(' ', 2) - game.changerole(game.findplayerbyusername(cmd[1]), globals()[cmd[2]]) + game.changerole(bot, game.findplayerbyusername(cmd[1]), globals()[cmd[2]]) else: bot.sendMessage(update.message.chat['id'], s.error_no_games_found, parse_mode=ParseMode.MARKDOWN) diff --git a/strings.py b/strings.py index 944927c..d75db66 100644 --- a/strings.py +++ b/strings.py @@ -134,15 +134,56 @@ intern_name = "Stagista" # Stagista: descrizione del potere intern_power_description = "In qualsiasi momento della partita puoi scegliere un altro giocatore.\n" \ "Il tuo ruolo diventerà uguale al suo.\n" \ - "Ricordati che, qualsiasi cosa succeda, è sempre colpa dello stagista, cioè tua!" + "Ricordati che, qualsiasi cosa succeda, è sempre colpa dello stagista, cioè tua!\n" \ + "Per andare in stage, scrivi in questa chat:\n" \ + "`/power {gamename} nomeutentedatoredilavoro`" -# TODO: si dice in stage? # Stagista: inizia lo stage intern_started_internship = "Stai andando in stage da @{master}." # Stagista: cambiato ruolo intern_changed_role = "Lo stagista ha finito il tirocinio ed ha imparato i segreti del mestiere di *{icon} {role}*." +#Stagista: EVOCATO IL SIGNORE DEL CAOS +intern_chaos_summoned = "Il *\U0001F479 Signore del Caos* e il suo fedele servitore sono scesi sulla Terra.\n" \ + "Preparatevi... a non capirci più niente." + +# Signore del Caos: icona +chaos_lord_icon = "\U0001F479" + +# Signore del Caos: nome ruolo +chaos_lord_name = "Signore del Caos" + +# Signore del Caos: descrizione del potere +chaos_lord_power_description = "Sei il *SIGNORE DEL CAOS*!\n" \ + "Le faccende dei mortali non ti interessano, quindi non fai parte nè del team Mifia nè del team Royal.\n" \ + "Di conseguenza, hai automaticamente _vinto la partita_!\n" \ + "Puoi usare i tuoi poteri del Caos per cambiare ruolo a un altro giocatore.\n" \ + "Il ruolo che riceverà sarà casuale.\n" \ + "Per usare i tuoi poteri, scrivi in questa chat:\n" \ + "`/power {gamename} nomeutentebersaglio`" + +# Signore del Caos: bersaglio selezionato +chaos_lord_target_selected = "BWHAHAHA. Hai deciso di usare i tuoi poteri del Caos su {target}." + +# Signore del Caos: bersaglio randomizzato +chaos_lord_randomized = "Il Caos è nell'aria...\n" \ + "*Qualcuno ha cambiato ruolo!*" + +# Signore del Caos: randomizzazione fallita +chaos_lord_failed = "Il Caos è nell'aria...\n" \ + "_Ma non succede nulla._" + +# Servitore del Caos: nome ruolo +chaos_servant_name = "Servitore del Caos" + +# Servitore del Caos: descrizione potere +chaos_servant_power_description = "Il Signore del Caos ti cederà i suoi poteri quando sarà morto.\n" \ + "Facendo parte della fazione del Caos, hai automaticamente _vinto la partita_!" + +# Servitore del Caos: ereditato i poteri +chaos_servant_inherited = "Il servitore ha ereditato i poteri del *\U0001F479 Signore del Caos*." + # Generale: ruolo assegnato role_assigned = "Ti è stato assegnato il ruolo di *{icon} {name}*." @@ -207,6 +248,9 @@ end_mifia_killed = "Tutti i Mifiosi sono stati eliminati.\n" # Vittoria: nessuno vivo lol end_game_wiped = "Nessuno è più vivo. La specie umana si è estinta.\n" +# Vittoria: Sei un Signore del Caos. +end_game_chaos = "Sei un Signore del Caos." + # Vittoria: team Royal victory_royal = "**La Royal Games vince!**" @@ -316,13 +360,16 @@ names_list = ["Cassata", "Arancia"] # 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?", - "Quanti *Terroristi* devono essere nella partita?", - "Quanti *Derek* devono essere nella partita?", - "Quanti *Disastri* devono essere nella partita?", - "Quante *Mamme* devono essere nella partita?", +config_list = ["Quanti *Mifiosi* devono essere nella partita all'inizio?", + "Quanti *Investigatori* devono essere nella partita all'inizio?", + "Quanti *Angeli* devono essere nella partita all'inizio?", + "Quanti *Terroristi* devono essere nella partita all'inizio?", + "Quanti *Derek* devono essere nella partita all'inizio?", + "Quanti *Disastri* devono essere nella partita all'inizio?", + "Quante *Mamme* devono essere nella partita all'inizio?", + "Quanti *Stagisti* devono essere nella partita all'inizio?", + "Quante *Signori del Caos* devono essere nella partita all'inizio?", + "Quante *Servitori del Caos* devono essere nella partita all'inizio?", "I mifiosi possono uccidere una persona a `testa` al giorno " "o votano e decidono un'`unica` persona da uccidere per tutta la squadra?", "La mifia può `mancare` le uccisioni o i loro attacchi sono `perfetti`?", @@ -332,7 +379,7 @@ config_list = ["Quanti *Mifiosi* devono essere nella partita?", preset_choose = "*Seleziona un preset per la partita:*\n" \ "`Semplice`: solo royal, mifia e investigatori e niente meccaniche avanzate. _(minimo 3 giocatori)_\n" \ "`Classico`: royal, mifia, investigatori, angeli e la comparsa casuale di un terrorista! _(minimo 4 giocatori)_\n" \ - "`Completo`: tutti i ruoli e le meccaniche nuove! _(minimo 7 giocatori)_\n" \ + "`Completo`: tutti i ruoli e le meccaniche nuove! _(minimo 8 giocatori)_\n" \ "`Personalizzato`: scegli tu i ruoli e le meccaniche che vuoi in partita!" # Preset semplice From b097ec92812382c029b4c4a3b0bb20d315b0e7b3 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Jan 2017 14:42:40 +0100 Subject: [PATCH 06/10] boh --- main.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index 4ca2e53..28b950f 100644 --- a/main.py +++ b/main.py @@ -337,14 +337,14 @@ class Stagista(Role): def onendday(self, bot, game): if self.master is not None: - if self.master.alive: - game.message(bot, s.intern_changed_role.format(icon=self.master.role.__class__.icon, role=self.master.role.__class__.name)) - game.changerole(bot, self.player, self.master.role.__class__) - else: + if isinstance(self.master.role, Derek) and self.master.role.deathwish: game.message(bot, s.intern_chaos_summoned) self.master.alive = True - game.changerole(bot, self.master, Servitore) - game.changerole(bot, self.player, SignoreDelCaos) + game.changerole(bot, self.master, SignoreDelCaos) + game.changerole(bot, self.player, Servitore) + else: + game.message(bot, s.intern_changed_role.format(icon=self.master.role.__class__.icon, role=self.master.role.__class__.name)) + game.changerole(bot, self.player, self.master.role.__class__) class SignoreDelCaos(Role): From f95f39ca28df577a9a19a45c95f15b4634a3d3e1 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Jan 2017 14:51:11 +0100 Subject: [PATCH 07/10] molto meglio --- main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 28b950f..ab694b4 100644 --- a/main.py +++ b/main.py @@ -230,6 +230,7 @@ class Derek(Role): super().__init__(player) # Per qualche motivo assurdo ho deciso di tenere l'oggetto Player qui self.deathwish = False + self.chaos = False def __repr__(self) -> str: r = "" @@ -248,6 +249,7 @@ class Derek(Role): if self.deathwish: game.message(bot, s.derek_deathwish_successful.format(name=self.player.tusername)) self.player.kill(bot, game) + self.chaos = True class Disastro(Role): @@ -337,7 +339,7 @@ class Stagista(Role): def onendday(self, bot, game): if self.master is not None: - if isinstance(self.master.role, Derek) and self.master.role.deathwish: + if isinstance(self.master.role, Derek) and self.master.role.chaos: game.message(bot, s.intern_chaos_summoned) self.master.alive = True game.changerole(bot, self.master, SignoreDelCaos) From cd61e16212c3911f7cd25ed7a03ecdd66b97cadd Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Jan 2017 18:57:22 +0100 Subject: [PATCH 08/10] Votazioni con tastiera inline! --- main.py | 44 ++++++++++++++++++++++++-------------------- strings.py | 9 +++++++++ 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/main.py b/main.py index ab694b4..83fe1d5 100644 --- a/main.py +++ b/main.py @@ -1115,21 +1115,15 @@ def vote(bot, update): elif game.day <= 1: game.message(bot, s.error_no_votes_on_first_day) return - # Trova il giocatore - player = game.findplayerbyid(update.message.from_user['id']) - if player is None: - game.message(bot, s.error_not_in_game) - return - if not player.alive: - game.message(bot, s.error_dead) - return - # Trova il bersaglio - target = game.findplayerbyusername(update.message.text.split(' ')[1]) - if target is None: - game.message(bot, s.error_username) - return - player.votingfor = target - game.message(bot, s.vote.format(voting=player.tusername, voted=target.tusername)) + # Genera la tastiera + table = list() + for player in game.players: + row = list() + row.append(InlineKeyboardButton(s.vote_keyboard_line.format(name=player.tusername), callback_data=player.tusername)) + table.append(row) + keyboard = InlineKeyboardMarkup(table) + # Manda la tastiera + bot.sendMessage(game.groupid, s.vote_keyboard, parse_mode=ParseMode.MARKDOWN, reply_markup=keyboard) def endday(bot, update): @@ -1289,12 +1283,22 @@ def debuggameslist(bot, update): bot.sendMessage(update.message.from_user['id'], repr(inprogress), parse_mode=ParseMode.MARKDOWN) -def selectpreset(bot, update): +def inlinekeyboard(bot, update): """Seleziona un preset dalla tastiera.""" game = findgamebyid(update.callback_query.message.chat['id']) - if game is not None and game.phase is 'Preset': - if update.callback_query.from_user['id'] == game.admin.tid: - game.loadpreset(bot, update.callback_query.data) + if game is not None: + if game.phase is 'Preset': + if update.callback_query.from_user['id'] == game.admin.tid: + game.loadpreset(bot, update.callback_query.data) + elif game.phase is 'Voting': + # Trova il giocatore + player = game.findplayerbyid(update.callback_query.from_user['id']) + if player is not None: + # Trova il bersaglio + target = game.findplayerbyusername(update.callback_query.data) + player.votingfor = target + game.message(bot, s.vote.format(voting=player.tusername, voted=target.tusername)) + bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text=s.vote_fp.format(voted=target.tusername)) def handleerror(bot, update, error): @@ -1325,7 +1329,7 @@ updater.dispatcher.add_handler(CommandHandler('save', save)) updater.dispatcher.add_handler(CommandHandler('load', load)) updater.dispatcher.add_handler(CommandHandler('delete', delete)) updater.dispatcher.add_handler(CommandHandler('debugchangerole', debugchangerole)) -updater.dispatcher.add_handler(CallbackQueryHandler(selectpreset)) +updater.dispatcher.add_handler(CallbackQueryHandler(inlinekeyboard)) updater.dispatcher.add_error_handler(handleerror) updater.start_polling() print("Bot avviato!") diff --git a/strings.py b/strings.py index d75db66..c64823b 100644 --- a/strings.py +++ b/strings.py @@ -221,6 +221,9 @@ mifia_team_player = "{icon} {name}\n" # Generale: votazione completata vote = "@{voting} ha votato per uccidere @{voted}." +# Generale: votazione completata in prima persona +vote_fp = "Hai votato per uccidere @{voted}." + # Generale: un admin ha ucciso un giocatore con /kill admin_killed = "{name} è morto _di infarto_.\n" \ "Era un *{icon} {role}*." @@ -251,6 +254,12 @@ end_game_wiped = "Nessuno è più vivo. La specie umana si è estinta.\n" # Vittoria: Sei un Signore del Caos. end_game_chaos = "Sei un Signore del Caos." +# Generale: scegli per chi votare +vote_keyboard = "Chi vuoi votare...?" + +# Generale: riga della tastiera del voto +vote_keyboard_line = "@{name}" + # Vittoria: team Royal victory_royal = "**La Royal Games vince!**" From adf8c573735a2f6e2bf724b7536417d1c66e6465 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Jan 2017 20:18:23 +0100 Subject: [PATCH 09/10] Finito. --- main.py | 27 +++++++++++++++++---------- strings.py | 6 ++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index ab694b4..ef7320d 100644 --- a/main.py +++ b/main.py @@ -374,9 +374,9 @@ class SignoreDelCaos(Role): def onendday(self, bot, game): if self.target is not None: - if self.target.alive: + if self.target.alive and self.player.alive: if not isinstance(self.target.role, SignoreDelCaos) or not isinstance(self.target.role, Servitore): - randomrole = random.sample(rolepriority, 1) + randomrole = random.sample(rolepriority, 1)[0] game.changerole(bot, self.target, randomrole) game.message(bot, s.chaos_lord_randomized) else: @@ -400,7 +400,7 @@ class Servitore(Role): if chaoslord.alive: break else: - game.changerole(bot, self, SignoreDelCaos) + game.changerole(bot, self.player, SignoreDelCaos) game.message(bot, s.chaos_servant_inherited) @@ -802,24 +802,29 @@ class Game: """Controlla se qualcuno ha completato le condizioni di vittoria.""" good = 0 evil = 0 + alive = 0 for player in self.players: - if player.alive and player.role.team == 'Evil': - evil += 1 - elif player.alive and player.role.team == 'Good': - good += 1 + if player.alive: + if player.role.team == 'Evil': + evil += 1 + elif player.role.team == 'Good': + good += 1 + alive += 1 # Distruzione atomica! - if good == 0 and evil == 0: + if alive == 0: self.message(bot, s.end_game_wiped) for player in self.players: player.message(bot, s.end_game_wiped + s.tie) # Mifiosi più dei Royal - elif (not self.missingmifia and evil >= good) or good == 0: + elif (not self.missingmifia and evil >= alive) or good == 0: self.message(bot, s.end_mifia_outnumber + s.victory_mifia) for player in self.players: if player.role.team == 'Good': player.message(bot, s.end_mifia_outnumber + s.defeat) elif player.role.team == 'Evil': player.message(bot, s.end_mifia_outnumber + s.victory) + elif player.role.team == 'Chaos': + player.message(bot, s.end_game_chaos + s.victory) self.endgame() # Male distrutto elif evil == 0: @@ -829,6 +834,8 @@ class Game: player.message(bot, s.end_mifia_killed + s.victory) elif player.role.team == 'Evil': player.message(bot, s.end_mifia_killed + s.defeat) + elif player.role.team == 'Chaos': + player.message(bot, s.end_game_chaos + s.victory) self.endgame() def changerole(self, bot, player, newrole): @@ -836,7 +843,7 @@ class Game: # Aggiorna le liste dei ruoli if player.role.__class__ != Royal: self.playersinrole[player.role.__class__.__name__].remove(player) - if player.role.__class__ != Royal: + if newrole != Royal: self.playersinrole[newrole.__name__].append(player) # Cambia il ruolo al giocatore player.role = newrole(player) diff --git a/strings.py b/strings.py index d75db66..3c4168a 100644 --- a/strings.py +++ b/strings.py @@ -95,7 +95,7 @@ derek_power_description = "Puoi decidere di suicidarti alla fine di un round.\n" "Potresti farlo per confondere le idee ai Royal, o per ragequittare malissimo.\n" \ "Sta a te la scelta.\n" \ "Per lasciare questo mondo alla fine del giorno, scrivi in questa chat:\n" \ - "`/power {gamename}`\n" + "`/power {gamename} banana`\n" # Derek: morte attivata derek_deathwish_set = "*Morirai* alla fine di questo giorno." @@ -357,7 +357,9 @@ names_list = ["Cassata", "Torrone", "Sorbetto", "Limone", - "Arancia"] + "Arancia", + "Arancino", + "Arancina"] # Lista dei passi di configurazione da eseguire config_list = ["Quanti *Mifiosi* devono essere nella partita all'inizio?", From 97c2530ad3dfc1951a4c74524866aec35ef31abe Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Jan 2017 20:21:27 +0100 Subject: [PATCH 10/10] Finito. --- strings.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/strings.py b/strings.py index 2041f20..1a4373c 100644 --- a/strings.py +++ b/strings.py @@ -358,17 +358,14 @@ error_missing_parameters = "\U000026A0 Mancano uno o più parametri.\n" \ "Controlla la sintassi del comando e riprova." # Lista dei possibili nomi di una partita -names_list = ["Cassata", - "Cannoli", - "Granita", - "Mandorle", - "Salame", - "Torrone", - "Sorbetto", - "Limone", - "Arancia", - "Arancino", - "Arancina"] +names_list = ["Caos", + "Vuoto", + "Nulla", + "Buconero", + "Fine", + "Supernova", + "Centrogalattico", + "Madre"] # Lista dei passi di configurazione da eseguire config_list = ["Quanti *Mifiosi* devono essere nella partita all'inizio?",