1
0

Compare commits

...

6 Commits

Author SHA256 Message Date
andrea
308c9e3602 use internal method to get the player's gender 2025-07-26 15:36:22 +02:00
andrea
871b3d2ab1 fix player random extraction number 2025-07-26 15:35:45 +02:00
andrea
5f0d6ad3f5 fix bug where a death player is killed multiple time during the same day 2025-07-26 15:31:28 +02:00
andrea
551c2ef8ef cleans 2025-07-26 15:25:27 +02:00
andrea
4ce19d1a50 add kills counter random agility for each player and random init players 2025-07-26 15:20:03 +02:00
andrea
67804a394d split main bot lib into multiple smaller libs and improve end game message 2025-07-26 14:44:16 +02:00
8 changed files with 152 additions and 100 deletions

92
bot.py
View File

@@ -4,70 +4,32 @@ from telegram.ext import MessageHandler
from telegram.ext import filters from telegram.ext import filters
from telegram import ReplyKeyboardMarkup from telegram import ReplyKeyboardMarkup
from telegram import ReplyKeyboardRemove from telegram import ReplyKeyboardRemove
import main as _brsim import main as _brsim
import debug as _dbg
from bot_libs import player_handling as _bot_player from bot_libs import player_handling as _bot_player
from bot_libs import simulation as _bot_sim
from bot_libs import repeating as _bot_repeat
from bot_libs import syms as _botsyms from bot_libs import syms as _botsyms
async def simulate_day(context, chat_id):
if 'arena' in context.application.bot_data:
Arena= context.application.bot_data['arena']
if len(Arena.get_alive_players()) == 1:
winner= Arena.get_alive_players()[0]
try:
context.job.schedule_removal()
print(f'simulate_day: Loop removed')
except: pass
msg= f'{winner.get_name()} Vince la cruenta battaglia, e vive felice e contento con Guarino'
return await context.bot.send_message(chat_id, msg)
print(f'{chat_id}: Guarino ha trovato l\'arena')
await context.bot.send_message(chat_id, f'Giorno #{Arena.day}')
msg= _dbg.play_one_day_debug(Arena)
await context.bot.send_message(chat_id, msg)
else:
print('Arena non trovata')
await context.bot.send_message(chat_id, 'Che e\' successo? un Guarino ha rubato l\'arena, avvia una nuova partita con /start')
async def loop_game(context):
chat_id = context.job.chat_id
print(f'loop_game: run on {chat_id}')
return await simulate_day(context, chat_id)
async def bot_start(update, context): async def bot_start(update, context):
await update.message.reply_text(_botsyms.START_MSG) await update.message.reply_text(_botsyms.START_MSG)
keyboard = [ keyboard = [
['Init/Restart'], ['Init/Restart'],
['Add Player'], ['Add Player', 'Add random Players', 'Add random color Players'],
['Get Players', 'Get Alive Players', 'Get Death Players'], ['Get Players', 'Get Alive Players', 'Get Death Players'],
['Simulate Day', 'Run Periodically'] ['Simulate Day', 'Run Periodically']
] ]
reply_markup= ReplyKeyboardMarkup(keyboard, one_time_keyboard=False, resize_keyboard=True) reply_markup= ReplyKeyboardMarkup(keyboard, one_time_keyboard=False, resize_keyboard=True)
chat_id = update.effective_chat.id chat_id = update.effective_chat.id
print(f'{chat_id}: Sto costruendo il mondo di gioco...') print(f'{chat_id}: I\'m building the world\'s game...')
Arena= _brsim.init_arena() Arena= _brsim.init_arena()
await update.message.reply_text('Ho creato il mondo di gioco', reply_markup=reply_markup) await update.message.reply_text('Ho creato il mondo di gioco', reply_markup=reply_markup)
context.application.bot_data['arena'] = Arena context.application.bot_data['arena'] = Arena
async def start_loop_game(update, context, seconds):
await update.message.reply_text(f'Ok capo!! giochero\' per te ogni {seconds}s')
chat_id = update.effective_chat.id
if 'arena' not in context.application.bot_data:
print(f'{chat_id}: Arena non trovata')
await update.message.reply_text(f'Arena non trovata, avviare con /start')
return
Arena= context.application.bot_data['arena']
if len(Arena.get_players()) < 2:
print(f'{chat_id}: Guarino pretende che ci siano almeno 2 giocatori')
await update.message.reply_text(f'Servono almeno 2 giocatori. Ecco i giocatori presenti nel mondo do gioco: \n{Arena.get_players()}')
return
context.job_queue.run_repeating(loop_game, interval= seconds, first=1, chat_id= chat_id)
print(f'Job giornaliero creato per la chat {chat_id}')
async def bot_commands(update, context): async def bot_commands(update, context):
text= update.message.text text= update.message.text
chat_id = update.effective_chat.id chat_id = update.effective_chat.id
@@ -93,14 +55,31 @@ async def bot_commands(update, context):
return await _bot_player.get_death_players(update, context) return await _bot_player.get_death_players(update, context)
if text == 'Simulate Day': if text == 'Simulate Day':
print(f'bot_command: {chat_id} Simulate Day') print(f'bot_command: {chat_id} Simulate Day')
return await simulate_day(context, chat_id) return await _bot_sim.simulate_day(context, chat_id)
if text == 'Run Periodically': if text == 'Run Periodically':
print(f'bot_command: {chat_id} Run Periodically') print(f'bot_command: {chat_id} Run Periodically')
context.application.bot_data['ask_seconds'] = 1 context.application.bot_data['ask_seconds'] = 1
if 'ask_name' in context.application.bot_data: if 'ask_name' in context.application.bot_data:
del(context.application.bot_data['ask_name']) del(context.application.bot_data['ask_name'])
return await update.message.reply_text('Inserisci il numero di secondi, ad esempio \n(60 = 1 minuto)(600 = 10 minuti)\n(3600 = 1 ora)\n(86400 = 1 giorno)') return await update.message.reply_text('Inserisci il numero di secondi, ad esempio \n(60 = 1 minuto)(600 = 10 minuti)\n(3600 = 1 ora)\n(86400 = 1 giorno)')
#return await simulate_day(context, chat_id)
waiting_for_name= context.application.bot_data.get('ask_name')
if waiting_for_name or text in ['Add random Players', 'Add random color Players']:
print(f'bot_command: {chat_id} Collected Player Name {text}')
if 'ask_name' in context.application.bot_data:
del(context.application.bot_data['ask_name'])
players= text.split(',')
for player in players:
await _bot_player.add_player(update, context, player.strip())
elif text == 'Add random Players':
await _bot_player.add_random_players(update, context, colors_names= False)
elif text == 'Add random color Players':
await _bot_player.add_random_players(update, context, colors_names= True)
Arena= context.application.bot_data['arena']
players= [p.get_name() for p in Arena.get_players()]
players_str= '\n'.join(players)
return await update.message.reply_text(f'Ecco i {len(players)} giocatori presenti nel mondo do gioco: \n{players_str}')
waiting_for_seconds= context.application.bot_data.get('ask_seconds') waiting_for_seconds= context.application.bot_data.get('ask_seconds')
if waiting_for_seconds: if waiting_for_seconds:
@@ -108,35 +87,18 @@ async def bot_commands(update, context):
try: text= int(text) try: text= int(text)
except: return except: return
seconds= max(1, text) seconds= max(1, text)
return await start_loop_game(update, context, seconds) return await _bot_repeat.start_loop_game(update, context, seconds)
waiting_for_name= context.application.bot_data.get('ask_name') print(f'bot_command: {chat_id} sent this text: {text}')
if waiting_for_name:
print(f'bot_command: {chat_id} Collected Player Name {text}')
del(context.application.bot_data['ask_name'])
players= text.split(',')
for player in players:
await _bot_player.add_player(update, context, player.strip())
return
print(f'{chat_id} ha inviato questo testo: {text}')
await update.message.reply_text(_botsyms.WIP_MSG) await update.message.reply_text(_botsyms.WIP_MSG)
def main(): def main():
application = Application.builder().token(_botsyms.TOKEN).build() application = Application.builder().token(_botsyms.TOKEN).build()
application.add_handler(CommandHandler('start', bot_start)) application.add_handler(CommandHandler('start', bot_start))
#application.add_handler(CommandHandler('start_game', start_loop_game))
# player handler
#application.add_handler(CommandHandler('add_player', _bot_player.add_player))
#application.add_handler(CommandHandler('get_players', _bot_player.get_players))
#application.add_handler(CommandHandler('get_alive_players', _bot_player.get_alive_players))
#application.add_handler(CommandHandler('get_death_players', _bot_player.get_death_players))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, bot_commands)) application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, bot_commands))
print('Bot in esecuzione...') print('Bot is running...')
application.run_polling() application.run_polling()
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -1,29 +1,41 @@
import random as _rand
from bot_libs import syms as _bot_syms
async def add_player(update, context, name): async def add_player(update, context, name):
#name= " ".join(context.args)
print(f'add_player: {name}') print(f'add_player: {name}')
Arena= context.application.bot_data['arena'] Arena= context.application.bot_data['arena']
Arena.add_player(name) Arena.add_player(name)
players= [p.get_name() for p in Arena.get_players()]
players_str= '\n'.join(players) async def add_random_players(update, context, colors_names= False):
await update.message.reply_text(f'Ecco i giocatori presenti nel mondo do gioco: \n{players_str}') if colors_names: names= _bot_syms.COLORS_NAMES
else: names= _bot_syms.RANDOM_NAMES
max_players= len(names)
min_players= min(7, max_players)
players_num= _rand.randint(min_players, max_players)
_rand.shuffle(names)
lucky_players= _rand.sample(names, players_num)
print(f'add_random_players: extracting {players_num} random players for the game')
for name in lucky_players: await add_player(update, context, name)
async def get_players(update, context): async def get_players(update, context):
Arena= context.application.bot_data['arena'] Arena= context.application.bot_data['arena']
print(f'get_players: {Arena.get_players()}')
players= [p.get_name() for p in Arena.get_players()] players= [p.get_name() for p in Arena.get_players()]
players_str= '\n'.join(players) players_str= '\n'.join(players)
print(f'get_players: {players_str}')
await update.message.reply_text(f'Ecco i giocatori presenti nel mondo do gioco: \n{players_str}') await update.message.reply_text(f'Ecco i giocatori presenti nel mondo do gioco: \n{players_str}')
async def get_alive_players(update, context): async def get_alive_players(update, context):
Arena= context.application.bot_data['arena'] Arena= context.application.bot_data['arena']
print(f'get_alive_players: {Arena.get_alive_players()}')
alive= [a.get_name() for a in Arena.get_alive_players()] alive= [a.get_name() for a in Arena.get_alive_players()]
alive_str= '\n'.join(alive) alive_str= '\n'.join(alive)
print(f'get_alive_players: {alive_str}')
await update.message.reply_text(f'Ecco i giocatori ancora vivi: \n{alive_str}') await update.message.reply_text(f'Ecco i giocatori ancora vivi: \n{alive_str}')
async def get_death_players(update, context): async def get_death_players(update, context):
Arena= context.application.bot_data['arena'] Arena= context.application.bot_data['arena']
print(f'get_death_players: {Arena.get_death_players()}')
death= [d.get_name() for d in Arena.get_death_players()] death= [d.get_name() for d in Arena.get_death_players()]
death_str= '\n'.join(death) death_str= '\n'.join(death)
print(f'get_death_players: {death_str}')
await update.message.reply_text(f'Ecco i giocatori morti x.x: \n{death_str}') await update.message.reply_text(f'Ecco i giocatori morti x.x: \n{death_str}')

