zzgo -t: Force time settings, ignore GTP time updates in that case
[pachi/derm.git] / zzgo.c
blob9cd8dc025d19488105105c0ec59e51241dee6a20
1 #define DEBUG
2 #include <assert.h>
3 #include <getopt.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <time.h>
8 #include <unistd.h>
10 #include "board.h"
11 #include "debug.h"
12 #include "engine.h"
13 #include "replay/replay.h"
14 #include "montecarlo/montecarlo.h"
15 #include "random/random.h"
16 #include "patternscan/patternscan.h"
17 #include "t-unit/test.h"
18 #include "uct/uct.h"
19 #include "gtp.h"
20 #include "timeinfo.h"
21 #include "random.h"
22 #include "version.h"
24 int debug_level = 3;
25 int seed;
28 enum engine_id {
29 E_RANDOM,
30 E_REPLAY,
31 E_PATTERNSCAN,
32 E_MONTECARLO,
33 E_UCT,
34 E_MAX,
37 static struct engine *(*engine_init[E_MAX])(char *arg, struct board *b) = {
38 engine_random_init,
39 engine_replay_init,
40 engine_patternscan_init,
41 engine_montecarlo_init,
42 engine_uct_init,
45 static struct engine *init_engine(enum engine_id engine, char *e_arg, struct board *b)
47 char *arg = e_arg? strdup(e_arg) : e_arg;
48 assert(engine < E_MAX);
49 struct engine *e = engine_init[engine](arg, b);
50 if (arg) free(arg);
51 return e;
54 static void done_engine(struct engine *e)
56 if (e->done) e->done(e);
57 if (e->data) free(e->data);
58 free(e);
61 bool engine_reset = false;
64 int main(int argc, char *argv[])
66 enum engine_id engine = E_UCT;
67 /* time_info for none(ignored), black, white: */
68 struct time_info ti_default[] = { { .period = TT_NULL }, { .period = TT_NULL }, { .period = TT_NULL }};
69 char *testfile = NULL;
71 seed = time(NULL) ^ getpid();
73 int opt;
74 while ((opt = getopt(argc, argv, "e:d:s:t:u:")) != -1) {
75 switch (opt) {
76 case 'e':
77 if (!strcasecmp(optarg, "random")) {
78 engine = E_RANDOM;
79 } else if (!strcasecmp(optarg, "patternscan")) {
80 engine = E_PATTERNSCAN;
81 } else if (!strcasecmp(optarg, "replay")) {
82 engine = E_REPLAY;
83 } else if (!strcasecmp(optarg, "montecarlo")) {
84 engine = E_MONTECARLO;
85 } else if (!strcasecmp(optarg, "uct")) {
86 engine = E_UCT;
87 } else {
88 fprintf(stderr, "%s: Invalid -e argument %s\n", argv[0], optarg);
89 exit(1);
91 break;
92 case 'd':
93 debug_level = atoi(optarg);
94 break;
95 case 's':
96 seed = atoi(optarg);
97 break;
98 case 't':
99 /* Time settings to follow; if specified,
100 * GTP time information is ignored. Useful
101 * e.g. when you want to force your bot to
102 * play weaker while giving the opponent
103 * reasonable time to play, or force play
104 * by number of simulations in timed games. */
105 /* Please see timeinfo.h:time_parse()
106 * description for syntax details. */
107 if (!time_parse(&ti_default[S_BLACK], optarg)) {
108 fprintf(stderr, "%s: Invalid -t argument %s\n", argv[0], optarg);
109 exit(1);
111 ti_default[S_BLACK].ignore_gtp = true;
112 ti_default[S_WHITE] = ti_default[S_BLACK];
113 break;
114 case 'u':
115 testfile = strdup(optarg);
116 break;
117 default: /* '?' */
118 fprintf(stderr, "Pachi version %s\n", PACHI_VERSION);
119 fprintf(stderr, "Usage: %s [-e random|replay|patternscan|montecarlo|uct] [-d DEBUG_LEVEL] [-s RANDOM_SEED] [-t TIME_SETTINGS] [-u TEST_FILENAME] [ENGINE_ARGS]\n",
120 argv[0]);
121 exit(1);
125 fast_srandom(seed);
126 fprintf(stderr, "Random seed: %d\n", seed);
128 struct board *b = board_init();
129 struct time_info ti[S_WHITE+1];
130 ti[S_BLACK] = ti_default[S_BLACK];
131 ti[S_WHITE] = ti_default[S_WHITE];
133 char *e_arg = NULL;
134 if (optind < argc)
135 e_arg = argv[optind];
136 struct engine *e = init_engine(engine, e_arg, b);
138 if (testfile) {
139 unittest(testfile);
140 return 0;
143 char buf[4096];
144 while (fgets(buf, 4096, stdin)) {
145 if (DEBUGL(1))
146 fprintf(stderr, "IN: %s", buf);
147 gtp_parse(b, e, ti, buf);
148 if (engine_reset) {
149 if (!e->keep_on_clear) {
150 b->es = NULL;
151 done_engine(e);
152 e = init_engine(engine, e_arg, b);
153 ti[S_BLACK] = ti_default[S_BLACK];
154 ti[S_WHITE] = ti_default[S_WHITE];
156 engine_reset = false;
159 done_engine(e);
160 return 0;