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