import random # exo 1 def afficher_etat(etat_jeu): print("État du jeu:", etat_jeu) # exo 2 def generer_mouvements(etat_jeu): mouvements = [] for i in range(len(etat_jeu)): for j in range(1, etat_jeu[i] + 1): nouveau_etat = etat_jeu.copy() nouveau_etat[i] -= j mouvements.append(nouveau_etat) return mouvements # exo 3 def appliquer_mouvement(etat_jeu, tas_index, nb_objets): etat_jeu[tas_index] -= nb_objets return etat_jeu # exo 4 def heuristique(etat_jeu): return sum(etat_jeu) # Total des objets restants def heuristique_nim_sum(etat_jeu): nim_sum = 0 for tas in etat_jeu: nim_sum ^= tas # Calculer la somme de Nim (XOR) return nim_sum # Retourne le Nim-sum pour guider l'algorithme A* # exo 5 def est_etat_final(etat_jeu): return all(tas == 0 for tas in etat_jeu) def cout_mouvement(): return 1 #exo 6 class Noeud: def __init__(self, etat, parent=None, g=0, h=0): self.etat = etat # L'état actuel du jeu (tas d'objets) self.parent = parent # Le nœud précédent self.g = g # Coût réel du chemin jusqu'à ce nœud self.h = h # Heuristique (estimation du coût restant) self.f = g + h # Coût total (g + h) # Ajout de la méthode __lt__ pour comparer les nœuds def __lt__(self, autre): return self.f < autre.f # Comparer en fonction du coût total import heapq def algorithme_a_star(etat_initial): open_list = [] closed_list = set() # Ensemble pour stocker les états déjà visités # Ajouter l'état initial à la file de priorité heapq.heappush(open_list, Noeud(etat_initial, g=0, h=heuristique_nim_sum(etat_initial))) while open_list: # Extraire le nœud avec le plus petit coût total (g + h) current_node = heapq.heappop(open_list) # Si nous avons atteint l'état final, reconstruire le chemin if est_etat_final(current_node.etat): return reconstruire_chemin(current_node) # Ajouter l'état actuel dans la liste des états explorés closed_list.add(tuple(current_node.etat)) # Générer les mouvements possibles à partir de l'état actuel for mouvement in generer_mouvements(current_node.etat): # Si l'état résultant a déjà été visité, on l'ignore if tuple(mouvement) in closed_list: continue # Créer un nouveau nœud pour cet état nouveau_noeud = Noeud(mouvement, current_node, current_node.g + cout_mouvement(), heuristique_nim_sum(mouvement)) # Ajouter le nouveau nœud à la file de priorité heapq.heappush(open_list, nouveau_noeud) # exo 8 def reconstruire_chemin(noeud_final): chemin = [] noeud_courant = noeud_final while noeud_courant: # Tant qu'il y a un parent chemin.append(noeud_courant.etat) # Ajouter l'état actuel au chemin noeud_courant = noeud_courant.parent # Passer au nœud parent return chemin[::-1] # Inverser le chemin pour avoir de l'état initial à l'état final # exo 9 import json import os # Fonction pour écrire les résultats dans un fichier JSON def enregistrer_resultat(resultat): # Vérifier si le fichier JSON existe déjà if os.path.exists("resultats.json"): # Charger les résultats existants with open("resultats.json", "r") as fichier: try: resultats = json.load(fichier) except json.JSONDecodeError: resultats = [] # Si le fichier est vide ou corrompu else: resultats = [] # Ajouter le nouveau résultat resultats.append(resultat) # Sauvegarder les résultats mis à jour dans le fichier JSON with open("resultats.json", "w") as fichier: json.dump(resultats, fichier, indent=4) def jouer_contre_ia(): etat_jeu = [random.randint(1, 10) for _ in range(3)] etat_jeu_initial = etat_jeu.copy() historique_actions = [] # Liste pour enregistrer l'historique des actions while not est_etat_final(etat_jeu): # Tour de l'utilisateur afficher_etat(etat_jeu) """tas_index = int(input("Sélectionnez le tas (index) : ")) nb_objets = int(input("Combien d'objets retirer ? ")) if nb_objets > etat_jeu[tas_index]: print("Erreur : Vous ne pouvez pas retirer plus d'objets que ce qui est disponible.") continue # Appliquer le mouvement de l'utilisateur et ajouter à l'historique etat_jeu = appliquer_mouvement(etat_jeu, tas_index, nb_objets) historique_actions.append({ "joueur": "utilisateur", "tas": tas_index, "objets_retires": nb_objets, "etat_apres": etat_jeu.copy() # Copier l'état après le mouvement }) if est_etat_final(etat_jeu): print("Vous avez gagné !") enregistrer_resultat({"etat_jeu_initial": etat_jeu_initial, "gagnant": "utilisateur", "historique": historique_actions}) return""" # Tour de l'IA print("Tour de l'IA 1...") etat_jeu = algorithme_a_star(etat_jeu)[1] # IA applique A* et choisit le meilleur mouvement # Simuler une action de l'IA (ici c'est un exemple, tu devras remplacer cela par un vrai mouvement) historique_actions.append({ "joueur": "IA 1", "tas": 0, # Exemple de tas choisi par l'IA (à adapter) "objets_retires": 1, # Exemple d'objets retirés par l'IA (à adapter) "etat_apres": etat_jeu.copy() # Copier l'état après le mouvement }) afficher_etat(etat_jeu) if est_etat_final(etat_jeu): print("L'IA 1 a gagné !") enregistrer_resultat({"etat_jeu_initial": etat_jeu_initial, "gagnant": "IA 1", "historique": historique_actions}) return # Tour de l'IA print("Tour de l'IA 2...") etat_jeu = algorithme_a_star(etat_jeu)[1] # IA applique A* et choisit le meilleur mouvement # Simuler une action de l'IA (ici c'est un exemple, tu devras remplacer cela par un vrai mouvement) historique_actions.append({ "joueur": "IA 2", "tas": 0, # Exemple de tas choisi par l'IA (à adapter) "objets_retires": 1, # Exemple d'objets retirés par l'IA (à adapter) "etat_apres": etat_jeu.copy() # Copier l'état après le mouvement }) afficher_etat(etat_jeu) if est_etat_final(etat_jeu): print("L'IA 2 a gagné !") enregistrer_resultat({"etat_jeu_initial": etat_jeu_initial, "gagnant": "IA 2", "historique": historique_actions}) return jouer_contre_ia()