-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimulator.py
94 lines (79 loc) · 2.89 KB
/
simulator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from __future__ import annotations
import sys
from typing import Iterable, Sequence, SupportsInt, TypeVar
from datetime import date
from os.path import isfile
from probability import get_backup_probability, get_probabilities_file
gender = 'm'
if '-w' in sys.argv:
gender = 'w'
elif '-m' in sys.argv:
gender = 'm'
GAMES_REQUIRED = 7
year = date.today().year
while (
(not isfile(probabilities_file := f'probabilities_{year}{gender}.json'))
and year > 1985): # First year of tournament
year -= 1
PROBABILITIES_FILE = probabilities_file
class Team:
main_prob = get_probabilities_file(PROBABILITIES_FILE)
def __init__(self, seed: SupportsInt, name: str):
self.seed, self.name = int(seed), name
def __lt__(self, other):
if self.seed > other.seed:
return True
elif self.seed < other.seed:
return False
elif self.seed == other.seed:
return None
def __gt__(self, other):
if self.seed < other.seed:
return True
elif self.seed > other.seed:
return False
elif self.seed == other.seed:
return None
@staticmethod
def play_game(team_a: Team, team_b: Team, simulation_value: int):
games_won, games_played = Team.main_prob[team_a.seed][team_b.seed]
p_team_a = (
games_won / games_played
if games_played >= GAMES_REQUIRED
else get_backup_probability(team_a.seed, team_b.seed)
)
if simulation_value / 1000 < p_team_a:
return team_a
return team_b
class Division:
def __init__(self, teams: Iterable[Team], name):
self.teams, self.name = {team.seed: team for team in teams}, name
def play_through(self, random_number_generator: Iterable[int]):
bracket = [1, 16, 8, 9, 5, 12, 4, 13, 6, 11, 3, 14, 7, 10, 2, 15]
next_round = list(better_grouper_two(bracket))
matches = 0
for rnd in range(4):
print("\n" + self.name + str(64 // 2 ** rnd))
this_round = next_round
next_round = []
for match in this_round:
matches += 1
advances = Team.play_game(
self.teams[match[0]],
self.teams[match[1]],
next(random_number_generator),
)
print(advances.name, end="")
next_round.append(advances.seed)
if matches != 8 / 2 ** rnd:
print(", ", end="")
else:
matches = 0
next_round = list(better_grouper_two(next_round))
self.winner = advances
return advances
Grouped = TypeVar('Grouped')
def better_grouper_two(inputs: Iterable[Grouped]) -> list[tuple[Grouped]]:
# Modified from https://realpython.com/python-itertools/
iters = [iter(inputs)] * 2
return list(zip(*iters))