La mission est d’implémenter le tournoi d’Axelrod première version présenté dans la vidéo ci-dessous.
Vous ferez concourir les stratégies suivantes en écrivant une fonction par stratégie :
AllC
: coopère toujours.AllD
: trahit toujours.Rando
: joue au hasard.Alt
: alterne un coup sur deux.TitforTat
: coopère au premier coup puis joue le coup précédent de l’adversaire.Grudger
: commence par coopérer mais dès que l’autre trahit, trahit toujours.Joss
: commence par coopérer puis joue le coup précédent de l’adversaire sauf 10% du temps où il trahit.TitforTwoTats
: trahit si l’autre trahit deux fois de suite, coopère sinon.TwoTitsforTat
: coopère tant que l’autre coopère, mais à chaque trahison de l’adversaire, trahit deux fois consécutives.Tester
: commence par trahir. Si l’autre a coopéré au premier coup, Tester
se repent et joue TitforTat
pour la suite, sinon il joue Alt
.Eatherly
: commence par trahir puis trahit en proportion du taux de trahison de l’autre jusqu’à ce coup.Gofman
: commence par coopérer. Si les deux joueurs ont joué différemment au coup précédent, trahit avec une probabilité de 5/7, et coopère s’ils ont joué la même chose.Tullock
: coopère les 10 premiers coups puis coopère à chaque coup 10% de moins que l’autre a coopéré sur les 10 coups qui précèdent.Pavlov
: commence par coopérer. Si l’autre a coopéré au dernier tour, on garde le même coup, sinon on change.Donnez le palmares du tournoi après 200 parties.
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/mScpHTIi-kM?autoplay=0&controls=1&end=0&loop=0&mute=0&start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"
></iframe>
</div>
from random import random
import seaborn as sns
import matplotlib.pyplot as plt
Les différentes stratégies :
def TitforTat(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) == 0:
return 1
elif liste_coups_adverses[-1]:
return 1
else:
return 0
def Grudger(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) == 0:
return 1
else:
if liste_coups_joueur[-1] == 0:
return 0
elif liste_coups_adverses[-1] == 0:
return 0
else:
return 1
def Joss(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) == 0:
return 1
else:
if random()<0.1:
return 0
else:
return liste_coups_adverses[-1]
def Rando(liste_coups_joueur,liste_coups_adverses):
return int(random()*2)
def AllD(liste_coups_joueur,liste_coups_adverses):
return 0
def AllC(liste_coups_joueur,liste_coups_adverses):
return 1
def TitforTwoTats(liste_coups_joueur,liste_coups_adverses): # tit for 2 tats
if len(liste_coups_adverses) < 2:
return 1
elif liste_coups_adverses[-1]+liste_coups_adverses[-2] == 0:
return 0
else:
return 1
def TwoTitsforTat(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) < 1:
return 1
elif liste_coups_adverses[-1] == 0 or (len(liste_coups_adverses) > 1 and liste_coups_adverses[-2] == 0):
return 0
else:
return 1
def Tester(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) == 0:
return 0
elif len(liste_coups_adverses) == 1:
return liste_coups_adverses[-1]
else:
if liste_coups_adverses[1]: # tit for tat
return liste_coups_adverses[-1]
else: # alternance
return (len(liste_coups_adverses)+1)%2
def Eatherly(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) == 0:
return 0
else:
if random() < (len(liste_coups_adverses)-sum(liste_coups_adverses))/len(liste_coups_adverses):
return 0
else:
return 1
def Alt(liste_coups_joueur,liste_coups_adverses):
return (len(liste_coups_adverses)+1)%2
def Gofman(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) == 0:
return 1
else:
if liste_coups_adverses[-1] != liste_coups_joueur[-1]:
if random() < 2/7:
return 1
else:
return 0
else:
return 1
def Tullock(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) < 11:
return 1
else:
if random() < sum(liste_coups_adverses)/len(liste_coups_adverses)-0.1:
return 1
else:
return 0
def Pavlov(liste_coups_joueur,liste_coups_adverses):
if len(liste_coups_adverses) == 0:
return 1
else:
if not liste_coups_adverses[-1]:
return 1-liste_coups_joueur[-1]
else:
return liste_coups_joueur[-1]
Match entre deux joueurs :
def partie(joueurA,joueurB):
nbre_parties = 200
score_joueurA = 0
score_joueurB = 0
liste_coups_joueurA = []
liste_coups_joueurB = []
for i in range(nbre_parties):
JA = dico_strategies[joueurA](liste_coups_joueurA,liste_coups_joueurB)
JB = dico_strategies[joueurB](liste_coups_joueurB,liste_coups_joueurA)
liste_coups_joueurA.append(JA)
liste_coups_joueurB.append(JB)
if JA:
if JB:
score_joueurA += 3
score_joueurB += 3
else:
score_joueurA += 0
score_joueurB += 5
else:
if JB:
score_joueurA += 5
score_joueurB += 0
else:
score_joueurA += 1
score_joueurB += 1
if joueurA == joueurB:
dico_scores[joueurA] += score_joueurA
matrice_tournoi[liste_joueurs.index(joueurA)][liste_joueurs.index(joueurA)] += score_joueurA
else:
dico_scores[joueurA] += score_joueurA
dico_scores[joueurB] += score_joueurB
matrice_tournoi[liste_joueurs.index(joueurB)][liste_joueurs.index(joueurA)] += score_joueurB
matrice_tournoi[liste_joueurs.index(joueurA)][liste_joueurs.index(joueurB)] += score_joueurA
Le tournoi (on fait s’affronter tous les joueurs y compris eux-mêmes et on recommence 50 fois) :
def tournoi():
global partie
nb_tournois = 100
for i in range(nb_tournois):
for j,JA in enumerate(liste_joueurs):
for JB in liste_joueurs[j:]:
partie(JA,JB)
for i in range(len(matrice_tournoi)):
for j in range(len(matrice_tournoi[0])):
matrice_tournoi[i][j] = int(matrice_tournoi[i][j]/nb_tournois)
for key in dico_scores:
dico_scores[key] = int(dico_scores[key]/nb_tournois)
Pour réinitialiser les scores entre deux tournois :
def raz():
global liste_joueurs,liste_strategies,dico_strategies,dico_scores,matrice_tournoi
liste_joueurs = ["TitforTat","Grudger","Joss","AllD","AllC","TitforTwoTats","Tester","Eatherly","Alt","Gofman","Tullock","Rando","TwoTitsforTat"]
liste_strategies = [TitforTat,Grudger,Joss,AllD,AllC,TitforTwoTats,Tester,Eatherly,Alt,Gofman,Tullock,Rando,TwoTitsforTat]
dico_strategies = {J:S for (J,S) in zip(liste_joueurs,liste_strategies)}
dico_scores = {J:0 for J in liste_joueurs}
matrice_tournoi = [[0 for _ in range(len(liste_joueurs))] for _ in range(len(liste_joueurs))]
raz()
tournoi()
liste_scores = [dico_scores[k] for k in dico_scores]
combo = list(zip(liste_scores,liste_joueurs))
combo.sort(reverse=True)
for s,j in combo:
print(f"{j:17} : {s}")
plt.figure(figsize=(15,15),dpi=150)
s = sns.heatmap(matrice_tournoi, annot=True, fmt="d", cmap='YlGnBu', xticklabels=liste_joueurs, yticklabels=liste_joueurs)
plt.tick_params(axis='both', which='both', length=5)
s.xaxis.tick_top()
s.xaxis.set_label_position('top')
plt.xticks(rotation=90)
⚡
Player A : 0
Player B : 0
Imaginer une nouvelle stratégie qui se hisse sur le podium du tournoi contre les autres stratégies déjà implémentées.