import json, sys import _pydecimal # moteur decimal (moins d'overflows) #-------------------------------- decimal_context = _pydecimal.Context(Emax=10**20) def new_decimal(n): return decimal_context.create_decimal(n) #fonctions ELO #------------- K = 32 D = 400 def expected_scores(RA, RB): """Expected normalized scores a player A and B with ratings RA and RB.""" RAB = RB - RA return 1 / (1 + new_decimal(10) ** (RAB / D)), 1 / (1 + new_decimal(10) ** (-RAB / D)) def update_ratings(RA, RB, EA, EB, SA, SB): """Update ratings RA/RB of players A and B, which were expected to score EA/EB and ended up scoring SA/SB.""" return (RA + K * (SA - EA), RB + K * (SB - EB)) #fonctions dictionnaire #---------------------- def sorted_dictionnary(d, reverse=False): sitems = sorted(d.items(), key=lambda item: item[1], reverse=reverse) sd = {} for key, value in sitems: sd[key] = value return sd #fonctions tournoi #----------------- nprogress = 202 #chargement donnees #------------------ fparticipants = open('participants.json') participants = json.load(fparticipants) player_elo = {} player_ia = {} truels_par_tour = {} premier_par_tour = {} dernier_par_tour = {} scores_par_tour = {} player_infos = {} N = 3 SCORE_DIVIDER = 90#85#80#60 for participant in participants: p = participant['nom'] player_elo[p] = new_decimal(0) scores_par_tour[p] = [0] * N player_ia[p] = participant['choixfinal'] truels_par_tour[p] = [0] * N premier_par_tour[p] = [0] * N dernier_par_tour[p] = [0] * N resultats = [] for nomfic in sys.argv[1:]: fresultats = open(nomfic) resultats.extend(json.load(fresultats)) freq_by_top = {} stable_by_top = {} nprogress = 100 old_progress = -1 truels = 0 sorted_player_elo = {} print("Traitement des {:d} truels...".format(len(resultats))) for truel in resultats[::-1]: truels += 1 players = truel[:N] scores = [new_decimal(truel[i])/SCORE_DIVIDER for i in range(N, 2*N)] d12e1, d12e2 = expected_scores(player_elo[players[0]], player_elo[players[1]]) d13e1, d13e3 = expected_scores(player_elo[players[0]], player_elo[players[2]]) d23e2, d23e3 = expected_scores(player_elo[players[1]], player_elo[players[2]]) d12r1, d12r2 = update_ratings(player_elo[players[0]], player_elo[players[1]], d12e1, d12e2, scores[0], scores[1]) player_elo[players[0]], player_elo[players[1]] = d12r1, d12r2 d13r1, d13r3 = update_ratings(player_elo[players[0]], player_elo[players[2]], d13e1, d13e3, scores[0], scores[2]) player_elo[players[0]], player_elo[players[2]] = d13r1, d13r3 d23r2, d23r3 = update_ratings(player_elo[players[1]], player_elo[players[2]], d23e2, d23e3, scores[1], scores[2]) player_elo[players[1]], player_elo[players[2]] = d23r2, d13r3 prev_sorted_player_elo = sorted_player_elo.copy() sorted_player_elo = sorted_dictionnary(player_elo, reverse=True) for i in range(1, N + 1): top = tuple(sorted_player_elo)[:i] if not top in freq_by_top: freq_by_top[top] = 0 freq_by_top[top] += 1 if tuple(prev_sorted_player_elo)[:i] != tuple(sorted_player_elo)[:i]: if not top in stable_by_top: stable_by_top[top] = 0 stable_by_top[top] += 1 progress = round(nprogress*truels/len(resultats)) if old_progress != progress: sys.stdout.write("[%-{:d}s] %d%%".format(nprogress) % ('='*progress, round(progress*100/nprogress))) sys.stdout.write('\r') sys.stdout.flush() old_progress = progress print() print(" TOUR1 TOUR2 TOUR3") print() for participant1 in participants: for participant2 in participants: if participant2 != participant1: for participant3 in participants: if participant3 != participant2 and participant3 != participant1: participants_noms = [p["nom"] for p in (participant1, participant2, participant3)] victoires = [0 for i in range(N)] n_truels = 0 n_premier = [0] * N n_dernier = [0] * N t_scores = [0] * N for truel in resultats: if truel[:N] == [p for p in participants_noms]: n_truels += 1 scores = truel[N : 2 * N] for i in range(N): t_scores[i] += int(scores[i]) if max(scores) == scores[i]: n_premier[i] += 1 victoires[i] += 1 if min(scores) == scores[i]: n_dernier[i] += 1 print("{:06d}x {:9s} {:9s} {:9s}".format(n_truels, *participants_noms)) print("1er {:06d} ({:02.2f})% {:06d} ({:02.2f})% {:06d} ({:02.2f})%".format(n_premier[0], n_premier[0]*100/n_truels, n_premier[1], n_premier[1]*100/n_truels, n_premier[2], n_premier[2]*100/n_truels)) print("dernier {:06d} ({:02.2f})% {:06d} ({:02.2f})% {:06d} ({:02.2f})%".format(n_dernier[0], n_dernier[0]*100/n_truels, n_dernier[1], n_dernier[1]*100/n_truels, n_dernier[2], n_dernier[2]*100/n_truels)) print("scores {:09d} {:09d} {:09d}".format(*t_scores)) for i in range(N): truels_par_tour[participants_noms[i]][i] += n_truels scores_par_tour[participants_noms[i]][i] += t_scores[i] premier_par_tour[participants_noms[i]][i] += n_premier[i] dernier_par_tour[participants_noms[i]][i] += n_dernier[i] print() print("-"*91) print() print("{:9s} CRITERE TOTAL = TOUR1 + TOUR2 + TOUR3".format("NOM")) print() show_freq = True for participant in participants: p = participant['nom'] print("{:9s} truels : {:06d} = {:06d} + {:06d} + {:06d}".format(p, truels, truels_par_tour[p][0], truels_par_tour[p][1], truels_par_tour[p][2])) print() for participant in participants: p = participant['nom'] print("{:9s} 1er : {:06d} ({:02.2f}%) = {:06d} ({:02.2f}%) + {:06d} ({:02.2f}%) + {:06d} ({:02.2f}%)".format(p, sum(premier_par_tour[p]), sum(premier_par_tour[p])*100/truels, premier_par_tour[p][0], premier_par_tour[p][0]*100/truels_par_tour[p][0], premier_par_tour[p][1], premier_par_tour[p][1]*100/truels_par_tour[p][1], premier_par_tour[p][2], premier_par_tour[p][2]*100/truels_par_tour[p][2])) print() for participant in participants: p = participant['nom'] print("{:9s} dernier : {:06d} ({:02.2f}%) = {:06d} ({:02.2f}%) + {:06d} ({:02.2f}%) + {:06d} ({:02.2f}%)".format(p, sum(dernier_par_tour[p]), sum(dernier_par_tour[p])*100/truels, dernier_par_tour[p][0], dernier_par_tour[p][0]*100/truels_par_tour[p][0], dernier_par_tour[p][1], dernier_par_tour[p][1]*100/truels_par_tour[p][1], dernier_par_tour[p][2], dernier_par_tour[p][2]*100/truels_par_tour[p][2])) print() for participant in participants: p = participant['nom'] print("{:9s} scores : {:10d} = {:10d} + {:10d} + {:10d}".format(p, sum(scores_par_tour[p]), scores_par_tour[p][0], scores_par_tour[p][1], scores_par_tour[p][2])) print("-"*91) print() print("RANG NOM GROUP IA ELO FREQUENCE") i = 1 for p in sorted_player_elo: truels1, truels2, truels3 = truels_par_tour[p][0], truels_par_tour[p][1], truels_par_tour[p][2] top = tuple(sorted_player_elo)[:i] freq = freq_by_top[top]*100/truels for participant in participants: if p == participant['nom']: break infos = p in player_infos and player_infos[p] or "" if infos != "": show_freq = False top_freq = show_freq and "{:05.2f}% top{:d}".format(freq, i) or "" print("{:01d} {:14s} {:17s} {:19s} {:06.3f} {:s}".format(i, p, participant['choixgrp'], player_ia[p], sorted_player_elo[p] / 10**7, top_freq)) i += 1