2024-10-23 11:09:51 +02:00
|
|
|
import json
|
2024-10-23 10:54:30 +02:00
|
|
|
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
|
|
|
|
|
2024-10-23 11:09:51 +02:00
|
|
|
# Sauvegarder la partie dans un fichier json
|
2024-10-23 10:54:30 +02:00
|
|
|
def sauvegarder_partie(historique, resultat):
|
2024-10-23 11:09:51 +02:00
|
|
|
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)
|
2024-10-23 10:54:30 +02:00
|
|
|
|
|
|
|
# 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)
|