From 0fd4f3753c6a4e596f4635ac75fdb1e3730ede64 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 12 Mar 2006 17:26:54 +0000 Subject: [PATCH] mm: Add built-in option for running an internal tournament. --- mm.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/mm.c b/mm.c index 3048108..7ed9b16 100644 --- a/mm.c +++ b/mm.c @@ -28,6 +28,7 @@ /*----- Header files ------------------------------------------------------*/ +#include #include #include #include @@ -35,6 +36,7 @@ #include #include +#include #include #include #include @@ -511,6 +513,99 @@ again: static void sp_update(void *ss, const dig *g, unsigned b, unsigned w) { spc *s = ss; cp_update(s->c, g, b, w); } +/*----- Full tournament stuff ---------------------------------------------*/ + +DA_DECL(uint_v, unsigned); + +typedef struct allstats { + const mm *m; + unsigned f; +#define AF_VERBOSE 1u + uint_v gmap; + unsigned long g; + unsigned long n; + clock_t t; +} allstats; + +static void dorunone(allstats *a, dig *s) +{ + ratectx *r = rate_new(a->m, s); + clock_t t = 0, t0, t1; + cpc *c; + int n = 0; + const dig *g; + unsigned b, w; + + if (a->f & AF_VERBOSE) { + print_guess(a->m, s); + fputs(": ", stdout); + fflush(stdout); + } + + c = cpc_new(a->m, CPCF_QUIET); + for (;;) { + t0 = clock(); + g = cp_guess(c); + t1 = clock(); + t += t1 - t0; + assert(g); + n++; + rate(r, g, &b, &w); + if (b == a->m->k) + break; + t0 = clock(); + cp_update(c, g, b, w); + t1 = clock(); + t += t1 - t0; + } + a->t += t; + a->g += n; + while (DA_LEN(&a->gmap) <= n) + DA_PUSH(&a->gmap, 0); + DA(&a->gmap)[n]++; + rate_free(r); + cpc_free(c); + + if (a->f & AF_VERBOSE) + printf("%2u (%5.2fs)\n", n, (double)t/CLOCKS_PER_SEC); +} + +static void dorunall(allstats *a, dig *s, unsigned i) +{ + dig j; + + if (i >= a->m->k) { + dorunone(a, s); + a->n++; + } else { + for (j = 0; j < a->m->n; j++) { + s[i] = j; + dorunall(a, s, i + 1); + } + } +} + +static void run_all(const mm *m) +{ + dig *s = xmalloc(m->k * sizeof(dig)); + allstats a; + unsigned i; + + a.m = m; + a.f = AF_VERBOSE; + DA_CREATE(&a.gmap); + a.n = 0; + a.g = 0; + a.t = 0; + dorunall(&a, s, 0); + xfree(s); + + for (i = 1; i < DA_LEN(&a.gmap); i++) + printf("%2u guesses: %5u games\n", i, DA(&a.gmap)[i]); + printf("Average: %.4f (%.2fs)\n", + (double)a.g/a.n, (double)a.t/(a.n * CLOCKS_PER_SEC)); +} + /*----- Main game logic ---------------------------------------------------*/ static int play(const mm *m, @@ -553,15 +648,17 @@ int main(int argc, char *argv[]) { "computer", 0, 0, 'C' }, { "human", 0, 0, 'H' }, { "solver", 0, 0, 'S' }, + { "all", 0, 0, 'a' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "CHS", opt, 0, 0, 0); + int i = mdwopt(argc, argv, "CHSa", opt, 0, 0, 0); if (i < 0) break; switch (i) { case 'C': h = 0; break; case 'H': h = 1; break; case 'S': h = 2; break; + case 'a': h = 99; break; default: exit(1); } @@ -616,6 +713,10 @@ int main(int argc, char *argv[]) n = play(&m, hp_rate, &m, sp_guess, sp_update, ss); spc_free(ss); } break; + case 99: + run_all(&m); + return (0); + break; default: abort(); } -- 2.11.0