-
Notifications
You must be signed in to change notification settings - Fork 2
/
analyze_tournament_csv.py
149 lines (116 loc) · 4.49 KB
/
analyze_tournament_csv.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import argparse
import csv
import os
from othello.gamescheduler.othello_core import BLACK, WHITE
def load_csv(filename):
"""
Reads each row of a CSV into a list using a DictReader
"""
if not (os.path.exists(filename) and os.path.isfile(filename)):
raise FileNotFoundError(filename)
with open(filename, 'r') as f:
infile = csv.DictReader(f)
results = [row for row in infile]
return results
def read_rankings(filename):
"""
Reads tournament rankings from a file
Newline-seperated list of names, ordered from "best"
rank at the top to lowest rank at the bottom.
"""
ranking = [] # first index is highest rank
with open(filename, 'r') as f:
ranking = [line.strip() for line in f if line.strip()]
return ranking
def write_rankings(filename, rankings):
"""
Writes tournament rankings to a file, same format as reading
"""
with open(filename, 'w') as f:
for name in rankings:
f.write("{}\n".format(name))
def analyze_stats(results):
num_wins = dict()
differentials = dict()
for result in results:
black_ai = result['Black']
white_ai = result['White']
winner = result['Winner']
black_differential = differentials.get(black_ai, 0)
white_differential = differentials.get(white_ai, 0)
black_wins = num_wins.get(black_ai, 0)
white_wins = num_wins.get(white_ai, 0)
if winner == BLACK:
num_wins[black_ai] = black_wins + 1
num_wins[white_ai] = white_wins
elif winner == WHITE:
num_wins[white_ai] = white_wins + 1
num_wins[black_ai] = black_wins
if result.get('Black_Score', False):
diff = int(result['Black_Score']) - int(result['White_Score'])
differentials[black_ai] = black_differential + diff
differentials[white_ai] = white_differential - diff
return num_wins, differentials
def show_top_wins(num_wins):
top_num = input("How many top AIs to show? [default=8]: ")
try:
top_num = int(top_num)
except ValueError:
print("Invalid number, defaulting to 8...")
top_num = 8
output = sorted(num_wins.items(), key=lambda i: -i[1])[:top_num]
for ai, num in output:
print("{}: {}".format(ai, num))
def order_by_wins(results, args):
num_wins, _ = analyze_stats(results)
ranking = []
if args.in_ranking:
ranking = read_rankings(args.in_ranking)
else:
# No previous ranking, use alphabetical order
ranking = sorted([name for name in num_wins.keys()])
# Sort by most wins at the front
# Python's sort is stable, so this is fine
new_ranking = sorted(ranking, key=lambda i: -num_wins[i])
if args.out_ranking:
write_rankings(args.out_ranking, new_ranking)
else:
print("\n".join(new_ranking))
def order_by_differential(results, args):
_, differential = analyze_stats(results)
ranking = []
if args.in_ranking:
ranking = read_rankings(args.in_ranking)
else:
# No previous ranking, use alphabetical order
ranking = sorted([name for name in differential.keys()])
# Sort by most wins at the front
# Python's sort is stable, so this is fine
new_ranking = sorted(ranking, key=lambda i: -differential[i])
if args.out_ranking:
write_rankings(args.out_ranking, new_ranking)
else:
print("\n".join(new_ranking))
def analyze_bracket(results):
# TODO: once you fully implement bracket sets, come back to this
pass
ANALYSIS_TYPES = ["wins", "differential"]
ANALYSIS_FUNCS = [order_by_wins, order_by_differential]
assert(len(ANALYSIS_TYPES) == len(ANALYSIS_FUNCS))
def make_parser():
parser = argparse.ArgumentParser()
parser.add_argument('analysis_type', type=str, choices=ANALYSIS_TYPES,
help="The type of analysis to perform")
parser.add_argument('file', type=str,
help="The filename of the tournament to analyze")
parser.add_argument("--in-ranking", type=str,
help="Previous rankings to read from, used in certain analysis types")
parser.add_argument("--out-ranking", type=str,
help="Updated rankings to write to, used in certain analysis types")
return parser
if __name__ == "__main__":
args = make_parser().parse_args()
results = load_csv(args.file)
for i in range(len(ANALYSIS_TYPES)):
if args.analysis_type == ANALYSIS_TYPES[i]:
ANALYSIS_FUNCS[i](results, args)