nim.py
This commit is contained in:
parent
a6484292df
commit
948f6278c1
196
nim.py
Normal file
196
nim.py
Normal file
@ -0,0 +1,196 @@
|
||||
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...")
|
||||
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",
|
||||
"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 a gagné !")
|
||||
enregistrer_resultat({"etat_jeu_initial": etat_jeu_initial, "gagnant": "IA", "historique": historique_actions})
|
||||
return
|
||||
|
||||
|
||||
|
||||
jouer_contre_ia()
|
||||
|
170
resultats.json
Normal file
170
resultats.json
Normal file
@ -0,0 +1,170 @@
|
||||
[
|
||||
{
|
||||
"gagnant": "IA"
|
||||
},
|
||||
{
|
||||
"gagnant": "IA",
|
||||
"historique": [
|
||||
{
|
||||
"joueur": "utilisateur",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
2,
|
||||
4,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "IA",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
2,
|
||||
3,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "utilisateur",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
1,
|
||||
3,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "IA",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
1,
|
||||
3,
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "utilisateur",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
0,
|
||||
3,
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "IA",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"etat jeu initial": [
|
||||
3,
|
||||
4,
|
||||
5
|
||||
],
|
||||
"gagnant": "IA",
|
||||
"historique": [
|
||||
{
|
||||
"joueur": "utilisateur",
|
||||
"tas": 0,
|
||||
"objets_retires": 3,
|
||||
"etat_apres": [
|
||||
0,
|
||||
4,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "IA",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
0,
|
||||
1,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "utilisateur",
|
||||
"tas": 2,
|
||||
"objets_retires": 5,
|
||||
"etat_apres": [
|
||||
0,
|
||||
1,
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "IA",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"etat jeu initial": [
|
||||
4,
|
||||
4,
|
||||
3
|
||||
],
|
||||
"gagnant": "IA",
|
||||
"historique": [
|
||||
{
|
||||
"joueur": "utilisateur",
|
||||
"tas": 0,
|
||||
"objets_retires": 4,
|
||||
"etat_apres": [
|
||||
0,
|
||||
4,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "IA",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
0,
|
||||
1,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "utilisateur",
|
||||
"tas": 1,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
0,
|
||||
0,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"joueur": "IA",
|
||||
"tas": 0,
|
||||
"objets_retires": 1,
|
||||
"etat_apres": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue
Block a user