fast_frandom() always returns float, not floating_t
[pachi/t.git] / pachi.c
blob6a1ec672cb777c38dfb76ce152e9334e4ad3ec8e
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 "patternplay/patternplay.h"
18 #include "joseki/joseki.h"
19 #include "t-unit/test.h"
20 #include "uct/uct.h"
21 #include "distributed/distributed.h"
22 #include "gtp.h"
23 #include "chat.h"
24 #include "timeinfo.h"
25 #include "random.h"
26 #include "version.h"
27 #include "network.h"
29 int debug_level = 3;
30 bool debug_boardprint = true;
31 long verbose_logs = 0;
32 int seed;
35 enum engine_id {
36 E_RANDOM,
37 E_REPLAY,
38 E_PATTERNSCAN,
39 E_PATTERNPLAY,
40 E_MONTECARLO,
41 E_UCT,
42 E_DISTRIBUTED,
43 E_JOSEKI,
44 E_MAX,
47 static struct engine *(*engine_init[E_MAX])(char *arg, struct board *b) = {
48 engine_random_init,
49 engine_replay_init,
50 engine_patternscan_init,
51 engine_patternplay_init,
52 engine_montecarlo_init,
53 engine_uct_init,
54 engine_distributed_init,
55 engine_joseki_init,
58 static struct engine *init_engine(enum engine_id engine, char *e_arg, struct board *b)
60 char *arg = e_arg? strdup(e_arg) : e_arg;
61 assert(engine < E_MAX);
62 struct engine *e = engine_init[engine](arg, b);
63 if (arg) free(arg);
64 return e;
67 static void done_engine(struct engine *e)
69 if (e->done) e->done(e);
70 if (e->data) free(e->data);
71 free(e);
74 static void usage(char *name)
76 fprintf(stderr, "Pachi version %s\n", PACHI_VERSION);
77 fprintf(stderr, "Usage: %s [-e random|replay|montecarlo|uct|distributed]\n"
78 " [-d DEBUG_LEVEL] [-D] [-s RANDOM_SEED] [-t TIME_SETTINGS] [-u TEST_FILENAME]\n"
79 " [-g [HOST:]GTP_PORT] [-l [HOST:]LOG_PORT] [-f FBOOKFILE] [ENGINE_ARGS]\n", name);
82 int main(int argc, char *argv[])
84 enum engine_id engine = E_UCT;
85 struct time_info ti_default = { .period = TT_NULL };
86 char *testfile = NULL;
87 char *gtp_port = NULL;
88 char *log_port = NULL;
89 int gtp_sock = -1;
90 char *chatfile = NULL;
91 char *fbookfile = NULL;
93 seed = time(NULL) ^ getpid();
95 int opt;
96 while ((opt = getopt(argc, argv, "c:e:d:Df:g:l:s:t:u:")) != -1) {
97 switch (opt) {
98 case 'c':
99 chatfile = strdup(optarg);
100 break;
101 case 'e':
102 if (!strcasecmp(optarg, "random")) {
103 engine = E_RANDOM;
104 } else if (!strcasecmp(optarg, "replay")) {
105 engine = E_REPLAY;
106 } else if (!strcasecmp(optarg, "montecarlo")) {
107 engine = E_MONTECARLO;
108 } else if (!strcasecmp(optarg, "uct")) {
109 engine = E_UCT;
110 } else if (!strcasecmp(optarg, "distributed")) {
111 engine = E_DISTRIBUTED;
112 } else if (!strcasecmp(optarg, "patternscan")) {
113 engine = E_PATTERNSCAN;
114 } else if (!strcasecmp(optarg, "patternplay")) {
115 engine = E_PATTERNPLAY;
116 } else if (!strcasecmp(optarg, "joseki")) {
117 engine = E_JOSEKI;
118 } else {
119 fprintf(stderr, "%s: Invalid -e argument %s\n", argv[0], optarg);
120 exit(1);
122 break;
123 case 'd':
124 debug_level = atoi(optarg);
125 break;
126 case 'D':
127 debug_boardprint = false;
128 break;
129 case 'f':
130 fbookfile = strdup(optarg);
131 break;
132 case 'g':
133 gtp_port = strdup(optarg);
134 break;
135 case 'l':
136 log_port = strdup(optarg);
137 break;
138 case 's':
139 seed = atoi(optarg);
140 break;
141 case 't':
142 /* Time settings to follow; if specified,
143 * GTP time information is ignored. Useful
144 * e.g. when you want to force your bot to
145 * play weaker while giving the opponent
146 * reasonable time to play, or force play
147 * by number of simulations in timed games. */
148 /* Please see timeinfo.h:time_parse()
149 * description for syntax details. */
150 if (!time_parse(&ti_default, optarg)) {
151 fprintf(stderr, "%s: Invalid -t argument %s\n", argv[0], optarg);
152 exit(1);
154 ti_default.ignore_gtp = true;
155 assert(ti_default.period != TT_NULL);
156 break;
157 case 'u':
158 testfile = strdup(optarg);
159 break;
160 default: /* '?' */
161 usage(argv[0]);
162 exit(1);
166 if (log_port)
167 open_log_port(log_port);
169 fast_srandom(seed);
170 if (DEBUGL(0))
171 fprintf(stderr, "Random seed: %d\n", seed);
173 struct board *b = board_init(fbookfile);
174 struct time_info ti[S_MAX];
175 ti[S_BLACK] = ti_default;
176 ti[S_WHITE] = ti_default;
178 chat_init(chatfile);
180 char *e_arg = NULL;
181 if (optind < argc)
182 e_arg = argv[optind];
183 struct engine *e = init_engine(engine, e_arg, b);
185 if (testfile) {
186 unittest(testfile);
187 return 0;
190 if (gtp_port) {
191 open_gtp_connection(&gtp_sock, gtp_port);
194 for (;;) {
195 char buf[4096];
196 while (fgets(buf, 4096, stdin)) {
197 if (DEBUGL(1))
198 fprintf(stderr, "IN: %s", buf);
200 enum parse_code c = gtp_parse(b, e, ti, buf);
201 if (c == P_ENGINE_RESET) {
202 ti[S_BLACK] = ti_default;
203 ti[S_WHITE] = ti_default;
204 if (!e->keep_on_clear) {
205 b->es = NULL;
206 done_engine(e);
207 e = init_engine(engine, e_arg, b);
209 } else if (c == P_UNKNOWN_COMMAND && gtp_port) {
210 /* The gtp command is a weak identity check,
211 * close the connection with a wrong peer. */
212 break;
215 if (!gtp_port) break;
216 open_gtp_connection(&gtp_sock, gtp_port);
218 done_engine(e);
219 chat_done();
220 return 0;