Untitled
unknown
python
a year ago
3.3 kB
5
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