23
bot_libs/repeating.py Normal file
View File

@@ -0,0 +1,23 @@
from bot_libs import simulation as _bot_sim
async def _loop_game(context):
chat_id = context.job.chat_id
print(f'_loop_game: run on {chat_id}')
return await _bot_sim.simulate_day(context, chat_id)
async def start_loop_game(update, context, seconds):
await update.message.reply_text(f'Ok capo!! giochero\' per te ogni {seconds}s')
chat_id = update.effective_chat.id
if 'arena' not in context.application.bot_data:
print(f'start_loop_game: {chat_id} Arena not found')
await update.message.reply_text(f'Arena non trovata, avviare con /start')
return
Arena= context.application.bot_data['arena']
if len(Arena.get_players()) < 2:
print(f'start_loop_game: {chat_id} Not enough player to start the match')
await update.message.reply_text(f'Servono almeno 2 giocatori. Ecco i giocatori presenti nel mondo do gioco: \n{Arena.get_players()}')
return
context.job_queue.run_repeating(_loop_game, interval= seconds, first=1, chat_id= chat_id)
print(f'start_loop_game: Repeating Job created for: {chat_id}')

32
bot_libs/simulation.py Normal file
View File

@@ -0,0 +1,32 @@
import debug as _dbg
def get_winner(Arena):
winner= Arena.get_alive_players()[0]
try:
context.job.schedule_removal()
print(f'simulate_day: Loop removed')
except: pass
day= Arena.day
if winner.player_gender_is_male():
msg= f'{winner.get_name()} Vince la cruenta battaglia uccidendo {winner.get_kills()} giocatori, e vive felice e contento con Guarino'
elif winner.player_gender_is_female():
msg= f'{winner.get_name()} Vince la cruenta battaglia uccidendo {winner.get_kills()} giocatori, e vive felice e contenta con Guarino'
else:
msg= f'{winner.get_name()} Vince la cruenta battaglia uccidendo {winner.get_kills()} giocatori, e vive felice e content# con Guarino'
return msg
async def simulate_day(context, chat_id):
if 'arena' not in context.application.bot_data:
print('Arena not Found')
await context.bot.send_message(chat_id, 'Che e\' successo? un Guarino ha rubato l\'arena, avvia una nuova partita con /start')
return
Arena= context.application.bot_data['arena']
if len(Arena.get_alive_players()) <= 1: return await context.bot.send_message(chat_id, 'Il gioco e\' finito, Grazie per aver giocato!')
await context.bot.send_message(chat_id, f'Giorno #{Arena.day}')
msg= _dbg.play_one_day_debug(Arena)
await context.bot.send_message(chat_id, msg)
if len(Arena.get_alive_players()) == 1:
msg= get_winner(Arena)
return await context.bot.send_message(chat_id, msg)

