import json import time import os import random import sys from datetime import datetime, timedelta # --- CONSTANTES & CONFIG --- FICHIER_SAUVEGARDE = "tamagotchi_2026.json" VITESSE_TEMPS = 1.0 # Multiplicateur de vitesse class Couleurs: RESET = "\033[0m" ROUGE = "\033[91m" VERT = "\033[92m" JAUNE = "\033[93m" BLEU = "\033[94m" MAGENTA = "\033[95m" CYAN = "\033[96m" BLANC = "\033[97m" GRAS = "\033[1m" FOND_BLEU = "\033[44m" def cls(): os.system('cls' if os.name == 'nt' else 'clear') # --- ART ASCII & ASSETS --- SPRITES = { "Oeuf": [" ( ) ", " ( ? ) ", " (___) "], "Enfant": [" ( o.o ) ", " / ( ) \ ", " | | "], "Adulte": [" / ( ^_^ ) \ ", "| ( ) |", " \ | | / "], "Sage": [" ,___, ", " ( -.- ) ", " / {___} \ ", " d b "], "Mort": [" ( x_x ) ", " /|RIP|\\ ", " /_|___|_\\ "], "Fantome": [" ( . . ) ", " ( ~ ) ", " ( v v ) "] } METEO_ICON = {"Soleil": "☀️", "Pluie": "🌧️", "Nuageux": "☁️", "Orage": "⛈️"} # --- MOTEUR DE JEU --- class TamagotchiUltime: def __init__(self): # Données de base self.nom = "Inconnu" self.date_naissance = time.time() self.dernier_login = time.time() # Stats vitales (0-100) self.faim = 100 self.energie = 100 self.bonheur = 100 self.hygiene = 100 self.sante = 100 # Progression self.xp = 0 self.niveau = 1 self.argent = 100 self.stade = "Oeuf" self.metier = "Chômeur" # Environnement self.meteo_actuelle = "Soleil" self.notifications = [] self.inventaire = {"Burger": 2, "Sushi": 1, "Potion": 1, "Café": 0} self.vivant = True def log(self, message): """Ajoute un message au journal.""" heure = datetime.now().strftime("%H:%M") self.notifications.append(f"[{heure}] {message}") if len(self.notifications) > 5: self.notifications.pop(0) def calculer_temps_ecoule(self): """Calcule ce qui s'est passé pendant l'absence du joueur (AFK).""" maintenant = time.time() delta_sec = maintenant - self.dernier_login if delta_sec > 60: # Si absent plus d'une minute minutes = int(delta_sec / 60) heures = int(minutes / 60) # Décroissance des stats selon le temps perte_faim = min(100, int(minutes * 0.5)) # -0.5% par minute perte_energie = min(100, int(minutes * 0.2)) perte_hygiene = min(100, int(minutes * 0.3)) self.faim -= perte_faim self.energie -= perte_energie self.hygiene -= perte_hygiene self.log(f"{Couleurs.JAUNE}Pendant ton absence ({minutes}m) : -{perte_faim}% Faim, -{perte_energie}% Énergie.{Couleurs.RESET}") # Conséquences graves if self.faim <= 0: self.sante -= 20 self.log(f"{Couleurs.ROUGE}Il a souffert de la faim !{Couleurs.RESET}") self.dernier_login = maintenant self.verifier_etat() def verifier_etat(self): """Vérifie la vie, l'évolution et les bornes.""" # Bornes self.faim = max(0, min(100, self.faim)) self.energie = max(0, min(100, self.energie)) self.bonheur = max(0, min(100, self.bonheur)) self.hygiene = max(0, min(100, self.hygiene)) self.sante = max(0, min(100, self.sante)) # Mort if self.sante <= 0: self.vivant = False self.stade = "Fantome" # Evolution if self.vivant: age_jours = (time.time() - self.date_naissance) / 86400 # En vrai jours # Pour la démo, on accélère : on se base sur l'XP if self.xp < 50: self.stade = "Oeuf" elif self.xp < 200: self.stade = "Enfant" elif self.xp < 600: self.stade = "Adulte" else: self.stade = "Sage" def changer_meteo(self): """Météo aléatoire.""" types = ["Soleil", "Pluie", "Nuageux", "Orage"] weights = [0.4, 0.3, 0.2, 0.1] self.meteo_actuelle = random.choices(types, weights)[0] msg = f"La météo change : {METEO_ICON[self.meteo_actuelle]} {self.meteo_actuelle}" if self.meteo_actuelle == "Pluie": self.bonheur -= 5 msg += " (Bonheur -5)" elif self.meteo_actuelle == "Soleil": self.bonheur += 5 msg += " (Bonheur +5)" self.log(msg) def sauvegarder(self): self.dernier_login = time.time() data = self.__dict__.copy() try: with open(FICHIER_SAUVEGARDE, 'w') as f: json.dump(data, f, indent=4) except Exception as e: print(f"Erreur de sauvegarde : {e}") def charger(self): if os.path.exists(FICHIER_SAUVEGARDE): try: with open(FICHIER_SAUVEGARDE, 'r') as f: data = json.load(f) self.__dict__.update(data) return True except: return False return False # --- RENDU GRAPHIQUE --- def barre(self, valeur, couleur): blocs = int(valeur / 10) style = f"{couleur}" if valeur < 25: style = f"{Couleurs.ROUGE}{Couleurs.GRAS}" return f"{style}[" + "█" * blocs + "░" * (10 - blocs) + f"] {int(valeur)}%{Couleurs.RESET}" def afficher_interface(self): cls() # Header print(f"{Couleurs.FOND_BLEU}{Couleurs.BLANC} 🌟 TAMAGOTCHI ULTIMATE 2026 🌟 {Couleurs.RESET}") # Info Panel age_reel = int((time.time() - self.date_naissance) / 3600) # En heures print(f"\n📍 {Couleurs.CYAN}Nom :{Couleurs.RESET} {self.nom:<10} | {Couleurs.JAUNE}Niv :{Couleurs.RESET} {self.niveau} (XP: {self.xp})") print(f"💼 {Couleurs.MAGENTA}Job :{Couleurs.RESET} {self.metier:<10} | 💰 {Couleurs.JAUNE}Crédits :{Couleurs.RESET} {self.argent}") print(f"🌍 {Couleurs.BLEU}Météo :{Couleurs.RESET} {METEO_ICON.get(self.meteo_actuelle, '')} | ⏳ {Couleurs.GRAS}Age :{Couleurs.RESET} {age_reel}h") print(f"\n{Couleurs.GRAS}--- ÉTAT ---{Couleurs.RESET}") print(f"🍖 Faim : {self.barre(self.faim, Couleurs.VERT)}") print(f"⚡ Énergie : {self.barre(self.energie, Couleurs.JAUNE)}") print(f"❤️ Bonheur : {self.barre(self.bonheur, Couleurs.MAGENTA)}") print(f"🧼 Hygiène : {self.barre(self.hygiene, Couleurs.CYAN)}") print(f"🏥 Santé : {self.barre(self.sante, Couleurs.ROUGE if self.sante < 50 else Couleurs.VERT)}") # Sprite Zone print(f"\n{Couleurs.GRAS}--- VISUEL ({self.stade}) ---{Couleurs.RESET}") visage = SPRITES.get(self.stade, SPRITES["Oeuf"]) if not self.vivant: visage = SPRITES["Mort"] color_sprite = Couleurs.BLANC if self.malade(): color_sprite = Couleurs.VERT for ligne in visage: print(f"\t\t{color_sprite}{ligne}{Couleurs.RESET}") # Notifications Log print(f"\n{Couleurs.GRAS}--- JOURNAL ---{Couleurs.RESET}") for notif in self.notifications: print(f" > {notif}") def malade(self): return self.sante < 40 or self.hygiene < 20 # --- ACTIONS UTILISATEUR --- def menu_principal(self): while True: self.afficher_interface() if not self.vivant: print(f"\n{Couleurs.ROUGE}☠️ {self.nom} est décédé. Paix à son âme.{Couleurs.RESET}") print("1. Réinitialiser (Nouvel oeuf)") print("2. Quitter") c = input(">>> ") if c == '1': os.remove(FICHIER_SAUVEGARDE) return False # Relance le jeu elif c == '2': sys.exit() print(f"\n{Couleurs.CYAN}Actions :{Couleurs.RESET}") print("1. 🍔 Nourrir 2. 🚿 Laver") print("3. 💊 Soigner 4. 🎮 Jouer") print("5. 💼 Travailler 6. 🏪 Boutique") print("7. 💤 Dormir 8. ❌ Quitter") choix = input(f"\n{Couleurs.GRAS}Ton choix ? {Couleurs.RESET}") # Traitement self.traitement_tour() # Le temps passe un peu à chaque action if choix == '1': self.action_manger() elif choix == '2': self.action_laver() elif choix == '3': self.action_soigner() elif choix == '4': self.action_jouer() elif choix == '5': self.action_travailler() elif choix == '6': self.action_boutique() elif choix == '7': self.action_dormir() elif choix == '8': self.sauvegarder() print("Sauvegarde effectuée. À bientôt !") sys.exit() self.sauvegarder() def traitement_tour(self): """Applique les effets passifs d'un tour de jeu.""" self.faim -= 5 self.energie -= 3 self.hygiene -= 4 if random.random() < 0.1: self.changer_meteo() # Gain XP passif self.xp += 2 if self.xp > self.niveau * 100: self.niveau += 1 self.log(f"🎉 NIVEAU UP ! Niveau {self.niveau} atteint !") self.verifier_etat() # --- DÉTAILS DES ACTIONS --- def action_manger(self): print("\n=== INVENTAIRE ===") dispo = [k for k,v in self.inventaire.items() if v > 0] if not dispo: print("Inventaire vide !") time.sleep(1) return for i, item in enumerate(dispo): print(f"{i+1}. {item} (Qté: {self.inventaire[item]})") ch = input("Manger quoi ? (Entrée pour annuler) : ") if ch.isdigit() and 0 < int(ch) <= len(dispo): item = dispo[int(ch)-1] self.inventaire[item] -= 1 self.faim += 30 self.energie += 5 self.log(f"Miam ! {item} mangé.") if item == "Café": self.energie += 40 def action_laver(self): self.log("Frotte frotte frotte...") time.sleep(1) self.hygiene = 100 self.bonheur += 10 self.log("Tout propre !") def action_soigner(self): if self.inventaire["Potion"] > 0: self.inventaire["Potion"] -= 1 self.sante = 100 self.maladie = False self.log("Santé restaurée !") else: self.log("Pas de potion ! Va à la boutique.") time.sleep(1) def action_jouer(self): if self.energie < 20: self.log("Trop fatigué pour jouer.") return # Mini jeu Math a, b = random.randint(2, 12), random.randint(2, 12) ans = input(f"Mini-Jeu : Combien font {a} x {b} ? ") if ans == str(a*b): gain = 20 self.argent += gain self.bonheur += 20 self.xp += 15 self.log(f"Bravo ! Gagné {gain} crédits.") else: self.bonheur -= 5 self.log("Raté...") self.energie -= 15 def action_travailler(self): if self.stade in ["Oeuf", "Enfant"]: self.log("Trop jeune pour travailler !") time.sleep(1) return if self.energie < 30: self.log("Trop fatigué pour travailler.") return jobs = { "Serveur": {"gain": 30, "xp": 10}, "Développeur": {"gain": 60, "xp": 25}, "Médecin": {"gain": 100, "xp": 40} } # Déblocage métier selon niveau job_dispo = "Serveur" if self.niveau >= 5: job_dispo = "Développeur" if self.niveau >= 10: job_dispo = "Médecin" self.metier = job_dispo print(f"\nTu travailles comme {job_dispo}...") time.sleep(1.5) # Barre de chargement simulée salaire = jobs[job_dispo]["gain"] self.argent += salaire self.xp += jobs[job_dispo]["xp"] self.energie -= 30 self.faim -= 20 self.bonheur -= 10 self.log(f"Travail fini. Gagné {salaire} crédits.") def action_boutique(self): cls() print(f"💰 Tes crédits : {self.argent}") items = { "1": ("Burger", 20, 30), # Nom, Prix, Faim "2": ("Sushi", 50, 40), "3": ("Café", 15, 5), "4": ("Potion", 100, 0) } print("1. Burger (20$) - Nourriture de base") print("2. Sushi (50$) - Nourriture luxe") print("3. Café (15$) - Boost Energie") print("4. Potion (100$) - Soin complet") print("Q. Quitter") c = input("Choix : ") if c in items: nom, prix, _ = items[c] if self.argent >= prix: self.argent -= prix self.inventaire[nom] = self.inventaire.get(nom, 0) + 1 self.log(f"Acheté : {nom}") else: self.log("Pas assez d'argent !") time.sleep(1) def action_dormir(self): self.log("Bonne nuit...") self.energie = 100 self.faim -= 10 self.sauvegarder() time.sleep(2) self.log("Réveil en pleine forme !") # --- LANCEMENT --- if __name__ == "__main__": while True: game = TamagotchiUltime() if not game.charger(): cls() print(f"{Couleurs.VERT}=== NOUVEAU TAMAGOTCHI 2026 ==={Couleurs.RESET}") game.nom = input("Nom de la créature : ") or "Blob" game.log(f"{game.nom} est né !") else: game.calculer_temps_ecoule() restart = game.menu_principal() if restart is not False: break