/*----- Header files ------------------------------------------------------*/
+#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mLib/alloc.h>
+#include <mLib/darray.h>
#include <mLib/mdwopt.h>
#include <mLib/quis.h>
#include <mLib/report.h>
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,
{ "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);
}
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();
}