forked from GoodStartLabs/AI_Diplomacy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanalyze_game_results.py
More file actions
219 lines (170 loc) · 7.82 KB
/
analyze_game_results.py
File metadata and controls
219 lines (170 loc) · 7.82 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/usr/bin/env python3
"""
Analyze Diplomacy game results from FULL_GAME folders.
Creates a CSV showing how many times each model played as each power and won.
"""
import json
import os
import glob
from collections import defaultdict
import csv
from pathlib import Path
def find_overview_file(folder_path):
"""Find overview.jsonl or overviewN.jsonl in a folder."""
# Check for numbered overview files first (overview1.jsonl, overview2.jsonl, etc.)
numbered_files = glob.glob(os.path.join(folder_path, "overview[0-9]*.jsonl"))
if numbered_files:
# Return the one with the highest number
return max(numbered_files)
# Check for regular overview.jsonl
regular_file = os.path.join(folder_path, "overview.jsonl")
if os.path.exists(regular_file):
return regular_file
return None
def parse_lmvsgame_for_winner(folder_path):
"""Parse lmvsgame.json file to find the winner."""
lmvsgame_path = os.path.join(folder_path, "lmvsgame.json")
if not os.path.exists(lmvsgame_path):
return None
try:
with open(lmvsgame_path, 'r') as f:
data = json.load(f)
# Look for phases with "COMPLETED" status
if 'phases' in data:
for phase in data['phases']:
if phase.get('name') == 'COMPLETED':
# Check for victory note
if 'state' in phase and 'note' in phase['state']:
note = phase['state']['note']
if 'Victory by:' in note:
winner = note.split('Victory by:')[1].strip()
return winner
# Also check centers to see who has 18
if 'state' in phase and 'centers' in phase['state']:
centers = phase['state']['centers']
for power, power_centers in centers.items():
if len(power_centers) >= 18:
return power
except Exception as e:
print(f"Error parsing lmvsgame.json in {folder_path}: {e}")
return None
def parse_overview_file(filepath):
"""Parse overview.jsonl file and extract power-model mappings and winner."""
power_model_map = {}
winner = None
try:
with open(filepath, 'r') as f:
lines = f.readlines()
# The second line typically contains the power-model mapping
if len(lines) >= 2:
try:
second_line_data = json.loads(lines[1].strip())
# Check if this line contains power names as keys
if all(power in second_line_data for power in ['AUSTRIA', 'ENGLAND', 'FRANCE', 'GERMANY', 'ITALY', 'RUSSIA', 'TURKEY']):
power_model_map = second_line_data
except:
pass
# Search all lines for winner information
for line in lines:
if line.strip():
try:
data = json.loads(line)
# Look for winner in various possible fields
if 'winner' in data:
winner = data['winner']
elif 'game_status' in data and 'winner' in data['game_status']:
winner = data['game_status']['winner']
elif 'result' in data and 'winner' in data['result']:
winner = data['result']['winner']
# Also check if there's a phase result with winner info
if 'phase_results' in data:
for phase_result in data['phase_results']:
if 'winner' in phase_result:
winner = phase_result['winner']
except:
continue
except Exception as e:
print(f"Error parsing {filepath}: {e}")
return power_model_map, winner
def analyze_game_folders(results_dir):
"""Analyze all FULL_GAME folders and collect statistics."""
# Dictionary to store stats: model -> power -> (games, wins)
stats = defaultdict(lambda: defaultdict(lambda: [0, 0]))
# Find all FULL_GAME folders
full_game_folders = glob.glob(os.path.join(results_dir, "*_FULL_GAME"))
print(f"Found {len(full_game_folders)} FULL_GAME folders")
for folder in full_game_folders:
print(f"\nAnalyzing: {os.path.basename(folder)}")
# Find overview file
overview_file = find_overview_file(folder)
if not overview_file:
print(f" No overview file found in {folder}")
continue
print(f" Using: {os.path.basename(overview_file)}")
# Parse the overview file
power_model_map, winner = parse_overview_file(overview_file)
if not power_model_map:
print(f" No power-model mapping found")
continue
# If no winner found in overview, check lmvsgame.json
if not winner:
winner = parse_lmvsgame_for_winner(folder)
print(f" Power-Model mappings: {power_model_map}")
print(f" Winner: {winner}")
# Update statistics
for power, model in power_model_map.items():
# Increment games played
stats[model][power][0] += 1
# Increment wins if this power won
if winner:
# Handle different winner formats (e.g., "FRA", "FRANCE", etc.)
winner_upper = winner.upper()
power_upper = power.upper()
# Check if winner matches power (could be abbreviated)
if (winner_upper == power_upper or
winner_upper == power_upper[:3] or
(len(winner_upper) == 3 and power_upper.startswith(winner_upper))):
stats[model][power][1] += 1
return stats
def write_csv_output(stats, output_file):
"""Write statistics to CSV file."""
# Get all unique models and powers
all_models = sorted(stats.keys())
all_powers = ['AUSTRIA', 'ENGLAND', 'FRANCE', 'GERMANY', 'ITALY', 'RUSSIA', 'TURKEY']
# Create CSV
with open(output_file, 'w', newline='') as csvfile:
# Header row
header = ['Model'] + all_powers
writer = csv.writer(csvfile)
writer.writerow(header)
# Data rows
for model in all_models:
row = [model]
for power in all_powers:
games, wins = stats[model][power]
if games > 0:
cell_value = f"{games} ({wins} wins)"
else:
cell_value = ""
row.append(cell_value)
writer.writerow(row)
print(f"\nResults written to: {output_file}")
def main():
"""Main function."""
results_dir = "/Users/alxdfy/Documents/mldev/AI_Diplomacy/results"
output_file = "/Users/alxdfy/Documents/mldev/AI_Diplomacy/model_power_statistics.csv"
print("Analyzing Diplomacy game results...")
stats = analyze_game_folders(results_dir)
# Print summary
print("\n=== Summary ===")
total_games = 0
for model, power_stats in stats.items():
model_games = sum(games for games, wins in power_stats.values())
model_wins = sum(wins for games, wins in power_stats.values())
total_games += model_games
print(f"{model}: {model_games} games, {model_wins} wins")
print(f"\nTotal games analyzed: {total_games // 7}") # Divide by 7 since each game has 7 players
# Write to CSV
write_csv_output(stats, output_file)
if __name__ == "__main__":
main()