Skip to content
Snippets Groups Projects
Commit 9ca3dca6 authored by Cire Ba's avatar Cire Ba
Browse files

Tournoi OK

parent ef97e1b6
No related branches found
No related tags found
No related merge requests found
import random
class Prisonnier:
"""
Classe représentant un prisonnier avec une stratégie basée sur une probabilité d'avouer.
"""
def __init__(self, proba_avouer=0.5, nom="Prisonnier Aléatoire"):
"""
Constructeur de la classe Prisonnier.
Args:
proba_avouer: probabilité d'avouer (par défaut 0.5 pour un joueur aléatoire uniforme)
nom: nom de la stratégie pour l'affichage
"""
self.proba_avouer = proba_avouer
self.historique_adversaire = []
self.nom = nom
def jouer(self):
"""
Méthode qui détermine l'action du joueur en fonction de sa probabilité d'avouer.
Returns:
'avoue' ou 'nie' selon la probabilité
"""
if random.random() < self.proba_avouer:
return "avoue"
else:
return "nie"
def maj(self, coup):
"""
Méthode qui met à jour l'historique des coups joués par l'adversaire.
Args:
coup: le coup joué par l'adversaire ('avoue' ou 'nie')
"""
self.historique_adversaire.append(coup)
def reinitialiser(self):
"""
Méthode qui réinitialise l'historique des coups de l'adversaire.
"""
self.historique_adversaire = []
class TitForTat(Prisonnier):
"""
Stratégie Tit for Tat (oeil pour oeil) : commence par coopérer (nier),
puis imite le dernier coup de l'adversaire.
"""
def __init__(self):
"""
Constructeur de la classe TitForTat.
"""
super().__init__(nom="TitForTat") # Appel du constructeur de la classe parente
def jouer(self):
"""
Méthode qui détermine l'action du joueur selon la stratégie Tit for Tat.
Returns:
'avoue' ou 'nie' selon la stratégie
"""
# Si c'est le premier coup, on coopère (nie)
if not self.historique_adversaire:
return "nie"
# Sinon, on imite le dernier coup de l'adversaire
else:
return self.historique_adversaire[-1]
class Dummy(Prisonnier):
"""
Stratégie Dummy : toujours coopérer ou toujours trahir selon un paramètre.
"""
def __init__(self, coopere=True):
"""
Constructeur de la classe Dummy.
Args:
coopere: si True, toujours coopérer (nier), sinon toujours trahir (avouer)
"""
nom = "Dummy (coopère)" if coopere else "Dummy (trahit)"
super().__init__(nom=nom) # Appel du constructeur de la classe parente
self.coopere = coopere
def jouer(self):
"""
Méthode qui détermine l'action du joueur selon la stratégie Dummy.
Returns:
'avoue' ou 'nie' selon la stratégie
"""
if self.coopere:
return "nie" # Coopérer = nier
else:
return "avoue" # Trahir = avouer
def dilemme_prisonnier_itere(matrice_pertes, joueur1, joueur2, nb_tours=10, afficher_details=False):
"""
Fonction qui simule un dilemme du prisonnier itéré entre deux joueurs.
Args:
matrice_pertes: dictionnaire des pertes
joueur1: premier joueur
joueur2: deuxième joueur
nb_tours: nombre de tours à jouer
afficher_details: si True, affiche les détails de chaque tour
Returns:
tuple des scores totaux (score_joueur1, score_joueur2)
"""
# Réinitialisation des historiques
joueur1.reinitialiser()
joueur2.reinitialiser()
score_joueur1 = 0
score_joueur2 = 0
if afficher_details:
print(f"Dilemme du prisonnier itéré: {joueur1.nom} vs {joueur2.nom}")
print(f"Nombre de tours: {nb_tours}")
print("-" * 50)
for tour in range(nb_tours):
# Les joueurs choisissent leur action
action_joueur1 = joueur1.jouer()
action_joueur2 = joueur2.jouer()
# On calcule les pertes pour ce tour
perte_joueur1, perte_joueur2 = matrice_pertes[(action_joueur1, action_joueur2)]
# On met à jour les scores (négatif des pertes)
score_joueur1 -= perte_joueur1
score_joueur2 -= perte_joueur2
# On met à jour l'historique des joueurs
joueur1.maj(action_joueur2)
joueur2.maj(action_joueur1)
# Affichage du tour si demandé
if afficher_details:
print(f"Tour {tour+1}: {joueur1.nom} joue {action_joueur1}, {joueur2.nom} joue {action_joueur2}")
print(f"Pertes: {joueur1.nom} = {perte_joueur1}, {joueur2.nom} = {perte_joueur2}")
print(f"Scores cumulés: {joueur1.nom} = {score_joueur1}, {joueur2.nom} = {score_joueur2}\n")
if afficher_details:
print("Résultat final:")
print(f"Score {joueur1.nom}: {score_joueur1}")
print(f"Score {joueur2.nom}: {score_joueur2}")
if score_joueur1 > score_joueur2:
print(f"{joueur1.nom} gagne!")
elif score_joueur2 > score_joueur1:
print(f"{joueur2.nom} gagne!")
else:
print("Match nul!")
print("-" * 50)
return score_joueur1, score_joueur2
def organiser_tournoi_simple(matrice_pertes, joueurs, nb_tours=50):
"""
Fonction qui organise un tournoi simple entre différentes stratégies.
Args:
matrice_pertes: dictionnaire des pertes
joueurs: liste des joueurs
nb_tours: nombre de tours par partie
Returns:
dictionnaire des scores totaux par joueur
"""
scores = {joueur.nom: 0 for joueur in joueurs}
nb_matchs = {joueur.nom: 0 for joueur in joueurs}
print("\nTournoi sur la matrice de pertes")
print("=" * 40)
# Chaque joueur affronte tous les autres joueurs
for i, joueur1 in enumerate(joueurs):
for j, joueur2 in enumerate(joueurs):
if i != j: # Un joueur ne s'affronte pas lui-même
score1, score2 = dilemme_prisonnier_itere(matrice_pertes, joueur1, joueur2, nb_tours=nb_tours)
# On met à jour les scores totaux
scores[joueur1.nom] += score1
scores[joueur2.nom] += score2
# On met à jour le nombre de matchs
nb_matchs[joueur1.nom] += 1
nb_matchs[joueur2.nom] += 1
# On affiche les résultats de cette confrontation
print(f"{joueur1.nom} vs {joueur2.nom}: {score1} - {score2}")
# On calcule les scores moyens
scores_moyens = {nom: scores[nom] / nb_matchs[nom] for nom in scores}
# On trie les joueurs par score moyen décroissant
classement = sorted(scores_moyens.items(), key=lambda x: x[1], reverse=True)
print("\nClassement final:")
for rang, (nom, score) in enumerate(classement, 1):
print(f"{rang}. {nom}: {score:.1f}")
return scores_moyens
# Main pour tester le code
if __name__ == "__main__":
# Définition des actions possibles
actions = ["avoue", "nie"]
# Représentation des pertes (peines) par un dictionnaire
pertes = {
("avoue", "avoue"): (3, 3),
("avoue", "nie"): (0, 10),
("nie", "avoue"): (10, 0),
("nie", "nie"): (1, 1)
}
print("Dilemme du Prisonnier Itéré")
print("===========================")
# Création des joueurs avec différentes stratégies
joueurs = [
TitForTat(),
Dummy(coopere=True),
Dummy(coopere=False),
Prisonnier(proba_avouer=0.5),
Prisonnier(proba_avouer=0.3, nom="Prisonnier (p=0.3)")
]
# Test de différentes combinaisons de stratégies
print("\nTest de différentes combinaisons de stratégies")
print("-------------------------------------------")
# TitForTat vs Dummy (trahit)
dilemme_prisonnier_itere(pertes, joueurs[0], joueurs[2], nb_tours=10, afficher_details=True)
# TitForTat vs Dummy (coopère)
dilemme_prisonnier_itere(pertes, joueurs[0], joueurs[1], nb_tours=10, afficher_details=True)
# Organisation d'un tournoi simple
organiser_tournoi_simple(pertes, joueurs, nb_tours=50)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment