123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- from Outils import *
- from Outils.Arbre import *
- from Outils.Moteur_de_jeu import Partie
- from Outils.Moteur_de_jeu.Partie import *
- import math
- from random import shuffle
- import numpy
- from Outils.Arbre import *
- from Outils.Moteur_de_jeu import Joueur
- from Outils.Moteur_de_jeu.Joueur import *
- from Outils import IA_MinMax
- from Outils.IA_MinMax import *
- from time import time
- from fct_eval_elric import *
- from Outils.IA_alphabeta import *
- #Il y a 3 types de tournois différents :
- #par élimination directe, en toutes rondes ou en rondes suisses
- # toutes rondes : chacun joue contre tous les autres
- # rondes suisses : les joueurs jouent contre des adversaires ayant un score proche du leur, le nombre de rondes (donc de matchs de chaque joueur) est fixé à l'avance
- #pour les utiliser, "tournoi" fait une élimination directe
- #tournoi2 fait un toutes rondes avec des fonctions, tournoi3 directement avec les intelligences artificielles
- #rondes_suisses en rondes suisses
- def match (joueurA, joueurB, k = 2) : # Baptiste 31 05
- """prend 2 intelligences artificielles en paramètres, ainsi que le nombre minimum de partie pour gagner le match"""
- joueurA.nom = "A"
- joueurB.nom = "B"
- wins = numpy.zeros (2)
- for i in range (0, 2*(k)) :
- if wins[0] < k and wins[1] < k :
- Global.partie = Partie(joueurA, joueurB, False, "")
- vainqueur = Global.partie.demarrer()
- if vainqueur.nom == "A" :
- wins[0] = wins[0]+1
- else :
- wins[1] = wins[1] + 1
- if wins[0] > wins [1] :
- return (joueurA)
- else :
- return (joueurB)
- def max_tab (t) :
- """indice maximum d'un tableau"""
- l = len(t)
- k = t[0]
- x = 0
- for i in range (l) :
- if t[i] > k :
- x = i
- return (x)
- def etablir_classement(tab_scores) :
- """ Etablit le classement à partir du score """
- n = len(tab_scores)
- tab = [(tab_scores[i],i) for i in range(n)]
- tab.sort()
- tab_classement = [0] * n
- for i in range(n) :
- tab_classement[tab[i][1]] = n - 1 - i
- return tab_classement
- def tournoi (intelligences) :
- """prend en compte des intelligences artificielles, qui jouent toutes les unes contre les autres"""
- n = len(intelligences)
- joueurs = [0]*n
- for i in range (n) :
- joueurs[i] = intelligences[i]
- scores = [0]*n
- for i in range (n) :
- for j in range (i+1, n) :
- vainqueur = match (joueurs[i], joueurs[j], 2)
- if vainqueur == joueurs[i] :
- scores[i] = scores[i] + 1
- else :
- scores[j] = scores[j] + 1
- return (etablir_classement(scores))
- def conversion(fonctions) :
- """Convertit des fonctions d'évaluation en intelligences artificielles MinMax"""
- n = len(fonctions)
- joueurs = [0]*n
- for i in range (n) :
- joueurs[i] = IA_minmax_alpha_beta("MinMax 2", fonctions[i], 2)
- return (joueurs)
- def distance_bord (position) :
- """distance au bord"""
- return (min (position[0], 9-position[0]))
- def tournoi2(fonctions) :
- """tournoi de type élimination directe, à partir de fonctions"""
- return (tournoi3(conversion(fonctions)))
- def tournoi3 (joueurs) :
- """tournoi de type élimination directe, à partir d'intelligences artificielles"""
- n = len(joueurs)
- if n == 1 :
- return (joueurs[0])
- while len(joueurs) != 1 :
- n = len(joueurs)
- if n%2 == 0 : #si il y a un nombre de joueurs pair, on les fait se rencontrer
- k = n//2
- joueurs_vainqueurs = [0]*(k)
- for i in range (0, k) :
- vainqueur = match (joueurs[2*i], joueurs[2*i+1], 2)
- joueurs_vainqueurs[i] = vainqueur
- joueurs = joueurs_vainqueurs
- else : #si il y a un nombre de joueurs impair, on les fait se rencontrer, le dernier est bye, considéré gagnant
- k = (n-1)//2
- joueurs_vainqueurs = [0]*(k+1)
- for i in range (0, k) :
- vainqueur = match (joueurs[2*i], joueurs[2*i+1], 2)
- joueurs_vainqueurs[i] = vainqueur
- joueurs_vainqueurs[-1] = joueurs[-1]
- joueurs = joueurs_vainqueurs
- t = match (joueurs[0], joueurs[1], 2)
- return joueurs[0]
- def false_sum (tableau) :
- """compte le nombre de 1 d'un tableau"""
- n = len(tableau)
- s = 0
- for i in range (n) :
- if tableau[i] == 1 :
- s = s+1
- return (s)
- """un dernier élément à régler serait le fait que les joueurs ne rejouent pas contre les mêmes adversaires, ce qui n'est pas vérifié ici, est supposé fait par appariement"""
- """le problème semble venir de la partie d'identification avec le vainqueur dans cette fonction-ci"""
- def rondes_suisses (joueurs, nombre_rondes = None) :
- """tournoi en rondes suisses, des IA en paramètres et le nombre de rondes"""
- n = len (joueurs)
- if nombre_rondes == None :
- nombre_rondes = int(log(len(joueurs), 2) + 1 )
- p = nombre_rondes
- matrice_matchs = numpy.zeros((n,n))
- matrice_scores = numpy.zeros((n,p)) #(appariement prend en compte les joueurs, la matrice des scores, la ronde (utile : non))
- for i in range (0, p) :
- t_init = time()
- if n%2 == 0 : #si il y a un nombre de joueurs pair, on les fait se rencontrer
- k = n//2 #appariement renvoie les indices des joueurs qui se rencontrent
- appariements = appariement(joueurs, matrice_scores, i)
- for j in range (0, k) :
- J0 = appariements[j][0]
- J1 = appariements[j][1]
- vainqueur = match (joueurs[J0], joueurs[J1], 2) #J0 et J1 sont des indices
- matrice_matchs[J0][J1] = 1
- matrice_matchs[J1][J0] = 1
- if vainqueur == joueurs[J0] :
- matrice_scores[J0][i] = +1
- matrice_scores[J1][i] = -1
- else :
- matrice_scores[J0][i] = -1
- matrice_scores[J1][i] = +1
- else :
- k = (n-1)//2
- appariements = appariement(joueurs, matrice_scores, i)
- for j in range (0, k) :
- J0 = appariements[j][0]
- J1 = appariements[j][1]
- vainqueur = match (joueurs[J0], joueurs[J1], 2)
- matrice_matchs[J0][J1] = 1
- matrice_matchs[J1][J0] = 1
- if vainqueur == joueurs[J0] :
- matrice_scores[J0][i] = +1
- matrice_scores[J1][i] = -1
- else :
- matrice_scores[J0][i] = -1
- matrice_scores[J1][i] = +1
- matrice_scores[appariements[-1]][i] = +1
- scores_finaux = [0]*n
- for l in range (n) :
- scores_finaux[l] = false_sum(matrice_scores[l])
- return scores_finaux
- def egalite_tableau (t1, t2) :
- """vérifie si deux tableaux sont égaux"""
- c = 0
- b = True
- n = len(t1)
- while c < n and b == True :
- if t1[c] != t2[c] :
- b = False
- c = c + 1
- return (b)
- def appariement (joueurs, matrice_des_scores, ronde) :
- """la fonction qui à partir des scores renvoie quels matchs sont à faire"""
- n = len(joueurs) # si il y a un nombre de joueurs impairs, le dernier est 'bye' et gagne automatiquement
- apparies = [-1]*n
- if n%2 == 0 : #nombre pair de joueurs
- compteur = 0
- k = n//2
- liste_matchs = [[ 0 for i in range (2)] for j in range (k)]
- for i in range (n) : #on part du i et on on vérifie lesquels ont le même score (en partant du suivant)
- if apparies[i] == -1 : #on ne continue que s'il n'est pas déjà apparié
- for j in range (i+1, n) :
- if apparies[j] == -1 :
- if egalite_tableau(matrice_des_scores[i], matrice_des_scores[j]) == True :
- liste_matchs[compteur][0] = i
- liste_matchs[compteur][1] = j
- apparies[i] = 1
- apparies[j] = 1 #tous ceux qui ont des scores similaires sont apparies faire un test while sur la somme du tableau apparies jusqu'à n
- compteur = compteur + 1
- break
- compteur_tolerance = 1
- while sum(apparies) < n :
- for i in range (sommenegative(apparies)) : #on remet la même chose car on remplit des appariements
- depart = find_meilleur(apparies, matrice_des_scores) #en fait ça sert à apparier les joueurs qui n'ont pas exactement les mêmes scores, mais ayant des scores "similaires"
- for j in range (n) :
- if apparies[j] == -1 and j!= depart :
- if quasi_similitude (matrice_des_scores[depart], matrice_des_scores[j], compteur_tolerance) == True : #ça fait la même chose, au début on accepte s'il y a une différence de score
- liste_matchs[compteur][0] = depart
- liste_matchs[compteur][1] = j
- apparies[depart] = 1
- apparies[j] = 1
- compteur = compteur +1
- break
- compteur_tolerance = compteur_tolerance + 1 #si tout n'est pas déjà fait, on passe au degré de tolérance suivant (2 différences, 3...)
- return (liste_matchs)
- else :
- #Nombre de joueurs IMPAIR
- #c'est excatement la même chose mais le dernier est 'bye' et gagne automatiquement
- compteur = 0
- k = (n-1)//2
- liste_matchs = [[ 0 for i in range (2)] for j in range (k+1)]
- for i in range (n) :
- if apparies[i] == -1 :
- for j in range (i+1, n) :
- if apparies[j] == -1 :
- if egalite_tableau(matrice_des_scores[i], matrice_des_scores[j]) == True :
- liste_matchs[compteur][0] = i
- liste_matchs[compteur][1] = j
- apparies[i] = 1
- apparies[j] = 1 #tous ceux qui ont des scores similaires sont apparies faire un test while sur la somme du tableau apparies jusqu'à n
- compteur = compteur + 1
- break
- compteur_tolerance = 1
- while sum(apparies) < (n-2) :
- #"""LA IL Y A UNE DIFFERENCE""" on ne peut nas atteindre n, car un ne sera jamais apparie
- for i in range (sommenegative(apparies)-1) :
- #on remet la même chose car on remplit des appariements
- depart = find_meilleur(apparies, matrice_des_scores) #en fait ça sert à apparier les joueurs qui n'ont pas exactement les mêmes scores, mais ayant des scores "similaires"
- for j in range (n) :
- if apparies[j] == -1 and j!= depart :
- if quasi_similitude (matrice_des_scores[depart], matrice_des_scores[j], compteur_tolerance) == True : #ça fait la même chose, au début on accepte s'il y a une différence de score
- liste_matchs[compteur][0] = depart
- liste_matchs[compteur][1] = j
- apparies[depart] = 1
- apparies[j] = 1
- compteur = compteur +1
- break
- compteur_tolerance = compteur_tolerance + 1 #si tout n'est pas déjà fait, on passe au degré de tolérance suivant (2 différences, 3...)
- liste_matchs[-1] = find (apparies, -1)
- return liste_matchs
- def quasi_similitude (tableau1, tableau2, tolerance) :
- """renvoie true si le nombre de différences dans les tableaux est inférieur ou égal à la tolérance"""
- l = len(tableau1)
- s = 0
- for i in range (l) :
- if tableau1[i] != tableau2[i] :
- s = s+1
- return (s <= tolerance)
- def find(tableau, valeur) :
- n = len(tableau)
- for i in range (n) :
- if tableau[i] == valeur :
- return (i)
-
- def sommenegative (tableau) :
- """compte le nombre de -1"""
- n = len(tableau)
- s = 0
- for i in range (n) :
- if tableau[i] == -1 :
- s = s+1
- return (s)
- def find_meilleur (apparies, matrice_scores) :
- """renvoie la personne avec le meilleur score et son indice, parmi ceux qui ne sont pas appariés"""
- n = len(apparies)
- scores = [0]*n
- p = len(matrice_scores[0])
- for i in range (n) :
- if apparies[i] == 1 :
- scores[i] = -p-1
- else :
- scores[i] = sum(matrice_scores[i])
- sm = max(scores)
- return(find(scores, sm))
|