commit 78a49bec882a2144a7be1a80e164e14de4ec69d4 Author: 7ka1 <7ka1@noreply.localhost> Date: Tue Feb 17 15:14:15 2026 +0000 Téléverser les fichiers vers "/" diff --git a/Tamagochi.py b/Tamagochi.py new file mode 100644 index 0000000..24fdd22 --- /dev/null +++ b/Tamagochi.py @@ -0,0 +1,404 @@ +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