ezpp-oppai-rx/test/test.c

120 lines
2.7 KiB
C

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../oppai.c"
#include "test_suite.c" /* defines suite */
#define ERROR_MARGIN 0.02f /* pp can be off by +- 2% */
/*
* margin is actually
* - 3x for < 100pp
* - 2x for 100-200pp
* - 1.5x for 200-300pp
*/
void print_score(score_t* s) {
char mods_str_buf[20];
char* mods_str = mods_str_buf;
strcpy(mods_str, "nomod");
#define m(mod) \
if (s->mods & MODS_##mod) { \
mods_str += sprintf(mods_str, #mod); \
} \
m(HR) m(NC) m(HT) m(SO) m(NF) m(EZ) m(DT) m(FL) m(HD)
#undef m
printf("m=%d %u +%s %dx %dx300 %dx100 %dx50 %dxmiss %g pp\n",
s->mode, s->id, mods_str_buf, s->max_combo, s->n300, s->n100,
s->n50, s->nmiss, s->pp);
}
int main() {
char fname_buf[4096];
char* fname = fname_buf;
int i, n = (int)(sizeof(suite) / sizeof(suite[0]));
float max_err[2] = { 0, 0 };
int max_err_map[2] = { 0, 0 };
float avg_err[2] = { 0, 0 };
int count[2] = { 0, 0 };
float error = 0;
float error_percent = 0;
ezpp_t ez = ezpp_new();
int err;
int last_id = 0;
fname += sprintf(fname, "test_suite/");
for (i = 0; i < n; ++i) {
score_t* s = &suite[i];
float margin;
float pptotal;
print_score(s);
if (s->id != last_id) {
sprintf(fname, "%u.osu", s->id);
last_id = s->id;
/* force reparse and don't reuse prev map ar/cs/od/hp */
ezpp_set_base_cs(ez, -1);
ezpp_set_base_ar(ez, -1);
ezpp_set_base_od(ez, -1);
ezpp_set_base_hp(ez, -1);
}
ezpp_set_mods(ez, s->mods);
ezpp_set_accuracy(ez, s->n100, s->n50);
ezpp_set_nmiss(ez, s->nmiss);
ezpp_set_combo(ez, s->max_combo);
ezpp_set_mode_override(ez, s->mode);
err = ezpp(ez, fname_buf);
if (err < 0) {
printf("%s\n", errstr(err));
exit(1);
}
pptotal = ezpp_pp(ez);
++count[s->mode];
margin = (float)s->pp * ERROR_MARGIN;
if (s->pp < 100) {
margin *= 3;
} else if (s->pp < 200) {
margin *= 2;
} else if (s->pp < 300) {
margin *= 1.5f;
}
error = (float)fabs(pptotal - (float)s->pp);
error_percent = error / (float)s->pp;
avg_err[s->mode] += error_percent;
if (error_percent > max_err[s->mode]) {
max_err[s->mode] = error_percent;
max_err_map[s->mode] = s->id;
}
if (error >= margin) {
printf("failed test: got %g pp, expected %g\n", pptotal, s->pp);
exit(1);
}
}
for (i = 0; i < 2; ++i) {
switch (i) {
case MODE_STD: puts("osu"); break;
case MODE_TAIKO: puts("taiko"); break;
}
avg_err[i] /= count[i];
printf("%d scores\n", count[i]);
printf("avg err %f\n", avg_err[i]);
printf("max err %f on %d\n", max_err[i], max_err_map[i]);
}
ezpp_free(ez);
return 0;
}