match_fonctionnels.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. from Outils import *
  2. from Outils.Arbre import *
  3. from Outils.Moteur_de_jeu import Partie
  4. from Outils.Moteur_de_jeu.Partie import *
  5. import math
  6. from random import shuffle
  7. import numpy
  8. from Outils.Arbre import *
  9. from Outils.Moteur_de_jeu import Joueur
  10. from Outils.Moteur_de_jeu.Joueur import *
  11. from Outils import IA_MinMax
  12. from Outils.IA_MinMax import *
  13. from time import time
  14. from fct_eval_elric import *
  15. from Outils.IA_alphabeta import *
  16. #Il y a 3 types de tournois différents :
  17. #par élimination directe, en toutes rondes ou en rondes suisses
  18. # toutes rondes : chacun joue contre tous les autres
  19. # 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
  20. #pour les utiliser, "tournoi" fait une élimination directe
  21. #tournoi2 fait un toutes rondes avec des fonctions, tournoi3 directement avec les intelligences artificielles
  22. #rondes_suisses en rondes suisses
  23. def match (joueurA, joueurB, k = 2) : # Baptiste 31 05
  24. """prend 2 intelligences artificielles en paramètres, ainsi que le nombre minimum de partie pour gagner le match"""
  25. joueurA.nom = "A"
  26. joueurB.nom = "B"
  27. wins = numpy.zeros (2)
  28. for i in range (0, 2*(k)) :
  29. if wins[0] < k and wins[1] < k :
  30. Global.partie = Partie(joueurA, joueurB, False, "")
  31. vainqueur = Global.partie.demarrer()
  32. if vainqueur.nom == "A" :
  33. wins[0] = wins[0]+1
  34. else :
  35. wins[1] = wins[1] + 1
  36. if wins[0] > wins [1] :
  37. return (joueurA)
  38. else :
  39. return (joueurB)
  40. def max_tab (t) :
  41. """indice maximum d'un tableau"""
  42. l = len(t)
  43. k = t[0]
  44. x = 0
  45. for i in range (l) :
  46. if t[i] > k :
  47. x = i
  48. return (x)
  49. def etablir_classement(tab_scores) :
  50. """ Etablit le classement à partir du score """
  51. n = len(tab_scores)
  52. tab = [(tab_scores[i],i) for i in range(n)]
  53. tab.sort()
  54. tab_classement = [0] * n
  55. for i in range(n) :
  56. tab_classement[tab[i][1]] = n - 1 - i
  57. return tab_classement
  58. def tournoi (intelligences) :
  59. """prend en compte des intelligences artificielles, qui jouent toutes les unes contre les autres"""
  60. n = len(intelligences)
  61. joueurs = [0]*n
  62. for i in range (n) :
  63. joueurs[i] = intelligences[i]
  64. scores = [0]*n
  65. for i in range (n) :
  66. for j in range (i+1, n) :
  67. vainqueur = match (joueurs[i], joueurs[j], 2)
  68. if vainqueur == joueurs[i] :
  69. scores[i] = scores[i] + 1
  70. else :
  71. scores[j] = scores[j] + 1
  72. return (etablir_classement(scores))
  73. def conversion(fonctions) :
  74. """Convertit des fonctions d'évaluation en intelligences artificielles MinMax"""
  75. n = len(fonctions)
  76. joueurs = [0]*n
  77. for i in range (n) :
  78. joueurs[i] = IA_minmax_alpha_beta("MinMax 2", fonctions[i], 2)
  79. return (joueurs)
  80. def distance_bord (position) :
  81. """distance au bord"""
  82. return (min (position[0], 9-position[0]))
  83. def tournoi2(fonctions) :
  84. """tournoi de type élimination directe, à partir de fonctions"""
  85. return (tournoi3(conversion(fonctions)))
  86. def tournoi3 (joueurs) :
  87. """tournoi de type élimination directe, à partir d'intelligences artificielles"""
  88. n = len(joueurs)
  89. if n == 1 :
  90. return (joueurs[0])
  91. while len(joueurs) != 1 :
  92. n = len(joueurs)
  93. if n%2 == 0 : #si il y a un nombre de joueurs pair, on les fait se rencontrer
  94. k = n//2
  95. joueurs_vainqueurs = [0]*(k)
  96. for i in range (0, k) :
  97. vainqueur = match (joueurs[2*i], joueurs[2*i+1], 2)
  98. joueurs_vainqueurs[i] = vainqueur
  99. joueurs = joueurs_vainqueurs
  100. else : #si il y a un nombre de joueurs impair, on les fait se rencontrer, le dernier est bye, considéré gagnant
  101. k = (n-1)//2
  102. joueurs_vainqueurs = [0]*(k+1)
  103. for i in range (0, k) :
  104. vainqueur = match (joueurs[2*i], joueurs[2*i+1], 2)
  105. joueurs_vainqueurs[i] = vainqueur
  106. joueurs_vainqueurs[-1] = joueurs[-1]
  107. joueurs = joueurs_vainqueurs
  108. t = match (joueurs[0], joueurs[1], 2)
  109. return joueurs[0]
  110. def false_sum (tableau) :
  111. """compte le nombre de 1 d'un tableau"""
  112. n = len(tableau)
  113. s = 0
  114. for i in range (n) :
  115. if tableau[i] == 1 :
  116. s = s+1
  117. return (s)
  118. """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"""
  119. """le problème semble venir de la partie d'identification avec le vainqueur dans cette fonction-ci"""
  120. def rondes_suisses (joueurs, nombre_rondes = None) :
  121. """tournoi en rondes suisses, des IA en paramètres et le nombre de rondes"""
  122. n = len (joueurs)
  123. if nombre_rondes == None :
  124. nombre_rondes = int(log(len(joueurs), 2) + 1 )
  125. p = nombre_rondes
  126. matrice_matchs = numpy.zeros((n,n))
  127. matrice_scores = numpy.zeros((n,p)) #(appariement prend en compte les joueurs, la matrice des scores, la ronde (utile : non))
  128. for i in range (0, p) :
  129. t_init = time()
  130. if n%2 == 0 : #si il y a un nombre de joueurs pair, on les fait se rencontrer
  131. k = n//2 #appariement renvoie les indices des joueurs qui se rencontrent
  132. appariements = appariement(joueurs, matrice_scores, i)
  133. for j in range (0, k) :
  134. J0 = appariements[j][0]
  135. J1 = appariements[j][1]
  136. vainqueur = match (joueurs[J0], joueurs[J1], 2) #J0 et J1 sont des indices
  137. matrice_matchs[J0][J1] = 1
  138. matrice_matchs[J1][J0] = 1
  139. if vainqueur == joueurs[J0] :
  140. matrice_scores[J0][i] = +1
  141. matrice_scores[J1][i] = -1
  142. else :
  143. matrice_scores[J0][i] = -1
  144. matrice_scores[J1][i] = +1
  145. else :
  146. k = (n-1)//2
  147. appariements = appariement(joueurs, matrice_scores, i)
  148. for j in range (0, k) :
  149. J0 = appariements[j][0]
  150. J1 = appariements[j][1]
  151. vainqueur = match (joueurs[J0], joueurs[J1], 2)
  152. matrice_matchs[J0][J1] = 1
  153. matrice_matchs[J1][J0] = 1
  154. if vainqueur == joueurs[J0] :
  155. matrice_scores[J0][i] = +1
  156. matrice_scores[J1][i] = -1
  157. else :
  158. matrice_scores[J0][i] = -1
  159. matrice_scores[J1][i] = +1
  160. matrice_scores[appariements[-1]][i] = +1
  161. scores_finaux = [0]*n
  162. for l in range (n) :
  163. scores_finaux[l] = false_sum(matrice_scores[l])
  164. return scores_finaux
  165. def egalite_tableau (t1, t2) :
  166. """vérifie si deux tableaux sont égaux"""
  167. c = 0
  168. b = True
  169. n = len(t1)
  170. while c < n and b == True :
  171. if t1[c] != t2[c] :
  172. b = False
  173. c = c + 1
  174. return (b)
  175. def appariement (joueurs, matrice_des_scores, ronde) :
  176. """la fonction qui à partir des scores renvoie quels matchs sont à faire"""
  177. n = len(joueurs) # si il y a un nombre de joueurs impairs, le dernier est 'bye' et gagne automatiquement
  178. apparies = [-1]*n
  179. if n%2 == 0 : #nombre pair de joueurs
  180. compteur = 0
  181. k = n//2
  182. liste_matchs = [[ 0 for i in range (2)] for j in range (k)]
  183. for i in range (n) : #on part du i et on on vérifie lesquels ont le même score (en partant du suivant)
  184. if apparies[i] == -1 : #on ne continue que s'il n'est pas déjà apparié
  185. for j in range (i+1, n) :
  186. if apparies[j] == -1 :
  187. if egalite_tableau(matrice_des_scores[i], matrice_des_scores[j]) == True :
  188. liste_matchs[compteur][0] = i
  189. liste_matchs[compteur][1] = j
  190. apparies[i] = 1
  191. apparies[j] = 1 #tous ceux qui ont des scores similaires sont apparies faire un test while sur la somme du tableau apparies jusqu'à n
  192. compteur = compteur + 1
  193. break
  194. compteur_tolerance = 1
  195. while sum(apparies) < n :
  196. for i in range (sommenegative(apparies)) : #on remet la même chose car on remplit des appariements
  197. 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"
  198. for j in range (n) :
  199. if apparies[j] == -1 and j!= depart :
  200. 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
  201. liste_matchs[compteur][0] = depart
  202. liste_matchs[compteur][1] = j
  203. apparies[depart] = 1
  204. apparies[j] = 1
  205. compteur = compteur +1
  206. break
  207. 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...)
  208. return (liste_matchs)
  209. else :
  210. #Nombre de joueurs IMPAIR
  211. #c'est excatement la même chose mais le dernier est 'bye' et gagne automatiquement
  212. compteur = 0
  213. k = (n-1)//2
  214. liste_matchs = [[ 0 for i in range (2)] for j in range (k+1)]
  215. for i in range (n) :
  216. if apparies[i] == -1 :
  217. for j in range (i+1, n) :
  218. if apparies[j] == -1 :
  219. if egalite_tableau(matrice_des_scores[i], matrice_des_scores[j]) == True :
  220. liste_matchs[compteur][0] = i
  221. liste_matchs[compteur][1] = j
  222. apparies[i] = 1
  223. apparies[j] = 1 #tous ceux qui ont des scores similaires sont apparies faire un test while sur la somme du tableau apparies jusqu'à n
  224. compteur = compteur + 1
  225. break
  226. compteur_tolerance = 1
  227. while sum(apparies) < (n-2) :
  228. #"""LA IL Y A UNE DIFFERENCE""" on ne peut nas atteindre n, car un ne sera jamais apparie
  229. for i in range (sommenegative(apparies)-1) :
  230. #on remet la même chose car on remplit des appariements
  231. 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"
  232. for j in range (n) :
  233. if apparies[j] == -1 and j!= depart :
  234. 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
  235. liste_matchs[compteur][0] = depart
  236. liste_matchs[compteur][1] = j
  237. apparies[depart] = 1
  238. apparies[j] = 1
  239. compteur = compteur +1
  240. break
  241. 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...)
  242. liste_matchs[-1] = find (apparies, -1)
  243. return liste_matchs
  244. def quasi_similitude (tableau1, tableau2, tolerance) :
  245. """renvoie true si le nombre de différences dans les tableaux est inférieur ou égal à la tolérance"""
  246. l = len(tableau1)
  247. s = 0
  248. for i in range (l) :
  249. if tableau1[i] != tableau2[i] :
  250. s = s+1
  251. return (s <= tolerance)
  252. def find(tableau, valeur) :
  253. n = len(tableau)
  254. for i in range (n) :
  255. if tableau[i] == valeur :
  256. return (i)
  257. def sommenegative (tableau) :
  258. """compte le nombre de -1"""
  259. n = len(tableau)
  260. s = 0
  261. for i in range (n) :
  262. if tableau[i] == -1 :
  263. s = s+1
  264. return (s)
  265. def find_meilleur (apparies, matrice_scores) :
  266. """renvoie la personne avec le meilleur score et son indice, parmi ceux qui ne sont pas appariés"""
  267. n = len(apparies)
  268. scores = [0]*n
  269. p = len(matrice_scores[0])
  270. for i in range (n) :
  271. if apparies[i] == 1 :
  272. scores[i] = -p-1
  273. else :
  274. scores[i] = sum(matrice_scores[i])
  275. sm = max(scores)
  276. return(find(scores, sm))