Untitled
unknown
python
a year ago
3.3 kB
4
Indexable
import math import random import matplotlib.pyplot as plt from tqdm import tqdm class Team: id: int pos: float elo: float win_count: int placement: int def __init__(self, id, pos, elo=2000): self.id = id self.pos = pos self.elo = elo self.placement = 0 self.win_count = 0 def __repr__(self) -> str: return f"Team {self.id}, pos {self.pos:.2f}, placement {self.placement}" def simulate(p=0.5) -> tuple[int, int]: teams = [Team(i, random.random() * 2 - 1) for i in range(20)] teams[0].elo += 400 * math.log(p / (1 - p), 10) res = [] while len(teams) != 1: teams.sort(key=lambda x: x.pos) min_diff = 2 min_diff_idx = 0 for i in range(len(teams) - 1): diff = teams[i + 1].pos - teams[i].pos if diff < min_diff: min_diff = diff min_diff_idx = i elo_diff = teams[min_diff_idx + 1].elo - teams[min_diff_idx].elo win_rate = 1 / (1 + 10 ** (-elo_diff / 400)) win = random.random() < win_rate new_pos = (teams[min_diff_idx + 1].pos + teams[min_diff_idx].pos) / 2 winner_idx = min_diff_idx + 1 if win else min_diff_idx loser_idx = min_diff_idx if win else min_diff_idx + 1 teams[winner_idx].pos = new_pos teams[winner_idx].win_count += 1 teams[loser_idx].placement = len(teams) res.append(teams[loser_idx]) teams.pop(loser_idx) teams[0].placement = 1 res.append(teams[0]) t: Team = next((x for x in res if x.id == 0)) return t.placement, t.win_count def main(): for P in [0.4, 0.45, 0.5, 0.55, 0.6]: COUNT = 100000 y = [0.0] * 20 PLACEMENT_SCORE = [ 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 10, 10, 20, 20, 30, 45, 55, 70, 95, 125, ] KILL_SCORE = [ 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 10, 10, 12, 12, 14, 16, 18, 20, 23, 25, ] total_placement_score = 0 total_kill_score = 0 for _ in tqdm(range(COUNT)): placement, win_count = simulate(P) y[placement - 1] += 1 total_placement_score += PLACEMENT_SCORE[20 - placement] total_kill_score += KILL_SCORE[20 - placement] * win_count * 2.5 x = range(1, 21) y = [i / COUNT for i in y] plt.xticks(x) plt.bar(x, y) plt.title( f"win rate: {P:.2f}, " f"avg placement score: {(total_placement_score / COUNT):.2f}, " f"avg kill score: {(total_kill_score / COUNT):.2f}" ) plt.savefig(f"img/{P:.2f}.png") plt.clf() if __name__ == "__main__": main()
Editor is loading...
Leave a Comment