fbook: Use only at the game beginning (until first mismatch)
[pachi/derm.git] / fbook.c
blobdbe10ed95d1ea71f1d008d22b29be0c60c1ae1ea
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
6 #include "board.h"
7 #include "debug.h"
8 #include "fbook.h"
10 struct fbook *
11 fbook_init(char *filename, struct board *b)
13 FILE *f = fopen(filename, "r");
14 if (!f) {
15 perror(filename);
16 return NULL;
19 struct fbook *fbook = calloc(1, sizeof(*fbook));
20 fbook->bsize = board_size(b);
21 fbook->handicap = b->handicap;
22 for (int i = 0; i < 1<<fbook_hash_bits; i++)
23 fbook->moves[i] = pass;
25 if (DEBUGL(1))
26 fprintf(stderr, "Loading opening fbook %s...\n", filename);
28 /* Scratch board where we lay out the sequence;
29 * one for each transposition. */
30 struct board *bs[8];
31 for (int i = 0; i < 8; i++) {
32 bs[i] = board_init(NULL);
33 board_resize(bs[i], fbook->bsize - 2);
36 char linebuf[1024];
37 while (fgets(linebuf, sizeof(linebuf), f)) {
38 char *line = linebuf;
39 linebuf[strlen(linebuf) - 1] = 0; // chop
41 /* Format of line is:
42 * BSIZE COORD COORD COORD... | COORD
43 * We descend up to |, then add the new node
44 * with value minimax(1000), forcing UCT to
45 * always pick that node immediately. */
46 int bsize = strtol(line, &line, 10);
47 if (bsize != fbook->bsize - 2)
48 continue;
49 while (isspace(*line)) line++;
51 for (int i = 0; i < 8; i++) {
52 board_clear(bs[i]);
53 bs[i]->last_move.color = S_WHITE;
56 while (*line != '|') {
57 coord_t *c = str2coord(line, fbook->bsize);
59 for (int i = 0; i < 8; i++) {
60 #define HASH_VMIRROR 1
61 #define HASH_HMIRROR 2
62 #define HASH_XYFLIP 4
63 coord_t coord = *c;
64 if (i & HASH_VMIRROR) {
65 coord = coord_xy(b, coord_x(coord, b), board_size(b) - 1 - coord_y(coord, b));
67 if (i & HASH_HMIRROR) {
68 coord = coord_xy(b, board_size(b) - 1 - coord_x(coord, b), coord_y(coord, b));
70 if (i & HASH_XYFLIP) {
71 coord = coord_xy(b, coord_y(coord, b), coord_x(coord, b));
73 struct move m = { .coord = coord, .color = stone_other(bs[i]->last_move.color) };
74 int ret = board_play(bs[i], &m);
75 assert(ret >= 0);
78 coord_done(c);
79 while (!isspace(*line)) line++;
80 while (isspace(*line)) line++;
83 line++;
84 while (isspace(*line)) line++;
86 coord_t *c = str2coord(line, fbook->bsize);
87 for (int i = 0; i < 8; i++) {
88 #if 0
89 fprintf(stderr, "%c %"PRIhash" (<%d> %s)\n",
90 is_pass(fbook->moves[bs[i]->hash & fbook_hash_mask]) ? '+' : 'C',
91 bs[i]->hash & fbook_hash_mask, i, linebuf);
92 #endif
93 fbook->moves[bs[i]->hash & fbook_hash_mask] = *c;
95 coord_done(c);
98 for (int i = 0; i < 8; i++) {
99 board_done(bs[i]);
102 fclose(f);
104 return fbook;
107 void fbook_done(struct fbook *fbook)
109 free(fbook);