import json import random import datetime # Fonction pour afficher l'état actuel du jeu def afficher_etat(etat_jeu): print("\nVoici l'état actuel des tas :") for i, nb_objets in enumerate(etat_jeu): print(f"Tas {i+1}: {nb_objets} objets") print() # Fonction pour calculer le Nim-sum (ou exclusif XOR de tous les tas) def calculer_nim_sum(etat_jeu): nim_sum = 0 for nb_objets in etat_jeu: nim_sum ^= nb_objets return nim_sum # Fonction pour appliquer un mouvement à l'état def appliquer_mouvement(etat_jeu, tas_index, nb_objets): if 1 <= nb_objets <= etat_jeu[tas_index]: etat_jeu[tas_index] -= nb_objets return etat_jeu else: raise ValueError("Mouvement invalide") # Fonction pour vérifier si l'état est final (tous les tas sont vides) def est_etat_final(etat_jeu): return all(nb_objets == 0 for nb_objets in etat_jeu) # Heuristique Nim-Sum pour l'ordinateur def heuristique_nim_sum(etat_jeu): nim_sum = calculer_nim_sum(etat_jeu) if nim_sum == 0: # Si le Nim-sum est déjà 0, l'ordinateur fait un mouvement aléatoire tas_non_vide = [i for i, nb_objets in enumerate(etat_jeu) if nb_objets > 0] tas_choisi = random.choice(tas_non_vide) nb_objets = random.randint(1, etat_jeu[tas_choisi]) return tas_choisi, nb_objets else: # Si le Nim-sum est différent de 0, l'ordinateur essaie de rendre le Nim-sum égal à 0 for i, nb_objets in enumerate(etat_jeu): if nb_objets ^ nim_sum < nb_objets: nb_objets_a_prendre = nb_objets - (nb_objets ^ nim_sum) return i, nb_objets_a_prendre # Sauvegarder la partie dans un fichier json def sauvegarder_partie(historique, resultat): partie = { "date": str(datetime.datetime.now()), "historique": historique, "resultat": resultat } # Chargement du fichier JSON existant ou création s'il n'existe pas try: with open("historique_nim.json", "r") as fichier: sauvegardes = json.load(fichier) except FileNotFoundError: sauvegardes = [] # Ajouter la nouvelle partie à l'historique sauvegardes.append(partie) # Sauvegarde dans le fichier with open("historique_nim.json", "w") as fichier: json.dump(sauvegardes, fichier, indent=4) # Boucle principale pour jouer une partie def jeu_de_nim(tas_initial, mode="normal"): etat_jeu = tas_initial[:] joueur = 1 # 1 pour joueur humain, 2 pour ordinateur historique = [f"Tas initiaux: {etat_jeu}"] while not est_etat_final(etat_jeu): if joueur == 1: print("Tour du joueur :") afficher_etat(etat_jeu) tas_choisi = int(input("Choisissez un tas (numéro): ")) - 1 nb_objets = int(input(f"Combien d'objets voulez-vous prendre dans le tas {tas_choisi + 1}? ")) etat_jeu = appliquer_mouvement(etat_jeu, tas_choisi, nb_objets) historique.append(f"Joueur a pris {nb_objets} objets du tas {tas_choisi + 1}") else: print("Tour de l'ordinateur :") tas_choisi, nb_objets = heuristique_nim_sum(etat_jeu) etat_jeu = appliquer_mouvement(etat_jeu, tas_choisi, nb_objets) historique.append(f"Ordinateur a pris {nb_objets} objets du tas {tas_choisi + 1}") print(f"L'ordinateur a pris {nb_objets} objets du tas {tas_choisi + 1}.\n") joueur = 2 if joueur == 1 else 1 # Condition de victoire/perte if mode == "normal": if joueur == 2: print("Félicitations, vous avez gagné!") resultat = "Joueur a gagné" else: print("Dommage, l'ordinateur a gagné.") resultat = "Ordinateur a gagné" elif mode == "misere": if joueur == 2: print("L'ordinateur a perdu (version misère)!") resultat = "Ordinateur a perdu (misère)" else: print("Vous avez perdu (version misère).") resultat = "Joueur a perdu (misère)" # Sauvegarder la partie sauvegarder_partie(historique, resultat) # Lancement du jeu if __name__ == "__main__": tas_initial = [3, 4, 5] # Exemple de configuration initiale mode_de_jeu = input("Choisissez le mode de jeu (normal/misere) : ").strip().lower() if mode_de_jeu not in ["normal", "misere"]: mode_de_jeu = "normal" jeu_de_nim(tas_initial, mode_de_jeu)