-
Notifications
You must be signed in to change notification settings - Fork 37
/
stats.cpp
204 lines (193 loc) · 9.21 KB
/
stats.cpp
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
#include "stats.hpp"
void show_stats_mjai(const std::string& dir_name, const std::string& player_name_prefix) {
std::string ls_command = "ls -1 ./" + dir_name + "/*.mjson > tmp.txt"; // 指定したディレクトリ内のmjsonファイルを一旦tmp.txtに書き出す。
const int system_result = system(ls_command.c_str());
if (system_result == -1) {
std::cout << "system_result == -1 failed" << std::endl;
return;
}
std::ifstream ifs_tmptxt("tmp.txt");
assert_with_out(!ifs_tmptxt.fail(), "tmp.txt not generated");
std::string file_path;
int result_num[4] = {};
int kyoku_num = 0;
int hora_num = 0;
int reach_num = 0;
int houjuu_num = 0;
int fuuro1_num = 0;
int fuuro_num = 0;
while (getline(ifs_tmptxt, file_path)) {
std::ifstream ifs(file_path);
std::string str;
std::string err;
assert_with_out(!ifs.fail(), "file_not_found:" + file_path);
const int oya_first = 0; // mjaiでは常に0番プレイヤが起家
int my_pid = -1; // 注目するプレイヤの番号。(現状 1vs3 の1のプレイヤの統計を取る仕様)
int fuuro_flag[4] = {};
while (getline(ifs, str)) {
json11::Json action_json = json11::Json::parse(str, err);
if (action_json["type"].string_value() == "start_game") {
for (int j = 0; j < action_json["names"].array_items().size(); j++) {
if (str_starts_with(action_json["names"][j].string_value(), player_name_prefix)) {
my_pid = j;
break;
}
}
assert_with_out(my_pid != -1, "player_not_found in " + file_path);
} else if (action_json["type"].string_value() == "start_kyoku") {
kyoku_num++;
for (int i = 0; i < 4; i++) {
fuuro_flag[i] = 0;
}
} else if (action_json["type"].string_value() == "reach") {
if (action_json["actor"].int_value() == my_pid) {
reach_num++;
}
} else if (action_json["type"].string_value() == "chi" || action_json["type"].string_value() == "pon") {
if (action_json["actor"].int_value() == my_pid) {
fuuro_num++;
}
fuuro_flag[action_json["actor"].int_value()] = 1;
} else if (action_json["type"].string_value() == "hora") {
if (action_json["actor"].int_value() == my_pid) {
hora_num++;
}
if (action_json["actor"].int_value() != action_json["target"].int_value() &&
action_json["target"].int_value() == my_pid
) {
houjuu_num++;
}
} else if (action_json["type"].string_value() == "end_kyoku") {
fuuro1_num += fuuro_flag[my_pid] ? 1 : 0;
} else if (action_json["type"].string_value() == "end_game") {
std::vector<Player_Result> results;
for (int j = 0; j < action_json["scores"].array_items().size(); j++ ) {
results.push_back(Player_Result(j, action_json["scores"].array_items()[j].int_value(), (4 + j - oya_first)%4 ));
}
std::sort(results.begin(), results.end());
for (int j = 0; j < results.size(); j++) {
if (results[j].pid == my_pid) {
result_num[j]++;
}
}
break;
}
}
}
std::cout << result_num[0] << " " << result_num[1] << " " << result_num[2] << " " << result_num[3] << " " << std::endl;
double jun_average = result_num[0] + result_num[1]*2.0 + result_num[2]*3.0 + result_num[3]*4.0;
jun_average = jun_average/(result_num[0] + result_num[1] + result_num[2] + result_num[3]);
std::cout << "average_rank:" << jun_average << std::endl;
std::cout << "hora_prob:" << (double)hora_num / kyoku_num << std::endl;
std::cout << "reach_prob:" << (double)reach_num / kyoku_num << std::endl;
std::cout << "houjuu_prob:" << (double)houjuu_num / kyoku_num << std::endl;
std::cout << "fuuro_prob:" << (double)fuuro1_num / kyoku_num << std::endl;
std::cout << "fuuro_num:" << (double)fuuro_num / kyoku_num << std::endl;
//system("rm ./tmp.txt");
}
void show_stats(const std::string& dir_name) {
int result_num[4][4] = {};
int kyoku_num = 0;
int reach_num[4] = {};
int fuuro_num[4] = {};
int fuuro_prob[4] = {};
int fuuro_flag[4] = {};
int hora_num[4] = {};
int houjuu_num[4] = {};
std::vector<std::string> files_path = get_files_path(dir_name);
for (const std::string& path : files_path) {
if (str_split(path, '/').back() == "setup_match.json") {
continue;
}
std::ifstream ifs(path);
std::string str;
std::string err;
int oya_first = -1;
while (getline(ifs, str)) {
json11::Json action_json = json11::Json::parse(str, err);
if (action_json["type"].string_value() == "start_kyoku") {
kyoku_num++;
for (int i = 0; i < 4; i++) {
fuuro_flag[i] = 0;
}
if (oya_first == -1) {
oya_first = action_json["oya"].int_value();
}
} else if (action_json["type"].string_value() == "reach") {
reach_num[action_json["actor"].int_value()]++;
} else if (action_json["type"].string_value() == "chi" || action_json["type"].string_value() == "pon") {
fuuro_num[action_json["actor"].int_value()]++;
fuuro_flag[action_json["actor"].int_value()] = 1;
} else if (action_json["type"].string_value() == "hora") {
hora_num[action_json["actor"].int_value()]++;
if (action_json["actor"].int_value() != action_json["target"].int_value()) {
houjuu_num[action_json["target"].int_value()]++;
}
} else if (action_json["type"].string_value() == "end_kyoku") {
for (int i = 0; i < 4; i++) {
fuuro_prob[i] += fuuro_flag[i];
}
} else if (action_json["type"].string_value() == "end_game") {
std::vector<Player_Result> results;
for (int j = 0; j < action_json["scores"].array_items().size(); j++ ) {
results.push_back(Player_Result(j, action_json["scores"].array_items()[j].int_value(), (4 + j - oya_first)%4 ));
}
std::sort(results.begin(), results.end());
for (int j = 0; j < results.size(); j++) {
result_num[results[j].pid][j]++;
}
break;
}
}
ifs.close();
}
std::cout << std::endl;
for (int i = 0; i < 4; i++) {
// 雑な出力
std::cout << result_num[i][0] << " " << result_num[i][1] << " " << result_num[i][2] << " " << result_num[i][3] << " ";
double jun_average = result_num[i][0] + result_num[i][1]*2.0 + result_num[i][2]*3.0 + result_num[i][3]*4.0;
jun_average = jun_average/(result_num[i][0] + result_num[i][1] + result_num[i][2] + result_num[i][3]);
std::cout << jun_average << " " << double(reach_num[i])/kyoku_num << " " << double(fuuro_prob[i])/kyoku_num << " " << double(fuuro_num[i])/kyoku_num << " ";
std::cout << double(hora_num[i])/kyoku_num << " " << double(houjuu_num[i])/kyoku_num << std::endl;
}
std::cout << std::endl;
// きれいな出力
const int game_num = result_num[0][0] + result_num[0][1] + result_num[0][2] + result_num[0][3];
std::cout << "average_rank:";
for (int pid = 0; pid < 4; pid++) {
std::cout << " " << (result_num[pid][0] + result_num[pid][1]*2.0 + result_num[pid][2]*3.0 + result_num[pid][3]*4.0) / game_num;
}
std::cout << std::endl;
for (int i = 0; i < 4; i++) {
std::cout << "rank" + std::to_string(i+1) + "_prob:";
for (int pid = 0; pid < 4; pid++) {
std::cout << " " << float(result_num[pid][i]) / game_num;
}
std::cout << std::endl;
}
std::cout << "hora_prob:";
for (int pid = 0; pid < 4; pid++) {
std::cout << " " << float(hora_num[pid])/kyoku_num;
}
std::cout << std::endl;
std::cout << "houjuu_prob:";
for (int pid = 0; pid < 4; pid++) {
std::cout << " " << float(houjuu_num[pid])/kyoku_num;
}
std::cout << std::endl;
std::cout << "reach_prob:";
for (int pid = 0; pid < 4; pid++) {
std::cout << " " << float(reach_num[pid])/kyoku_num;
}
std::cout << std::endl;
std::cout << "fuuro_prob:";
for (int pid = 0; pid < 4; pid++) {
std::cout << " " << float(fuuro_prob[pid])/kyoku_num;
}
std::cout << std::endl;
std::cout << "fuuro_num:";
for (int pid = 0; pid < 4; pid++) {
std::cout << " " << float(fuuro_num[pid])/kyoku_num;
}
std::cout << std::endl;
}