View File

@@ -11,3 +11,30 @@ Uccidi o sarai tu ad essere ucciso
""" """
WIP_MSG= "Ehi, mio padre mi sta ancora finendo di creare, abbi pazienza, che fretta hai di entrare in questo mondo per morire?" WIP_MSG= "Ehi, mio padre mi sta ancora finendo di creare, abbi pazienza, che fretta hai di entrare in questo mondo per morire?"
RANDOM_NAMES = [
"Aeliana", "Thorne", "Kael", "Seraphine", "Jaxon", "Lyra", "Darius", "Elowen",
"Zander", "Nyssa", "Orion", "Vesper", "Kieran", "Isolde", "Riven", "Calista",
"Draven", "Mira", "Zephyr", "Selene", "Ashen", "Talia", "Finnian", "Aria",
"Kaelan", "Liora", "Soren", "Elara", "Thalia", "Jett", "Cressida", "Lucian",
"Freya", "Ronan", "Niamh", "Kellan", "Zara", "Dorian", "Amara", "Jace",
"Elysia", "Caius", "Sable", "Alaric", "Veda", "Quinn", "Thorne", "Lirael",
"Rhea", "Kade", "Isadora", "Ash", "Nyx", "Cassian", "Elowen", "Tamsin",
"Rylan", "Faye", "Jorah", "Sienna", "Kieran", "Astra", "Zane", "Lyric",
"Dax", "Ember", "Orion", "Selah", "Juno", "Kaia", "Thorne", "Vespera",
"Riven", "Caden", "Liora", "Soren", "Elara", "Talia", "Jett", "Freya",
"Ronan", "Niamh", "Kellan", "Zara", "Dorian", "Amara", "Jace", "Elysia",
"Caius", "Sable", "Alaric", "Veda", "Quinn", "Thorne", "Lirael", "Rhea",
"Kade", "Isadora", "Ash", "Nyx",
]
COLORS_NAMES= [
"Yellow", "Grey", "Violet", "Black", "Lime", "Ruby", "Avocado", "Crystal",
"Pink", "Maize", "Coral", "Jade", "Platinum", "Emerald", "Carmine", "Nickel",
"Chocolate", "Slate", "Turquoise", "Silver", "Teal", "Jet", "Ivory", "Cobalt",
"Vermillion", "Aero", "Orange", "Rhythm", "Amber", "Olive", "Sepia", "Cyan",
"Green", "Ochre", "Denim", "Erin", "Fuchsia", "Aqua", "Iceberg", "Blue",
"Canary", "Red", "Mint", "Scarlet", "Coffee", "Indigo", "Mystic", "Rose",
"Pearl", "Pumpkin", "Navy", "Ultramarine", "Sapphire", "Desert", "Cherry",
"Tulip",
]

