Téléverser les fichiers vers "/"
This commit is contained in:
commit
2a45424214
147
heuristique_Nim.py
Normal file
147
heuristique_Nim.py
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
import random
|
||||||
|
import datetime
|
||||||
|
import heapq # Pour la file de priorité (algorithme A*)
|
||||||
|
|
||||||
|
# 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 générer tous les mouvements possibles
|
||||||
|
def generer_mouvements(etat_jeu):
|
||||||
|
mouvements = []
|
||||||
|
for i, nb_objets in enumerate(etat_jeu):
|
||||||
|
for n in range(1, nb_objets + 1):
|
||||||
|
nouvel_etat = etat_jeu[:]
|
||||||
|
nouvel_etat[i] -= n
|
||||||
|
mouvements.append(nouvel_etat)
|
||||||
|
return mouvements
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
# Fonction heuristique pour estimer le coût restant
|
||||||
|
def heuristique(etat_jeu):
|
||||||
|
# Heuristique simple : somme des objets restants
|
||||||
|
return sum(etat_jeu)
|
||||||
|
|
||||||
|
# Classe Noeud 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 pour atteindre ce nœud
|
||||||
|
self.h = h # Heuristique estimée
|
||||||
|
self.f = g + h # Fonction de coût totale
|
||||||
|
|
||||||
|
def __lt__(self, autre):
|
||||||
|
return self.f < autre.f
|
||||||
|
|
||||||
|
# Fonction pour reconstruire le chemin optimal
|
||||||
|
def reconstruire_chemin(noeud_final):
|
||||||
|
chemin = []
|
||||||
|
noeud_actuel = noeud_final
|
||||||
|
while noeud_actuel:
|
||||||
|
chemin.append(noeud_actuel.etat)
|
||||||
|
noeud_actuel = noeud_actuel.parent
|
||||||
|
return chemin[::-1] # Inverser le chemin pour obtenir du départ à l'arrivée
|
||||||
|
|
||||||
|
# Algorithme A* pour résoudre le jeu de Nim
|
||||||
|
def algorithme_a_star(etat_initial):
|
||||||
|
# Initialisation de la file de priorité
|
||||||
|
open_list = []
|
||||||
|
heapq.heappush(open_list, Noeud(etat_initial, h=heuristique(etat_initial)))
|
||||||
|
|
||||||
|
# Ensemble des états déjà visités
|
||||||
|
visited = set()
|
||||||
|
|
||||||
|
while open_list:
|
||||||
|
noeud_courant = heapq.heappop(open_list)
|
||||||
|
|
||||||
|
if est_etat_final(noeud_courant.etat):
|
||||||
|
return reconstruire_chemin(noeud_courant)
|
||||||
|
|
||||||
|
visited.add(tuple(noeud_courant.etat))
|
||||||
|
|
||||||
|
for mouvement in generer_mouvements(noeud_courant.etat):
|
||||||
|
if tuple(mouvement) not in visited:
|
||||||
|
noeud_successeur = Noeud(mouvement, parent=noeud_courant,
|
||||||
|
g=noeud_courant.g + 1,
|
||||||
|
h=heuristique(mouvement))
|
||||||
|
heapq.heappush(open_list, noeud_successeur)
|
||||||
|
|
||||||
|
# Sauvegarder la partie dans un fichier texte
|
||||||
|
def sauvegarder_partie(historique, resultat):
|
||||||
|
with open("historique_nim.txt", "a") as fichier:
|
||||||
|
fichier.write("\n===== Nouvelle Partie =====\n")
|
||||||
|
fichier.write(f"Date : {datetime.datetime.now()}\n")
|
||||||
|
for entree in historique:
|
||||||
|
fichier.write(entree + "\n")
|
||||||
|
fichier.write(f"Résultat : {resultat}\n")
|
||||||
|
fichier.write("==========================\n")
|
||||||
|
|
||||||
|
# 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 :")
|
||||||
|
meilleur_chemin = algorithme_a_star(etat_jeu)
|
||||||
|
prochain_etat = meilleur_chemin[1] # Choisir le premier mouvement du chemin
|
||||||
|
for i in range(len(etat_jeu)):
|
||||||
|
if etat_jeu[i] != prochain_etat[i]:
|
||||||
|
nb_objets = etat_jeu[i] - prochain_etat[i]
|
||||||
|
etat_jeu = prochain_etat
|
||||||
|
historique.append(f"Ordinateur a pris {nb_objets} objets du tas {i + 1}")
|
||||||
|
break
|
||||||
|
|
||||||
|
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)
|
Loading…
Reference in New Issue
Block a user