diff --git a/ARE-DYNAMIC.py b/ARE-DYNAMIC.py index 8e2a3f3..9e336e0 100644 --- a/ARE-DYNAMIC.py +++ b/ARE-DYNAMIC.py @@ -31,7 +31,7 @@ from tkinter.ttk import * TailleGrilleX = 15 TailleGrilleY = 15 -# Grille +# la grille Grille = np.ndarray((TailleGrilleX, TailleGrilleY)) # historique des grilles aux itérations précédentes @@ -43,9 +43,9 @@ HistoriqueGrilles = list() # nb_utilisations = nombre total d'utilisations de la stratégie # total_ans_prisons = total d'années de prisons subies par les utilisateurs de la stratégie # utilisation_detail[i] = une liste de triplets [utilisateurs, utilisations, prisons] -# représentant, à la fin de l'itération i, le nombre d'utilisateurs, le nombre d'utilisations -# ainsi quel le nombre d'années de prisons qu'ils ont accumulés -# attention, le nombre d'utilisateurs stockés est +# utilisateur = nombre d'utilisateurs de la stratégie a la FIN de l'iteration i +# utilisations = le nombre de fois que la fonction stratégie a été appelée au course de l'itération i +# prisons = nombre total d'années de prisons pris par les utilisateurs de la stratégie au course de l'itération i StratsResultats = list() # liste des stratégies (fonctions Joueur^2 -> {0, 1} décidant si un joueur nie ou non en fonction de son adversaire) @@ -72,8 +72,8 @@ AffichageDynamique = True # nécessaire pour matrice_init_pourcents_choisis() ListePourcents = list() -#Couleurs des Stratégies -CouleursStrat=['b','r','black','g','purple','yellow'] +# couleurs des stratégies (pour l'affichage dynamique) +CouleursStrat = ['b','r','black','g','purple','yellow'] # Vitesse de défilement des images dans l'affichage dynamique en millisecondes Vitesse = 1 @@ -81,32 +81,33 @@ Vitesse = 1 # Fonction pour le GUI def saisir_les_pourcentages(): """ - S'il y a eu clic sur le bouton du - type 4, affiche 5 entry box pour - saisir les pourcentages voulus + S'il y a eu clic sur le bouton du + type 4, affiche 5 entry box pour + saisir les pourcentages voulus """ + Label(fenetre, text="% stratégie0:").grid(row=9, column =0) - per0=IntVar() + per0 = IntVar() Entry(fenetre, textvariable=per0, width=3).grid(row=9, column=1) Label(fenetre, text ="% stratégie1:").grid(row=10, column=0) - per1 =IntVar() + per1 = IntVar() Entry(fenetre, textvariable=per1, width=3).grid(row=10, column=1) Label(fenetre, text ="% stratégie2:").grid(row=11, column=0) - per2 =IntVar() + per2 = IntVar() Entry(fenetre, textvariable=per2, width=3).grid(row=11, column=1) Label(fenetre, text ="% stratégie3:").grid(row=12, column=0) - per3 =IntVar() + per3 = IntVar() Entry(fenetre, textvariable=per3, width=3).grid(row=12, column=1) Label(fenetre, text ="% stratégie4:").grid(row=13, column=0) - per4 =IntVar() + per4 = IntVar() Entry(fenetre, textvariable=per4, width=3).grid(row=13, column=1) global ListePourcents - ListePourcents=[per0.get(), per1.get(), per2.get(), per3.get(), per4.get()] + ListePourcents = [per0.get(), per1.get(), per2.get(), per3.get(), per4.get()] @@ -119,31 +120,27 @@ Types: ##################################### ### Génération de la matrice initiale + def gen_matrice_initiale(): - """ - NoneType -> GrilleJoueurs - """ - fonction_gen = ListeGenGrille[TypeGrilleInitiale] - - return fonction_gen() + return (ListeGenGrille[TypeGrilleInitiale])() ############################## ### Execution des tours / jeux def partie1v1(joueur, adversaire): """ - Joueur^2 -> int - + Joueur^2 -> int^2 + Effectue une partie à deux joueurs Renvoie: paire (prison_joueur, prison_adversaire) """ stratj = ListeStrategies[joueur["strategie"]] strata = ListeStrategies[adversaire["strategie"]] - + etatj = stratj(joueur, adversaire) etata = strata(adversaire, joueur) - + # 1 = avouer # 0 = nier if etatj == 0: @@ -170,13 +167,13 @@ def partie1v1(joueur, adversaire): StratsResultats[joueur["strategie"]][2][Iteration][2] += ans_prison[0] StratsResultats[adversaire["strategie"]][2][Iteration][1] += 1 StratsResultats[adversaire["strategie"]][2][Iteration][2] += ans_prison[0] - + joueur["historique_etats"].append(etatj) adversaire["historique_etats"].append(etata) joueur["historique_strategies"].append(stratj) adversaire["historique_strategies"].append(strata) - + joueur["etat"] = etatj adversaire["etat"] = etata @@ -186,10 +183,10 @@ def partie1v1(joueur, adversaire): return ans_prison def partie8tours(x,y): - """ - Coord -> NoneType - - Effectue huit parties 1v1 entre le joueur et chacun de ses voisins l'un après l'autre + """ + Coord -> NoneType + + Effectue huit parties 1v1 entre le joueur et chacun de ses voisins l'un après l'autre """ for i in range (-1,2): for j in range (-1,2): #(i,j) sont les coordonnées de l'adversaire @@ -206,13 +203,13 @@ def partie_globale(): for i in range(TailleGrilleX): for j in range(TailleGrilleY): partie8tours(i,j) - + # Changement des stratégies # On parcourt une copie de la grille pour avoir accès aux anciennes stratégies et non pas aux nouvelles adoptées copie_grille = np.copy(Grille) - for x in range(len(copie_grille)): + for x in range(len(copie_grille)): for y in range(len(copie_grille[0])): #(x,y) : joueur dont on va modifier la stratégie, si besoin min_prison = copie_grille[x][y]["annees_de_prison"] @@ -223,12 +220,12 @@ def partie_globale(): if min_prison > copie_grille[x+i][y+j]["annees_de_prison"]: new_strat = copie_grille[x+i][y+j]["strategie"] Grille[x][y]["strategie"] = new_strat # on modifie la stratégie du joueur dans la Grille et pas dans la copie - + # Réinitialisation du nb d'années de prison for i in range(TailleGrilleX): for j in range(TailleGrilleY): Grille[i][j]['annees_de_prison'] = 0 - + return Grille @@ -245,10 +242,8 @@ def matrice_init_vide(): def matrice_init_meme_strat(): """ - int -> array - Index: 0 - + Crée la matrice des joueurs où chacun a la même stratégie mais commence avec des états différents, générés aléatoirement """ @@ -267,15 +262,13 @@ def matrice_init_meme_strat(): def matrice_init_nie_sauf_un(): """ - int -> array - Index: 1 Crée la matrice des joueurs tel que chaque joueurs nie, sauf un qui avoue. Chaque joueur à la même stratégie """ - + histo_strat = [StratParDefaut] matrice = matrice_init_vide() @@ -292,8 +285,6 @@ def matrice_init_nie_sauf_un(): def matrice_init_avoue_sauf_un(): """ - int -> array - Index: 2 Créer la matrice des joueurs tel que chaque joueur avoue, @@ -316,20 +307,20 @@ def matrice_init_avoue_sauf_un(): def matrice_init_equitable(): """ - Crée la matrice des joueurs tel que le probabilité d'apparition de chaque + Index: 3 + + Crée la matrice des joueurs tel que le probabilité d'apparition de chaque stratégie est équitable. Les états initiaux de chaque joueur sont aléatoires. - - Index: 3 """ matrice_strat = np.full((TailleGrilleX, TailleGrilleY), -1, dtype=int) nb_de_joueurs_de_chaque = int((TailleGrilleX*TailleGrilleY)/len(ListeStrategies)) - + places_vides = TailleGrilleX*TailleGrilleY for e in range(len(ListeStrategies)): count_joueurs = 0 - + while count_joueurs <= nb_de_joueurs_de_chaque: index_aleatoirex = random.randint(0,TailleGrilleX-1) index_aleatoirey = random.randint(0,TailleGrilleY-1) @@ -358,8 +349,6 @@ def matrice_init_equitable(): def matrice_init_pourcents_choisis(): """ - list[float] -> array - Index: 4 ListePourcents contient des float de 0.0 à 1.0. @@ -369,13 +358,13 @@ def matrice_init_pourcents_choisis(): """ if (len(ListePourcents) != len(ListeStrategies)): print("Erreur: matrice_init_pourcents_choisis: liste_pourcent est de taille incorrecte!") - + matrice_strat = np.full((TailleGrilleX, TailleGrilleY), -1, dtype=int) list_nb_joueurs_de_chaque = list() for i in range(len(ListePourcents)): list_nb_joueurs_de_chaque.append((TailleGrilleX*TailleGrilleY)*ListePourcents[i]) - + places_vides = TailleGrilleX*TailleGrilleY for e in range(len(ListePourcents)): count_joueurs = 0 @@ -390,7 +379,7 @@ def matrice_init_pourcents_choisis(): matrice_strat[index_aleatoirex][index_aleatoirey] = e count_joueurs += 1 places_vides -= 1 - + for i in range(TailleGrilleY): #on vérifie qu'il n'y a pas d'index vides for j in range(TailleGrilleX): #si oui, on le rempli avec une strat aléatoire if matrice_strat[i][j] == 0: @@ -411,74 +400,58 @@ def matrice_init_pourcents_choisis(): def strat_toujours_nier(joueur, adversaire): """ - Joueur^2 -> int - Index: 0 - Toujours nier (coopération) """ return 0 # 0 : coop - + def strat_toujours_avouer(joueur, adversaire): """ - Joueur^2 -> int - Index: 1 - Toujours avouer (trahir) """ return 1 #1 : traître def strat_altern(joueur, adversaire): """ - Joueur^2 -> int - Index: 2 - Le joueur alterne entre nier et avouer """ return 1 - joueur['etat'] - + def strat_precedent_adversaire(joueur, adversaire): """ - Joueur^2 -> int - Index: 3 - Le joueur avoue/nie si durant la partie locale précédente, son adversaire avait avoué/nié (on utilise l'hisorique des états) """ return adversaire['historique_etats'][len(adversaire['historique_etats'])-1] == 0 - + def strat_principal_adversaire(joueur, adversaire): """ - Joueur^2 -> int - Index: 4 - Le joueur avoue/nie si l’adversaire avait majoritairement avoué/nié durant ses parties précédentes (on utilise l'hisorique des états) Si aucun état n’est majoritaire, la coopération l’emporte (le joueur nie) """ - + s = 0 # somme des entiers représentant les états for i in adversaire['historique_etats']: s += i - + if len(adversaire['historique_etats']) == 0: return 0 - elif (s/len(adversaire['historique_etats'])) > 0.5: + elif (s/len(adversaire['historique_etats'])) > 0.5: return 1 else: return 0 - + def strat_meilleur_gain (joueur, adversaire): """ - Joueur^2 -> int Index : 5 - Le joueur adopte l'état de l'adversaire ayant obtenu le meilleur gain (= le moins d'années de prison) + Le joueur adopte l'état de l'adversaire ayant obtenu le meilleur gain (= le moins d'années de prison) """ max_gain = joueur['annees_de_prison'] nveau_etat = joueur['etat'] @@ -495,26 +468,24 @@ def strat_meilleur_gain (joueur, adversaire): ###################### #INTERFACE GRAPHIQUE UTILISATEUR (GUI) ###################### -# Fonctions pour command -###################### # Initialise la fenetre principale -fenetre=Tk() +fenetre = Tk() # Taille en abscisse de la matrice -X=IntVar(fenetre) +X = IntVar(fenetre) # Taille en ordonnée de la matrice -Y=IntVar(fenetre) +Y = IntVar(fenetre) # Strategie definie pour le type 1 -Strat=IntVar(fenetre) +Strat = IntVar(fenetre) # Type de matrice selectionné par l'user -Var_choix=IntVar(fenetre) +Var_choix = IntVar(fenetre) # Nombre d'itérations maximum -It=IntVar(fenetre) +It = IntVar(fenetre) # Vitesse de défilement des images dans l'affichage dynamique en millisecondes, pré-variable IntVar Vit = IntVar() @@ -524,7 +495,7 @@ def affichage_fenetre_infos(): S'il y a eu clic sur le bouton "Infos", affiche une fenetre contenant le détail de chaque stratégie et de chaque type de matrice de départ. """ - fenetre_infos=Tk() + fenetre_infos = Tk() Label(fenetre_infos, text="INFORMATIONS").grid() Label(fenetre_infos, text=" ").grid(sticky=W) Label(fenetre_infos, text="STRATEGIES :").grid(sticky=W) @@ -545,12 +516,12 @@ def affichage_fenetre_infos(): Label(fenetre_infos, text="Type 4 : Les pourcentages de chaque stratégie sont choisis, les états de départ sont aléatoires.").grid(sticky=W) fenetre_infos.mainloop() - + def affichage_combobox(): """ - S'il y a eu clic sur le bouton, - on affiche un combobox pour selectionner - la stratégie par défaut voulue + S'il y a eu clic sur le bouton, + on affiche un combobox pour selectionner + la stratégie par défaut voulue """ global Strat Label(fenetre, text="Stratégie n°").grid(row=5, column=0, sticky=E) @@ -558,9 +529,9 @@ def affichage_combobox(): def Interface(): """ - Affiche l'interface graphique utilisateur - qui permet de saisir les paramètres de la - simulation + Affiche l'interface graphique utilisateur + qui permet de saisir les paramètres de la + simulation """ global X @@ -578,7 +549,7 @@ def Interface(): Label(fenetre, text="Choisir le type de la matrice initiale:").grid(row=4, columnspan = 2) - + Radiobutton(fenetre, text="Type 0", variable=Var_choix, value=0, command=affichage_combobox).grid(row=5, sticky=W) Radiobutton(fenetre, text="Type 1", variable=Var_choix, value=1, command=affichage_combobox).grid(row=6, sticky=W) Radiobutton(fenetre, text="Type 2", variable=Var_choix, value=2, command=affichage_combobox).grid(row=7, sticky=W) @@ -611,8 +582,8 @@ def init_complete(): ListeGenGrille.append(matrice_init_nie_sauf_un) # 1 ListeGenGrille.append(matrice_init_avoue_sauf_un) # 2 ListeGenGrille.append(matrice_init_equitable) # 3 - ListeGenGrille.append(matrice_init_pourcents_choisis) # 4 - + ListeGenGrille.append(matrice_init_pourcents_choisis) # 4 + ListeStrategies.append(strat_toujours_nier) # 0 ListeStrategies.append(strat_toujours_avouer) # 1 ListeStrategies.append(strat_altern) # 2 @@ -622,7 +593,7 @@ def init_complete(): global Grille global StratsResultats - + global Vitesse Vitesse = Vit.get() @@ -630,7 +601,6 @@ def init_complete(): global TailleGrilleY TailleGrilleX=X.get() TailleGrilleY=Y.get() - print(TailleGrilleX) global TypeGrilleInitiale TypeGrilleInitiale=Var_choix.get() @@ -655,25 +625,25 @@ def init_complete(): def simulation(): global Iteration global HistoriqueGrilles - + Iteration = 0 while Iteration <= MaxIterations: HistoriqueGrilles.append(copy.deepcopy(Grille)) Iteration += 1 - + for i in range(len(StratsResultats)): StratsResultats[i][2].append([0, 0, 0]) - + partie_globale() - + for i in range(len(StratsResultats)): for x in range(TailleGrilleX): for y in range(TailleGrilleY): if Grille[x][y]["strategie"] == i: StratsResultats[i][2][Iteration][0] += 1 - + return Grille @@ -682,38 +652,45 @@ def simulation(): def matRecup(i, param): - """array*str-> array - Récupère la grille avec seulement la valeur de la clef "stratégie" pour chaque joueur , à litération i voulue""" - #on initialise la matrice résultat avec que des 0 + """ + array*str-> array + Récupère la grille avec seulement la valeur de la clef "stratégie" pour chaque joueur , à litération i voulue + """ + + # on initialise la matrice résultat avec que des 0 matR = np.random.randint(0,1,(TailleGrilleX,TailleGrilleY)) - - - #on récupère la grille à l'itération i voulue + + + # on récupère la grille à l'itération i voulue matrice = HistoriqueGrilles[i] - - #on parcourt toute la grille + + # on parcourt toute la grille for ligne in range (0,TailleGrilleX): #int ligne for colonne in range (0, TailleGrilleY): #int colonne - matR[ligne][colonne]=matrice[ligne][colonne][param] #on place à l'indice (ligne,colonne) de matR la valeur de la clef "stratégie" de la grille pour l'individu (ligne,colonne) - + # on place à l'indice (ligne,colonne) de matR la valeur de la clef "stratégie" de la grille pour l'individu (ligne,colonne) + matR[ligne][colonne] = matrice[ligne][colonne][param] + return matR def afficher_strat_dynamique(): - """Affichage dynamique de l'évolution de la stratégie dans une fenêtre, avec des couleurs""" - fig=plt.figure() + """ + Affichage dynamique de l'évolution de la stratégie dans une fenêtre, avec des couleurs + """ + + fig = plt.figure() fig.suptitle('Animation des stratégies') cmap = mpl.colors.ListedColormap(["b","r" ,"black" ,"g" ,"purple", "yellow"]) - bounds=[0,1,2,3,4,5,6] - norm=mpl.colors.BoundaryNorm(bounds, cmap.N) - img=plt.imshow(matRecup(0, 'strategie'), interpolation = "nearest", cmap = cmap , norm = norm) - - cb=plt.colorbar(img , cmap=cmap , norm=norm , boundaries = bounds , ticks=bounds) + bounds = [0,1,2,3,4,5,6] + norm = mpl.colors.BoundaryNorm(bounds, cmap.N) + img = plt.imshow(matRecup(0, 'strategie'), interpolation = "nearest", cmap = cmap , norm = norm) + + cb = plt.colorbar(img , cmap=cmap , norm=norm , boundaries = bounds , ticks=bounds) labels = np.arange(0, 6, 1) cb.set_ticklabels(labels) - + def update(next_iteration,*args): img.set_array(matRecup(next_iteration , 'strategie')) return [img] @@ -721,23 +698,26 @@ def afficher_strat_dynamique(): anim = animation.FuncAnimation(fig, update, frames=range(MaxIterations), interval=500, repeat = False) plt.show(block = True) - + def afficher_etat_dynamique(): - """Affichage dynamique de l'évolution des états des individus dans une fenêtre, avec des couleurs""" - fig=plt.figure() + """ + Affichage dynamique de l'évolution des états des individus dans une fenêtre, avec des couleurs + """ + + fig = plt.figure() fig.suptitle('Animation des états') cmap = mpl.colors.ListedColormap(["black","white"]) - bounds=[0,1,2] - norm=mpl.colors.BoundaryNorm(bounds, cmap.N) - img=plt.imshow(matRecup(0, 'etat'), interpolation = "nearest", cmap = cmap , norm = norm) - - cb=plt.colorbar(img , cmap=cmap , norm=norm , boundaries = bounds , ticks=bounds) + bounds = [0,1,2] + norm = mpl.colors.BoundaryNorm(bounds, cmap.N) + img = plt.imshow(matRecup(0, 'etat'), interpolation = "nearest", cmap = cmap , norm = norm) + + cb = plt.colorbar(img , cmap=cmap , norm=norm , boundaries = bounds , ticks=bounds) labels = np.arange(0, 2, 1) cb.set_ticklabels(labels) - + def update(next_iteration,*args): img.set_array(matRecup(next_iteration , 'etat')) return [img] @@ -748,46 +728,45 @@ def afficher_etat_dynamique(): def affichage_strats_resultats_totaux(): - """array->graph - Retourne les diagrammes en baton qui mettent en évidence le nombre moyen d'années - de prison en fonction de la stratégie et le nombre d'utilisation de chaque stratégies """ - - #initialisation des paramètres - #list gain + """ + Retourne les diagrammes en baton qui mettent en évidence le nombre moyen d'années + de prison en fonction de la stratégie et le nombre d'utilisation de chaque stratégies + """ + + # initialisation des paramètres gain=[] - #list strat stratUtili=[] - + #nb_utilisations utilisateurs=list() - - #utilisateurs[strat][iter] = nombre d'utilisateur dune stratégie à une itération - - #iteration + + #utilisateurs[strat][iter] = nombre d'utilisateur d'une stratégie à une itération + iteration=[] - #on ajoute des 0 dans les listes gain() et stratUtili() autant qu'il y a de stratégies + + # on ajoute des 0 dans les listes gain() et stratUtili() autant qu'il y a de stratégies for i in range(6): gain.append(0) stratUtili.append(0) - for i in range(0,len(ListeStrategies)): #on parcourt les stratégies - stratUtili[i]=StratsResultats[i][0] #L'indice i de la liste stratUtili vaut le nombre total d'utilisations de la stratégie i - if StratsResultats[i][0]==0: #si la stratégie a été utilisée 0 fois - gain[i] #le gain ne change pas + for i in range(0,len(ListeStrategies)): # on parcourt les stratégies + stratUtili[i]=StratsResultats[i][0] # L'indice i de la liste stratUtili vaut le nombre total d'utilisations de la stratégie i + if StratsResultats[i][0]==0: # si la stratégie a été utilisée 0 fois + pass # le gain ne change pas else: gain[i]=StratsResultats[i][1]/StratsResultats[i][0] #Sinon le gain pour la stratégie i vaut le nombre d'années de prison pour une stratégie divisée par son utilisation (pour avoir une moyenne) - utilisateurs.append([]) #on initialise une liste vide dans la liste utilisateurs afin de s'en servir juste après - - for i in range(0,MaxIterations+1): #on parcourt toutes les itréations - for j in range(0,len(ListeStrategies)): #on parcourt toutes les stratégies - utilisateurs[j].append(StratsResultats[j][2][i][0]) #on ajoute à lindice j de la liste utilisateurs le nombre d'utilisateurs d'une stratégie donnée j à l'itération i - + utilisateurs.append([]) # on initialise une liste vide dans la liste utilisateurs afin de s'en servir juste après + + for i in range(0,MaxIterations+1): # on parcourt toutes les itréations + for j in range(0,len(ListeStrategies)): # on parcourt toutes les stratégies + utilisateurs[j].append(StratsResultats[j][2][i][0]) # on ajoute à lindice j de la liste utilisateurs le nombre d'utilisateurs d'une stratégie donnée j à l'itération i + iteration.append(i) #on ajoute à la liste itération l'indice i - + Strat=('0','1', '2','3' ,'4','5') - + x_pos = np.arange(len(Strat)) - + plt.subplot(221) plt.title("Nombre d'adoptions de chaque stratégie") plt.bar(x_pos, stratUtili, align='center' , color=CouleursStrat) @@ -795,46 +774,35 @@ def affichage_strats_resultats_totaux(): plt.xlabel("Stratégies") plt.ylabel("Nombre individus ayant adopté stratégie") plt.xticks(x_pos,Strat) - + plt.subplot(222) plt.title("Nombre moyen d'années de prison de chaque stratégie") plt.bar(x_pos, gain, align='center', color=CouleursStrat ) - + plt.xlabel("Stratégies") plt.ylabel("Nombre moyen d'années de prison ") plt.xticks(x_pos,Strat) - plt.subplot(223) + plt.subplot(223) plt.title("Evolution du nombre d'utilisateurs de chaque stratégie au cours des itérations") plt.xlabel('Iterations') plt.ylabel("Nombre utilisateurs") - + for i in range(len(ListeStrategies)): plt.plot(iteration,utilisateurs[i], CouleursStrat[i] ,linewidth=5 ,label="Stratégie" + str(i)) plt.show() - plt.legend() + plt.legend() + ####################### # SCRIPT ####################### -Interface() -init_complete() -simulation() -afficher_etat_dynamique() -afficher_strat_dynamique() -affichage_strats_resultats_totaux() +if __name__ == '__main__': + Interface() + init_complete() + simulation() + afficher_etat_dynamique() + afficher_strat_dynamique() + affichage_strats_resultats_totaux() - - -""" -def _ext(M): - K = np.ndarray((TailleGrilleX, TailleGrilleY)) - - for x in range(len(M)): - for y in range(len(M[0])): - K[x][y] = M[x][y]["strategie"] - - return K -print(_ext(simulation())) -"""