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))