IA-Learning/Nim-Sum.py

120 lines
4.5 KiB
Python

import json
import random
import datetime
# 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 calculer le Nim-sum (ou exclusif XOR de tous les tas)
def calculer_nim_sum(etat_jeu):
nim_sum = 0
for nb_objets in etat_jeu:
nim_sum ^= nb_objets
return nim_sum
# 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)
# Heuristique Nim-Sum pour l'ordinateur
def heuristique_nim_sum(etat_jeu):
nim_sum = calculer_nim_sum(etat_jeu)
if nim_sum == 0:
# Si le Nim-sum est déjà 0, l'ordinateur fait un mouvement aléatoire
tas_non_vide = [i for i, nb_objets in enumerate(etat_jeu) if nb_objets > 0]
tas_choisi = random.choice(tas_non_vide)
nb_objets = random.randint(1, etat_jeu[tas_choisi])
return tas_choisi, nb_objets
else:
# Si le Nim-sum est différent de 0, l'ordinateur essaie de rendre le Nim-sum égal à 0
for i, nb_objets in enumerate(etat_jeu):
if nb_objets ^ nim_sum < nb_objets:
nb_objets_a_prendre = nb_objets - (nb_objets ^ nim_sum)
return i, nb_objets_a_prendre
# Sauvegarder la partie dans un fichier json
def sauvegarder_partie(historique, resultat):
partie = {
"date": str(datetime.datetime.now()),
"historique": historique,
"resultat": resultat
}
# Chargement du fichier JSON existant ou création s'il n'existe pas
try:
with open("historique_nim.json", "r") as fichier:
sauvegardes = json.load(fichier)
except FileNotFoundError:
sauvegardes = []
# Ajouter la nouvelle partie à l'historique
sauvegardes.append(partie)
# Sauvegarde dans le fichier
with open("historique_nim.json", "w") as fichier:
json.dump(sauvegardes, fichier, indent=4)
# 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 :")
tas_choisi, nb_objets = heuristique_nim_sum(etat_jeu)
etat_jeu = appliquer_mouvement(etat_jeu, tas_choisi, nb_objets)
historique.append(f"Ordinateur a pris {nb_objets} objets du tas {tas_choisi + 1}")
print(f"L'ordinateur a pris {nb_objets} objets du tas {tas_choisi + 1}.\n")
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)