View File

@@ -48,10 +48,10 @@ def play_one_day_debug(Arena):
daily_events= [] daily_events= []
_rand.shuffle(alive_players) _rand.shuffle(alive_players)
for p_one in alive_players: for p_one in alive_players:
if not p_one.is_alive(): continue #he could be dead during this day cycle if not p_one.is_alive(): continue # he could be dead during this day cycle
p_two= _rand.sample(alive_players, 1)[0] p_two= _rand.sample(Arena.get_alive_players(), 1)[0]
while p_one.get_id() == p_two.get_id(): while p_one.get_id() == p_two.get_id():
p_two= _rand.sample(alive_players, 1)[0] p_two= _rand.sample(Arena.get_alive_players(), 1)[0]
_dmg, msg= p_one.attack(p_two) _dmg, msg= p_one.attack(p_two)
daily_events.append(msg) daily_events.append(msg)

View File

@@ -10,7 +10,7 @@ class BrSimPlayer():
self.inventory= inventory or [] self.inventory= inventory or []
self.damage= 1 # this is the punch damage amount self.damage= 1 # this is the punch damage amount
self.max_weight= 5 # this is the max inventory weight self.max_weight= 5 # this is the max inventory weight
self.agility= 10 # chance to avoid an hit self.agility= _random.randint(5,30) # chance to avoid an hit
self.kills= 0 # track the number of kills self.kills= 0 # track the number of kills
self.survived_days= 0 # track the number of the survived days self.survived_days= 0 # track the number of the survived days
self.equipped_weapon= None self.equipped_weapon= None
@@ -28,6 +28,15 @@ class BrSimPlayer():
def get_gender(self): def get_gender(self):
return self.gender return self.gender
def player_gender_is_male(self):
return self.gender == 'm'
def player_gender_is_female(self):
return self.gender == 'f'
def player_gender_is_not_binary(self):
return self.gender == '-'
def get_inventory(self): def get_inventory(self):
return self.inventory return self.inventory
@@ -69,6 +78,9 @@ class BrSimPlayer():
def is_alive(self): def is_alive(self):
return self.health > 0 return self.health > 0
def get_kills(self):
return self.kills
### player actions ### player actions
def _equip_weapon(self): def _equip_weapon(self):
@@ -94,9 +106,9 @@ class BrSimPlayer():
if self.health > 0: return self.get_health() if self.health > 0: return self.get_health()
self.health = 0 self.health = 0
if self.get_gender() == 'm': if self.player_gender_is_male():
print(f'[{self.get_name()}]: Guarino, perdonami se sono morto x.x') print(f'[{self.get_name()}]: Guarino, perdonami se sono morto x.x')
elif self.get_gender() == 'f': elif self.player_gender_is_female():
print(f'[{self.get_name()}]: Guarino, perdonami se sono morta x.x') print(f'[{self.get_name()}]: Guarino, perdonami se sono morta x.x')
else: else:
print(f'[{self.get_name()}]: Guarino, perdonami se sono mort* x.x') print(f'[{self.get_name()}]: Guarino, perdonami se sono mort* x.x')
@@ -105,22 +117,23 @@ class BrSimPlayer():
def attack(self, target): def attack(self, target):
self._equip_weapon() self._equip_weapon()
if target.dodge(): if target.dodge():
if target.get_gender() == 'm': if target.player_gender_is_male():
msg= f'Ehhhh voleviiii!!! sei lentoo! {target.get_name()} schiva il colpo di {self.get_name()}' msg= f'Ehhhh voleviiii!!! sei lentoo! {target.get_name()} schiva il colpo di {self.get_name()}'
elif target.get_gender() == 'f': elif target.player_gender_is_female():
msg= f'Ehhhh voleviiii!!! sei lentaa! {target.get_name()} schiva il colpo di {self.get_name()}' msg= f'Ehhhh voleviiii!!! sei lentaa! {target.get_name()} schiva il colpo di {self.get_name()}'
else: else:
msg= f'Ehhhh voleviiii!!! sei lent##! {target.get_name()} schiva il colpo di {self.get_name()}' msg= f'Ehhhh voleviiii!!! sei lent##! {target.get_name()} schiva il colpo di {self.get_name()}'
return 0, msg return 0, msg
target.accuses_damage(self.damage) target.accuses_damage(self.damage)
msg= f'{self.get_name()} Colpisce {target.get_name()} in nome di Guarino' msg= f'{self.get_name()} Colpisce {target.get_name()}'
self.kills+= 1
return self.damage, msg return self.damage, msg
def get_item(self, item): def get_item(self, item):
if self.get_inventory_weight() + item.get_weight() >= self.get_max_weight(): if self.get_inventory_weight() + item.get_weight() >= self.get_max_weight():
if self.get_gender() == 'm': if self.player_gender_is_male():
print(f'Sono sovraccarico, {self.get_name} non puo\' prendere questo oggetto') print(f'Sono sovraccarico, {self.get_name} non puo\' prendere questo oggetto')
elif self.get_gender() == 'f': elif self.player_gender_is_female():
print(f'Sono sovraccarica, {self.get_name} non puo\' prendere questo oggetto') print(f'Sono sovraccarica, {self.get_name} non puo\' prendere questo oggetto')
else: else:
print(f'Sono sovraccaric#, {self.get_name} non puo\' prendere questo oggetto') print(f'Sono sovraccaric#, {self.get_name} non puo\' prendere questo oggetto')

17
main.py
View File

@@ -8,20 +8,3 @@ def init_arena(players= None, weapons= None):
def run_events(Arena): def run_events(Arena):
#A event for each player: #A event for each player:
pass pass
def local_debug():
players= [{'name': 'Crystal'}, {'name': 'Andrea'}, {'name' : 'giampi'}]
w= _wsyms.KNIFE
#weapons= [{_wsyms.WEAPONS[w]['name' ]: 1}]
weapons= [{w: 1}]
Arena= init_arena(players, weapons)
print(f'Players: {Arena.get_players()}')
print(f'Weapons: {Arena.get_weapons()}')
while (len(Arena.get_alive_players()) > 1):
#Start a day
run_events(Arena)
#At 23:59:
Arena.next_day()
#End of day