mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
396 lines
16 KiB
Python
396 lines
16 KiB
Python
# -*- coding: utf-8 -*-
|
|
import telegram
|
|
import configparser
|
|
import random
|
|
|
|
|
|
class Player:
|
|
telegramid = int()
|
|
username = str()
|
|
role = 0 # 0 normale | 1 rryg | 2 resistenza
|
|
alive = True
|
|
votedfor = str()
|
|
special = False
|
|
|
|
def message(self, text):
|
|
"""Manda un messaggio al giocatore
|
|
:param text: Testo del messaggio
|
|
"""
|
|
telegram.sendmessage(text, self.telegramid)
|
|
|
|
|
|
partiteincorso = list()
|
|
|
|
|
|
class Game:
|
|
groupid = int()
|
|
adminid = int()
|
|
players = list()
|
|
tokill = list()
|
|
joinphase = True
|
|
|
|
def __del__(self):
|
|
print("Partita {0} eliminata.\n".format(self.groupid))
|
|
|
|
def message(self, text):
|
|
"""Manda un messaggio alla chat generale del gioco
|
|
:param text: Testo del messaggio
|
|
"""
|
|
telegram.sendmessage(text, self.groupid)
|
|
|
|
def adminmessage(self, text):
|
|
"""Manda un messaggio all'admin del gioco
|
|
:param text: Testo del messaggio
|
|
"""
|
|
telegram.sendmessage(text, self.adminid)
|
|
|
|
def evilmessage(self, text):
|
|
"""Manda un messaggio al team dei nemici del gioco
|
|
:param text: Testo del messaggio
|
|
"""
|
|
for player in self.players:
|
|
if player.role == 1:
|
|
telegram.sendmessage("\U0001F608: " + text, player.telegramid)
|
|
telegram.sendmessage("\U0001F608: " + text, self.adminid)
|
|
|
|
def status(self) -> str:
|
|
"""Restituisci lo stato attuale della partita in una stringa"""
|
|
tosend = "Stato attuale del gioco: \n"
|
|
for player in self.players:
|
|
if not player.alive:
|
|
tosend += "\U0001F480 "
|
|
else:
|
|
tosend += "\U0001F636 "
|
|
tosend += player.username + "\n"
|
|
return tosend
|
|
|
|
def mifiastatus(self) -> str:
|
|
"""Restituisci lo stato attuale della partita (per mifiosi) in una stringa"""
|
|
tosend = "Stato attuale del gioco: \n"
|
|
for player in self.players:
|
|
if not player.alive:
|
|
tosend += "\U0001F480 "
|
|
elif player.role == 1:
|
|
tosend += "\U0001F608 "
|
|
else:
|
|
tosend += "\U0001F610 "
|
|
tosend += player.username + "\n"
|
|
return tosend
|
|
|
|
def fullstatus(self) -> str:
|
|
"""Restituisci lo stato attuale della partita (per admin?) in una stringa"""
|
|
tosend = str(self.groupid) + "\n"
|
|
for player in self.players:
|
|
if not player.alive:
|
|
tosend += "\U0001F480 "
|
|
elif player.role == 1:
|
|
tosend += "\U0001F608 "
|
|
elif player.role == 2:
|
|
tosend += "\U0001F575 "
|
|
else:
|
|
tosend += "\U0001F610 "
|
|
tosend += player.username + "\n"
|
|
return tosend
|
|
|
|
def findusername(self, fusername) -> Player:
|
|
"""Trova un giocatore con un certo nome utente
|
|
:param fusername: Nome utente da cercare
|
|
"""
|
|
for player in self.players:
|
|
if player.username == fusername.capitalize():
|
|
return player
|
|
else:
|
|
return None
|
|
|
|
def findid(self, telegramid) -> Player:
|
|
"""Trova un giocatore con un certo ID di telegram
|
|
:param telegramid: ID da cercare
|
|
"""
|
|
for player in self.players:
|
|
if player.telegramid == telegramid:
|
|
return player
|
|
else:
|
|
return None
|
|
|
|
def addplayer(self, player):
|
|
"""Aggiungi un giocatore alla partita
|
|
:param player: Oggetto del giocatore da aggiungere
|
|
"""
|
|
self.players.append(player)
|
|
|
|
def mostvoted(self) -> Player:
|
|
"""Trova il giocatore più votato"""
|
|
votelist = dict()
|
|
for player in self.players:
|
|
if player.votedfor != str() and player.alive:
|
|
if player.votedfor not in votelist:
|
|
votelist[player.votedfor] = 1
|
|
else:
|
|
votelist[player.votedfor] += 1
|
|
mostvoted = str()
|
|
mostvotes = int()
|
|
for player in votelist:
|
|
if mostvoted == str():
|
|
mostvoted = player
|
|
mostvotes = votelist[player]
|
|
else:
|
|
if votelist[player] > mostvotes:
|
|
mostvoted = player
|
|
mostvotes = votelist[player]
|
|
if mostvoted is not None:
|
|
return self.findusername(mostvoted)
|
|
else:
|
|
return None
|
|
|
|
def endday(self):
|
|
votedout = self.mostvoted()
|
|
self.message(votedout.username + " è il più votato del giorno e sarà ucciso.")
|
|
self.tokill.append(votedout)
|
|
for killed in self.tokill:
|
|
tosend = killed.username + " è stato ucciso.\n"
|
|
if killed.role == 0:
|
|
tosend += "Era un \U0001F610 Royal."
|
|
elif killed.role == 1:
|
|
tosend += "Era un \U0001F608 Mifioso!"
|
|
elif killed.role == 2:
|
|
tosend += "Era un \U0001F575 Detective!"
|
|
self.message(tosend)
|
|
killed.alive = False
|
|
for player in self.players:
|
|
player.votedfor = str()
|
|
if player.role != 0:
|
|
player.special = True
|
|
self.message(self.displaycount())
|
|
mifia = self.mifiacount()
|
|
royal = self.royalcount()
|
|
if mifia == 0:
|
|
self.message("*Il Team Royal ha vinto!*\n"
|
|
"Tutti i Mifiosi sono stati eliminati.")
|
|
partiteincorso.remove(findgame(self.groupid))
|
|
if mifia >= royal:
|
|
self.message("*Il Team Mifia ha vinto!*\n"
|
|
"I Mifiosi rimasti sono tanti quanti i Royal.")
|
|
self.tokill = list()
|
|
|
|
def mifiacount(self) -> int:
|
|
mifia = 0
|
|
for player in self.players:
|
|
if player.alive:
|
|
if player.role == 1:
|
|
mifia += 1
|
|
return mifia
|
|
|
|
def royalcount(self) -> int:
|
|
royal = 0
|
|
for player in self.players:
|
|
if player.alive:
|
|
if player.role == 0 or player.role == 2:
|
|
royal += 1
|
|
return royal
|
|
|
|
def displaycount(self) -> str:
|
|
msg = "*Royal*: {0} persone rimaste\n" \
|
|
"*Mifia*: {1} persone rimaste".format(str(self.royalcount()), str(self.mifiacount()))
|
|
return msg
|
|
|
|
# Ricordatemi perchè ho deciso di salvare i dati in un ini invece che in un file json
|
|
def save(self):
|
|
status = configparser.ConfigParser()
|
|
status['General'] = {
|
|
"groupid": self.groupid,
|
|
"adminid": self.adminid,
|
|
}
|
|
for player in self.players:
|
|
status[player.username] = {
|
|
"telegramid": player.telegramid,
|
|
"role": player.role,
|
|
"alive": player.alive,
|
|
}
|
|
try:
|
|
f = open(str(self.groupid) + ".ini", "w")
|
|
except OSError:
|
|
open(str(self.groupid) + ".ini", "x")
|
|
f = open(str(self.groupid) + ".ini", "w")
|
|
status.write(f)
|
|
|
|
def endjoin(self):
|
|
self.message("La fase di join è finita.")
|
|
self.joinphase = False
|
|
|
|
|
|
def findgame(chatid) -> Game:
|
|
for game in partiteincorso:
|
|
if game.groupid == chatid:
|
|
return game
|
|
else:
|
|
return None
|
|
|
|
|
|
def loadgame(chatid) -> Game:
|
|
l = Game()
|
|
loaded = configparser.ConfigParser()
|
|
loaded.read(str(chatid) + ".ini")
|
|
# General non è un giocatore, quindi toglilo
|
|
playerlist = loaded.sections()
|
|
playerlist.remove("General")
|
|
for player in playerlist:
|
|
lp = Player()
|
|
lp.alive = bool(loaded[player]['alive'])
|
|
lp.username = player
|
|
lp.role = int(loaded[player]['role'])
|
|
if lp.role == 1 or lp.role == 2:
|
|
lp.special = True
|
|
lp.telegramid = int(loaded[player]['telegramid'])
|
|
l.players.append(lp)
|
|
l.groupid = int(loaded['General']['groupid'])
|
|
l.adminid = int(loaded['General']['adminid'])
|
|
return l
|
|
|
|
random.seed()
|
|
|
|
while True:
|
|
t = telegram.getupdates()
|
|
if 'text' in t:
|
|
g = findgame(t['chat']['id'])
|
|
if g is None:
|
|
if t['text'].startswith("/newgame"):
|
|
g = Game()
|
|
g.groupid = t['chat']['id']
|
|
g.adminid = t['from']['id']
|
|
partiteincorso.append(g)
|
|
g.message("Partita creata!")
|
|
elif t['text'].startswith("/loadgame"):
|
|
g = loadgame(t['chat']['id'])
|
|
partiteincorso.append(g)
|
|
g.message("Partita caricata!\n_Forse._")
|
|
elif t['text'].startswith("/status"):
|
|
telegram.sendmessage("Nessuna partita in corso in questo gruppo.", t['chat']['id'], t['message_id'])
|
|
else:
|
|
xtra = t['text'].split(' ', 2)
|
|
try:
|
|
g = findgame(int(xtra[0]))
|
|
except ValueError:
|
|
g = None
|
|
if g is not None:
|
|
if xtra[1].lower() == "special":
|
|
if g.findid(t['from']['id']).role == 1 and g.findid(t['from']['id']).special:
|
|
target = g.findusername(xtra[2])
|
|
if target is not None:
|
|
g.tokill.append(target)
|
|
g.findid(t['from']['id']).special = False
|
|
g.evilmessage("Il bersaglio di " + t['from']['username'] + " è *" + target.username +
|
|
"*.")
|
|
elif g.findid(t['from']['id']).role == 2 and g.findid(t['from']['id']).special:
|
|
target = g.findusername(xtra[2])
|
|
p = g.findid(t['from']['id'])
|
|
if target is not None:
|
|
if target.role == 0:
|
|
p.message(target.username + " è un \U0001F610 Royal.")
|
|
elif target.role == 1:
|
|
p.message(target.username + " è un \U0001F608 Mifioso.")
|
|
elif target.role == 2:
|
|
p.message(target.username + " è un \U0001F575 Detective.")
|
|
p.special = False
|
|
elif xtra[1].lower() == "chat":
|
|
if g.findid(t['from']['id']).role == 1:
|
|
g.evilmessage(xtra[2])
|
|
else:
|
|
if t['text'].startswith("/join"):
|
|
if g.joinphase and g.findid(t['from']['id']) is None:
|
|
p = Player()
|
|
p.telegramid = t['from']['id']
|
|
# Qui crasha se non è stato impostato un username. Fare qualcosa?
|
|
p.username = t['from']['username'].capitalize()
|
|
# Assegnazione dei ruoli
|
|
r = random.randrange(0, 100)
|
|
# Spiegare meglio cosa deve fare ogni ruolo?
|
|
if r < 15 and g.mifiacount() < 3:
|
|
p.role = 1
|
|
p.special = True
|
|
p.message("Sei stato assegnato alla squadra \U0001F608 *MIFIA*.\n"
|
|
"Apparirai agli altri come un membro del team ROYAL.\n"
|
|
"Depistali e non farti uccidere!\n"
|
|
"Il team ROYAL ucciderà la persona più votata di ogni turno.\n"
|
|
"Per votare, scrivi `/vote username`!\n"
|
|
"Scrivi in questa chat `{0} CHAT messaggio` per mandare un"
|
|
" messaggio segreto al tuo team.\n"
|
|
"Scrivi in questa chat `{0} SPECIAL username` per uccidere"
|
|
" qualcuno alla fine del giorno.\n"
|
|
"La squadra Mifia vince se tutta la Royal Games è eliminata.\n"
|
|
"Perdi se vieni ucciso."
|
|
.format(g.groupid))
|
|
elif r > 90:
|
|
p.role = 2
|
|
p.special = True
|
|
p.message("Sei stato assegnato alla squadra *ROYAL* con il ruolo di \U0001F575 *DETECTIVE*.\n"
|
|
"Apparirai agli altri come un membro del team ROYAL.\n"
|
|
"Non attirare l'attenzione dei Mifiosi su di te!\n"
|
|
"Il team ROYAL ucciderà la persona più votata di ogni turno.\n"
|
|
"Per votare, scrivi `/vote username`!\n"
|
|
"Tra di voi si nascondono dei Mifiosi.\n"
|
|
"Stanateli e uccideteli votando per le persone giuste!\n"
|
|
"La squadra Royal vince se tutti i Mifiosi sono morti.\n"
|
|
"La squadra Royal perde se sono vivi solo Mifiosi.\n"
|
|
"Scrivi in questa chat `{0} SPECIAL nomeutente` per usare il tuo "
|
|
" potere di detective e indagare sul ruolo di qualcuno per un giorno."
|
|
.format(g.groupid))
|
|
else:
|
|
p.role = 0
|
|
p.special = True
|
|
p.message("Sei stato assegnato alla squadra \U0001F610 *ROYAL*.\n"
|
|
"Il team ROYAL ucciderà la persona più votata di ogni turno.\n"
|
|
"Per votare, scrivi `/vote username`!\n"
|
|
"Tra di voi si nascondono dei Mifiosi.\n"
|
|
"Stanateli e uccideteli votando per le persone giuste!\n"
|
|
"La squadra Royal vince se tutti i Mifiosi sono morti.\n"
|
|
"La squadra Royal perde se sono vivi solo Mifiosi.")
|
|
g.addplayer(p)
|
|
g.message(p.username + " si è unito alla partita!")
|
|
g.adminmessage(g.fullstatus())
|
|
g.save()
|
|
else:
|
|
g.message("\u26A0\uFE0F Non puoi unirti alla partita.\n"
|
|
"La fase di unione è terminata o ti sei già unito in precedenza.")
|
|
elif t['text'].startswith("/status"):
|
|
if not g.joinphase:
|
|
g.message(g.status() + "\n" + g.displaycount())
|
|
else:
|
|
g.message(g.status())
|
|
p = g.findid(t['from']['id'])
|
|
if p is not None and p.role == 1:
|
|
p.message(g.mifiastatus())
|
|
elif t['text'].startswith("/fullstatus"):
|
|
if t['from']['id'] == g.adminid:
|
|
g.adminmessage(g.fullstatus() + "\n" + g.displaycount())
|
|
else:
|
|
g.message("\u26A0\uFE0F Non sei il creatore della partita; non puoi vedere lo status completo.")
|
|
elif t['text'].startswith("/save"):
|
|
if t['from']['id'] == g.adminid:
|
|
g.save()
|
|
g.message("Partita salvata!\n_Funzione instabile, speriamo che non succedano casini..._")
|
|
else:
|
|
g.message("\u26A0\uFE0F Non sei il creatore della partita; non puoi salvare la partita.")
|
|
elif t['text'].startswith("/endday"):
|
|
if t['from']['id'] == g.adminid:
|
|
g.endday()
|
|
else:
|
|
g.message("\u26A0\uFE0F Non sei il creatore della partita; non puoi finire il giorno.")
|
|
elif t['text'].startswith("/vote"):
|
|
if not g.joinphase:
|
|
username = t['text'].split(' ')
|
|
if len(username) > 1 and g.findusername(username[1]) is not None:
|
|
voter = g.findid(t['from']['id'])
|
|
if voter is not None:
|
|
if voter.alive:
|
|
voter.votedfor = username[1]
|
|
g.message("Hai votato per " + username[1] + ".")
|
|
else:
|
|
g.message("_La tua votazione riecheggia nel nulla._\n"
|
|
"\u26A0\uFE0F Sei morto, e i morti non votano.")
|
|
else:
|
|
g.message("\u26A0\uFE0F La persona selezionata non esiste.")
|
|
else:
|
|
g.message("\u26A0\uFE0F La partita non è ancora iniziata; non puoi votare.")
|
|
elif t['text'].startswith("/endjoin"):
|
|
if t['from']['id'] == g.adminid:
|
|
g.endjoin()
|