first commit
This commit is contained in:
BIN
TP01/JeuNim.pdf
Normal file
BIN
TP01/JeuNim.pdf
Normal file
Binary file not shown.
496
TP01/Nim.ipynb
Normal file
496
TP01/Nim.ipynb
Normal file
@@ -0,0 +1,496 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Implémentation du jeu de Nim"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"etat_jeu = [3, 4, 5] # Trois tas contenant respectivement 3, 4 et 5 objets.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 1 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[3, 4, 5]\n",
|
||||
"[0, 0, 0]\n",
|
||||
"[1, 0, 2]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# A.\n",
|
||||
"def afficher_etat(etat_jeu) :\n",
|
||||
" print(etat_jeu)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# B.\n",
|
||||
"test1 = [3, 4, 5]\n",
|
||||
"test2 = [0, 0, 0]\n",
|
||||
"test3 = [1, 0, 2]\n",
|
||||
"\n",
|
||||
"afficher_etat(test1)\n",
|
||||
"afficher_etat(test2)\n",
|
||||
"afficher_etat(test3)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 2 : "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[(0, 1), (0, 2), (0, 3), (1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5)]\n",
|
||||
"[]\n",
|
||||
"[(0, 1), (2, 1), (2, 2)]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# A.\n",
|
||||
"\n",
|
||||
"def generer_mouvement(etat_jeu) : \n",
|
||||
" mouvements = []\n",
|
||||
" for i in range(len(etat_jeu)) : # On parcourt les tas\n",
|
||||
" for j in range(etat_jeu[i]) : # On tire le nombre d'objets dans le tas\n",
|
||||
" if etat_jeu[i] > 0 :\n",
|
||||
" mouvements.append((i, j+1)) # On ajoute le mouvement à la liste\n",
|
||||
" return mouvements\n",
|
||||
"\n",
|
||||
"# B.\n",
|
||||
"print(generer_mouvement(test1))\n",
|
||||
"print(generer_mouvement(test2))\n",
|
||||
"print(generer_mouvement(test3))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 3 : "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# A et B\n",
|
||||
"def appliquer_mouvement(etat_jeu, tas_index, nombre_objets) :\n",
|
||||
" if nombre_objets > etat_jeu[tas_index] :\n",
|
||||
" print(\"Erreur : nombre d'objets à retirer supérieur au nombre d'objets dans le tas.\")\n",
|
||||
" return etat_jeu\n",
|
||||
" else : \n",
|
||||
" etat_jeu[tas_index] -= nombre_objets\n",
|
||||
" return etat_jeu\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 4 :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"\" étant donné que heuristique est égale à la somme des objets dans les tas, \\nc'est donc un calcul simple qui ne dépend pas de l'ordre des tas. \""
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# A.\n",
|
||||
"'''\n",
|
||||
"def heuristique(etat_jeu) :\n",
|
||||
" return sum(etat_jeu)\n",
|
||||
"\n",
|
||||
"print(heuristique(test1))\n",
|
||||
"print(heuristique(test2))\n",
|
||||
"print(heuristique(test3))'''\n",
|
||||
"\n",
|
||||
"# B.\n",
|
||||
"''' étant donné que heuristique est égale à la somme des objets dans les tas, \n",
|
||||
"c'est donc un calcul simple qui ne dépend pas de l'ordre des tas. '''\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 5 :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# A.\n",
|
||||
"def est_etat_final(etat_jeu) :\n",
|
||||
" return sum(etat_jeu) == 0\n",
|
||||
"\n",
|
||||
"# B.\n",
|
||||
"def cout_transition(etat_courant, etat_suivant):\n",
|
||||
" return 1\n",
|
||||
"\n",
|
||||
"# Exemple d'utilisation\n",
|
||||
"etat_courant = [3, 4, 5]\n",
|
||||
"etat_suivant = appliquer_mouvement(etat_courant, 0, 1) # Devrait retourner [2, 4, 5]\n",
|
||||
"print(cout_transition(etat_courant, etat_suivant)) # Devrait retourner 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 6 : "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[[4, 8, 5], [4, 0, 5], [0, 0, 5], [0, 0, 0]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import heapq\n",
|
||||
"\n",
|
||||
"class Noeud:\n",
|
||||
" def __init__(self, etat, parent, cout, heuristique):\n",
|
||||
" self.etat = etat\n",
|
||||
" self.parent = parent\n",
|
||||
" self.cout = cout\n",
|
||||
" self.heuristique = heuristique\n",
|
||||
"\n",
|
||||
" def __lt__(self, other):\n",
|
||||
" return self.cout + self.heuristique < other.cout + other.heuristique\n",
|
||||
"\n",
|
||||
" def __eq__(self, other):\n",
|
||||
" return self.etat == other.etat\n",
|
||||
"\n",
|
||||
" def __hash__(self):\n",
|
||||
" return hash(tuple(self.etat))\n",
|
||||
"\n",
|
||||
" def __str__(self):\n",
|
||||
" return str(self.etat)\n",
|
||||
" \n",
|
||||
"def xor_etat(etat_jeu):\n",
|
||||
" xor_total = 0\n",
|
||||
" for nb_objets in etat_jeu:\n",
|
||||
" xor_total ^= nb_objets\n",
|
||||
" return xor_total\n",
|
||||
"\n",
|
||||
"def heuristique(etat_jeu):\n",
|
||||
" xor_valeur = xor_etat(etat_jeu)\n",
|
||||
" if xor_valeur == 0:\n",
|
||||
" # Position désavantageuse (perdante)\n",
|
||||
" return 100 + sum(etat_jeu) # Pénalité\n",
|
||||
" else:\n",
|
||||
" # Position avantageuse (gagnante)\n",
|
||||
" return sum(etat_jeu) # Heuristique standard\n",
|
||||
"\n",
|
||||
"def est_etat_final(etat):\n",
|
||||
" return all(pile == 0 for pile in etat)\n",
|
||||
"\n",
|
||||
"def generer_successeurs(etat):\n",
|
||||
" successeurs = []\n",
|
||||
" for i in range(len(etat)):\n",
|
||||
" if etat[i] > 0:\n",
|
||||
" for j in range(1, etat[i] + 1):\n",
|
||||
" nouvel_etat = etat[:]\n",
|
||||
" nouvel_etat[i] -= j\n",
|
||||
" successeurs.append(nouvel_etat)\n",
|
||||
" return successeurs\n",
|
||||
"\n",
|
||||
"def algorithme_a_star(etat_initial):\n",
|
||||
" noeud_initial = Noeud(etat_initial, None, 0, heuristique(etat_initial))\n",
|
||||
" frontiere = []\n",
|
||||
" heapq.heappush(frontiere, noeud_initial)\n",
|
||||
" visites = set()\n",
|
||||
"\n",
|
||||
" while frontiere:\n",
|
||||
" noeud_courant = heapq.heappop(frontiere)\n",
|
||||
"\n",
|
||||
" if est_etat_final(noeud_courant.etat):\n",
|
||||
" chemin = []\n",
|
||||
" while noeud_courant:\n",
|
||||
" chemin.append(noeud_courant.etat)\n",
|
||||
" noeud_courant = noeud_courant.parent\n",
|
||||
" return chemin[::-1]\n",
|
||||
"\n",
|
||||
" visites.add(tuple(noeud_courant.etat))\n",
|
||||
"\n",
|
||||
" for successeur in generer_successeurs(noeud_courant.etat):\n",
|
||||
" if tuple(successeur) not in visites:\n",
|
||||
" cout = noeud_courant.cout + cout_transition(noeud_courant.etat, successeur)\n",
|
||||
" heur = heuristique(successeur)\n",
|
||||
" noeud_successeur = Noeud(successeur, noeud_courant, cout, heur)\n",
|
||||
" heapq.heappush(frontiere, noeud_successeur)\n",
|
||||
"\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"# Exemple d'utilisation\n",
|
||||
"etat_initial = [4, 8, 5]\n",
|
||||
"chemin_optimal = algorithme_a_star(etat_initial)\n",
|
||||
"print(chemin_optimal)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 7 :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"(voir cellule précédante)\n",
|
||||
"\n",
|
||||
"A. \n",
|
||||
"- Initialisation:\n",
|
||||
" - Crée un nœud initial avec l'état initial du jeu.\n",
|
||||
" - Utilise une file de priorité (heap) pour gérer les nœuds à explorer.\n",
|
||||
" - Utilise un ensemble (set) pour stocker les états déjà visités.\n",
|
||||
"- Boucle principale:\n",
|
||||
" - Tant que la file de priorité n'est pas vide, extraire le nœud avec le coût total (coût + heuristique) le plus bas.\n",
|
||||
" - Si l'état du nœud courant est un état final, reconstruire et retourner le chemin depuis l'état initial jusqu'à l'état final.\n",
|
||||
" - Ajouter l'état courant à l'ensemble des états visités.\n",
|
||||
" - Générer les états successeurs et les ajouter à la file de priorité s'ils n'ont pas été visités.\n",
|
||||
"- Retour: Si aucun chemin n'est trouvé, retourner None.\n",
|
||||
"\n",
|
||||
"B.\n",
|
||||
"- Vérification des états visités, avant d'ajouter un successeur à la file de priorité, on vérifie si ils ont été visité.\n",
|
||||
"- Une fois qu'un successeur est ajouté, il est ajouté à la file de priorité et marqué comme visité.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 8 : "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"A. \n",
|
||||
"Une représentation de son parent est crée dans la classe noeud. Lorsque qu'un successeur est crée, le noeud courant est défini comme parent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[[3, 4, 5], [3, 4, 4], [3, 4, 0]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# B.\n",
|
||||
"\n",
|
||||
"def reconstruire_chemin(noeud_final):\n",
|
||||
" \"\"\"\n",
|
||||
" Reconstruit la séquence de mouvements depuis l’état initial jusqu’à l’état final.\n",
|
||||
" \n",
|
||||
" :param noeud_final: Le nœud final de l'algorithme A*.\n",
|
||||
" :return: Une liste des états représentant le chemin de l'état initial à l'état final.\n",
|
||||
" \"\"\"\n",
|
||||
" chemin = []\n",
|
||||
" noeud_courant = noeud_final\n",
|
||||
" while noeud_courant:\n",
|
||||
" chemin.append(noeud_courant.etat)\n",
|
||||
" noeud_courant = noeud_courant.parent\n",
|
||||
" return chemin[::-1]\n",
|
||||
"\n",
|
||||
"# Création d'un chemin d'exemple pour tester la fonction\n",
|
||||
"etat_initial = [3, 4, 5]\n",
|
||||
"etat_intermediaire = [3, 4, 4]\n",
|
||||
"etat_final = [3, 4, 0]\n",
|
||||
"\n",
|
||||
"noeud_final = Noeud(etat_final, Noeud(etat_intermediaire, Noeud(etat_initial, None, 0, 0), 1, 0), 2, 0)\n",
|
||||
"chemin = reconstruire_chemin(noeud_final)\n",
|
||||
"print(chemin) # Devrait retourner [[3, 4, 5], [3, 4, 4], [3, 4, 0]]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 9 : "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[3, 4, 5]\n",
|
||||
"[3, 4, 5]\n",
|
||||
"\n",
|
||||
"L'IA joue...\n",
|
||||
"[3, 4, 0]\n",
|
||||
"[0, 4, 0]\n",
|
||||
"\n",
|
||||
"L'IA joue...\n",
|
||||
"\n",
|
||||
" L'IA a gagné !\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def jeu_nim(etat_initial):\n",
|
||||
" etat = etat_initial[:]\n",
|
||||
" while not est_etat_final(etat):\n",
|
||||
" afficher_etat(etat)\n",
|
||||
" try:\n",
|
||||
" pile = int(input(\"Entrez le numéro de la pile (1, 2, 3, ...): \")) - 1\n",
|
||||
" nb_objets = int(input(\"Entrez le nombre d'objets à retirer: \"))\n",
|
||||
" appliquer_mouvement(etat, pile, nb_objets)\n",
|
||||
" afficher_etat(etat)\n",
|
||||
" except ValueError:\n",
|
||||
" print(\"Entrée invalide. Veuillez entrer des nombres entiers.\")\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" if est_etat_final(etat):\n",
|
||||
" print(\"\\nFélicitations ! Vous avez gagné !\")\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
" # Tour de l'IA\n",
|
||||
" chemin_optimal = algorithme_a_star(etat)\n",
|
||||
" if chemin_optimal and len(chemin_optimal) > 1:\n",
|
||||
" etat_ia = chemin_optimal[1]\n",
|
||||
" print(\"\\nL'IA joue...\")\n",
|
||||
" etat = etat_ia\n",
|
||||
"\n",
|
||||
" if est_etat_final(etat):\n",
|
||||
" print(\"\\n L'IA a gagné !\")\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
"# Exemple d'utilisation\n",
|
||||
"etat_initial = [3, 4, 5]\n",
|
||||
"jeu_nim(etat_initial)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exercice 10 :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def xor_etat(etat_jeu):\n",
|
||||
" xor_total = 0\n",
|
||||
" for nb_objets in etat_jeu:\n",
|
||||
" xor_total ^= nb_objets\n",
|
||||
" return xor_total\n",
|
||||
"\n",
|
||||
"def heuristique_amelioree(etat_jeu):\n",
|
||||
" xor_valeur = xor_etat(etat_jeu)\n",
|
||||
" if xor_valeur == 0:\n",
|
||||
" # Position désavantageuse (perdante)\n",
|
||||
" return 100 + sum(etat_jeu) # Pénalité\n",
|
||||
" else:\n",
|
||||
" # Position avantageuse (gagnante)\n",
|
||||
" return sum(etat_jeu) # Heuristique standard"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
197
TP01/code.py
Normal file
197
TP01/code.py
Normal file
@@ -0,0 +1,197 @@
|
||||
import heapq
|
||||
import random
|
||||
|
||||
class Noeud:
|
||||
def __init__(self, etat, parent, cout, heuristique):
|
||||
self.etat = etat
|
||||
self.parent = parent
|
||||
self.cout = cout
|
||||
self.heuristique = heuristique
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.cout + self.heuristique < other.cout + other.heuristique
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.etat == other.etat
|
||||
|
||||
def __hash__(self):
|
||||
return hash(tuple(self.etat))
|
||||
|
||||
def __str__(self):
|
||||
return str(self.etat)
|
||||
|
||||
def afficher_etat(etat_jeu) :
|
||||
print(etat_jeu)
|
||||
|
||||
def xor_etat(etat_jeu):
|
||||
xor_total = 0
|
||||
for nb_objets in etat_jeu:
|
||||
xor_total ^= nb_objets
|
||||
return xor_total
|
||||
|
||||
def heuristique(etat_jeu):
|
||||
xor_valeur = xor_etat(etat_jeu)
|
||||
if xor_valeur == 0:
|
||||
# Position désavantageuse (perdante)
|
||||
return 100 + sum(etat_jeu) # Pénalité
|
||||
else:
|
||||
# Position avantageuse (gagnante)
|
||||
return sum(etat_jeu) # Heuristique standard
|
||||
|
||||
def appliquer_mouvement(etat_jeu, tas_index, nombre_objets) :
|
||||
if nombre_objets > etat_jeu[tas_index] :
|
||||
print("Erreur : nombre d'objets à retirer supérieur au nombre d'objets dans le tas.")
|
||||
return etat_jeu
|
||||
else :
|
||||
etat_jeu[tas_index] -= nombre_objets
|
||||
return etat_jeu
|
||||
|
||||
def cout_transition(etat_courant, etat_suivant):
|
||||
return 1
|
||||
|
||||
|
||||
def est_etat_final(etat):
|
||||
return all(pile == 0 for pile in etat)
|
||||
|
||||
def generer_successeurs(etat):
|
||||
successeurs = []
|
||||
for i in range(len(etat)):
|
||||
if etat[i] > 0:
|
||||
for j in range(1, etat[i] + 1):
|
||||
nouvel_etat = etat[:]
|
||||
nouvel_etat[i] -= j
|
||||
successeurs.append(nouvel_etat)
|
||||
return successeurs
|
||||
|
||||
def algorithme_a_star(etat_initial):
|
||||
noeud_initial = Noeud(etat_initial, None, 0, heuristique(etat_initial))
|
||||
frontiere = []
|
||||
heapq.heappush(frontiere, noeud_initial)
|
||||
visites = set()
|
||||
|
||||
while frontiere:
|
||||
noeud_courant = heapq.heappop(frontiere)
|
||||
|
||||
if est_etat_final(noeud_courant.etat):
|
||||
chemin = []
|
||||
while noeud_courant:
|
||||
chemin.append(noeud_courant.etat)
|
||||
noeud_courant = noeud_courant.parent
|
||||
return chemin[::-1]
|
||||
|
||||
visites.add(tuple(noeud_courant.etat))
|
||||
|
||||
for successeur in generer_successeurs(noeud_courant.etat):
|
||||
if tuple(successeur) not in visites:
|
||||
cout = noeud_courant.cout + cout_transition(noeud_courant.etat, successeur)
|
||||
heur = heuristique(successeur)
|
||||
noeud_successeur = Noeud(successeur, noeud_courant, cout, heur)
|
||||
heapq.heappush(frontiere, noeud_successeur)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def reconstruire_chemin(noeud_final):
|
||||
"""
|
||||
Reconstruit la séquence de mouvements depuis l’état initial jusqu’à l’état final.
|
||||
|
||||
:param noeud_final: Le nœud final de l'algorithme A*.
|
||||
:return: Une liste des états représentant le chemin de l'état initial à l'état final.
|
||||
"""
|
||||
chemin = []
|
||||
noeud_courant = noeud_final
|
||||
while noeud_courant:
|
||||
chemin.append(noeud_courant.etat)
|
||||
noeud_courant = noeud_courant.parent
|
||||
return chemin[::-1]
|
||||
|
||||
def sauvegarder_partie(historique, fichier="historique_parties.txt"):
|
||||
"""
|
||||
Sauvegarde l'historique de la partie dans un fichier.
|
||||
|
||||
:param historique: Liste des coups effectués pendant la partie.
|
||||
:param fichier: Nom du fichier où sauvegarder l'historique.
|
||||
"""
|
||||
with open(fichier, "a") as f:
|
||||
f.write("Nouvelle partie\n")
|
||||
for coup in historique:
|
||||
f.write(f"{coup}\n")
|
||||
f.write("\n")
|
||||
|
||||
|
||||
def jeu_nim(etat_initial):
|
||||
etat = etat_initial[:]
|
||||
historique = []
|
||||
while not est_etat_final(etat):
|
||||
afficher_etat(etat)
|
||||
try:
|
||||
pile = int(input("Entrez le numéro de la pile (1, 2, 3, ...): ")) - 1
|
||||
nb_objets = int(input("Entrez le nombre d'objets à retirer: "))
|
||||
historique.append(f"Joueur: Pile {pile + 1}, Objets retirés: {nb_objets}")
|
||||
appliquer_mouvement(etat, pile, nb_objets)
|
||||
afficher_etat(etat)
|
||||
except ValueError:
|
||||
print("Entrée invalide. Veuillez entrer des nombres entiers.")
|
||||
continue
|
||||
|
||||
if est_etat_final(etat):
|
||||
print("\nFélicitations ! Vous avez gagné !")
|
||||
break
|
||||
|
||||
# Tour de l'IA
|
||||
chemin_optimal = algorithme_a_star(etat)
|
||||
if chemin_optimal and len(chemin_optimal) > 1:
|
||||
etat_ia = chemin_optimal[1]
|
||||
historique.append(f"IA: Pile {pile + 1}, Objets retirés: {nb_objets}")
|
||||
print("\nL'IA joue...")
|
||||
etat = etat_ia
|
||||
|
||||
if est_etat_final(etat):
|
||||
print("\n L'IA a gagné !")
|
||||
break
|
||||
sauvegarder_partie(historique)
|
||||
|
||||
def pile_random(etat) :
|
||||
piles_non_vides = [i for i, pile in enumerate(etat) if pile > 0]
|
||||
return random.choice(piles_non_vides)
|
||||
|
||||
|
||||
def nb_objets_random(etat, pile):
|
||||
return random.randint(1, etat[pile])
|
||||
|
||||
|
||||
def jeu_nim_random(etat_initial):
|
||||
etat = etat_initial[:]
|
||||
historique = []
|
||||
while not est_etat_final(etat):
|
||||
afficher_etat(etat)
|
||||
try:
|
||||
pile = pile_random(etat)
|
||||
nb_objets = nb_objets_random(etat, pile)
|
||||
historique.append(f"Joueur: Pile {pile + 1}, Objets retirés: {nb_objets}")
|
||||
appliquer_mouvement(etat, pile, nb_objets)
|
||||
afficher_etat(etat)
|
||||
except ValueError:
|
||||
print("Entrée invalide. Veuillez entrer des nombres entiers.")
|
||||
continue
|
||||
|
||||
if est_etat_final(etat):
|
||||
print("\nFélicitations ! Vous avez gagné !")
|
||||
break
|
||||
|
||||
# Tour de l'IA
|
||||
chemin_optimal = algorithme_a_star(etat)
|
||||
if chemin_optimal and len(chemin_optimal) > 1:
|
||||
etat_ia = chemin_optimal[1]
|
||||
historique.append(f"IA: Pile {pile + 1}, Objets retirés: {nb_objets}")
|
||||
print("\nL'IA joue...")
|
||||
etat = etat_ia
|
||||
|
||||
if est_etat_final(etat):
|
||||
print("\n L'IA a gagné !")
|
||||
break
|
||||
sauvegarder_partie(historique)
|
||||
|
||||
|
||||
etat_initial = [3, 4, 5]
|
||||
jeu_nim_random(etat_initial)
|
Reference in New Issue
Block a user