diff --git a/heur.py b/heur.py index eca8013..facf3aa 100644 --- a/heur.py +++ b/heur.py @@ -19,37 +19,49 @@ def generer_mouvements(etat_jeu): mouvements_possibles.append(nouvel_etat) return mouvements_possibles +# Fonction pour appliquer un mouvement à l'état du jeu +def appliquer_mouvement(etat_jeu, tas_index, nb_objets): + if tas_index < 0 or tas_index >= len(etat_jeu): + raise ValueError("Index du tas invalide.") + + if nb_objets <= 0: + raise ValueError("Le nombre d'objets à retirer doit être supérieur à 0.") + + if nb_objets > etat_jeu[tas_index]: + raise ValueError(f"Le tas {tas_index + 1} ne contient pas suffisamment d'objets pour retirer {nb_objets} objets.") + + nouvel_etat = etat_jeu.copy() + nouvel_etat[tas_index] -= nb_objets + + return nouvel_etat + # Classe Noeud utilisée pour l'algorithme A* class Noeud: def __init__(self, etat, parent=None, g=0, h=0): self.etat = etat self.parent = parent - self.g = g # Coût du chemin (g(n)) - self.h = h # Heuristique (h(n)) + self.g = g + self.h = h - # Priorité des nœuds basée sur la somme g + h def __lt__(self, other): return (self.g + self.h) < (other.g + other.h) # Algorithme A* pour trouver le chemin optimal vers la victoire def algorithme_a_star(etat_initial): - # Initialisation de la file de priorité + open_list = [] heapq.heappush(open_list, Noeud(etat_initial, g=0, h=heuristique(etat_initial))) closed_list = set() while open_list: - # Récupérer le nœud avec le plus faible f(n) = g(n) + h(n) + noeud_courant = heapq.heappop(open_list) - # Vérifier si c'est l'état final + if est_etat_final(noeud_courant.etat): return reconstruire_chemin(noeud_courant) - - # Ajouter l'état courant aux états visités closed_list.add(tuple(noeud_courant.etat)) - # Générer les mouvements légaux for mouvement in generer_mouvements(noeud_courant.etat): if tuple(mouvement) in closed_list: continue @@ -59,7 +71,7 @@ def algorithme_a_star(etat_initial): nouveau_noeud = Noeud(mouvement, parent=noeud_courant, g=g_nouveau, h=h_nouveau) heapq.heappush(open_list, nouveau_noeud) - return None # Si aucun chemin n'est trouvé + return None # Fonction pour reconstruire le chemin optimal def reconstruire_chemin(noeud_final): @@ -68,9 +80,31 @@ def reconstruire_chemin(noeud_final): while noeud_courant is not None: chemin.append(noeud_courant.etat) noeud_courant = noeud_courant.parent - return chemin[::-1] # Retourner le chemin dans l'ordre correct + return chemin[::-1] -# Test de l'algorithme A* avec l'état initial [3, 4, 5] etat_initial = [3, 4, 5] chemin_optimal = algorithme_a_star(etat_initial) print("Chemin optimal:", chemin_optimal) + +etat_jeu = [3, 4, 5] + +nouvel_etat_1 = appliquer_mouvement(etat_jeu, 0, 2) +print("Nouvel état après retrait de 2 objets du tas 1:", nouvel_etat_1) + +nouvel_etat_2 = appliquer_mouvement(etat_jeu, 2, 3) +print("Nouvel état après retrait de 3 objets du tas 3:", nouvel_etat_2) + +try: + nouvel_etat_3 = appliquer_mouvement(etat_jeu, 5, 2) +except ValueError as e: + print(e) + +try: + nouvel_etat_4 = appliquer_mouvement(etat_jeu, 1, 5) +except ValueError as e: + print(e) + +try: + nouvel_etat_5 = appliquer_mouvement(etat_jeu, 0, 0) +except ValueError as e: + print(e)