fbook: Deal with conflicts properly, make the hash size smaller
[pachi/ann.git] / fbook.c
blob4731eeb90bd2baee75a67bdca2562aa3363f214b
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 char conflict = is_pass(fbook->moves[bs[i]->hash & fbook_hash_mask]) ? '+' : 'C';
90 if (conflict == 'C')
91 for (int j = 0; j < i; j++)
92 if (bs[i]->hash == bs[j]->hash)
93 conflict = '+';
94 if (conflict == 'C') {
95 hash_t hi = bs[i]->hash;
96 while (!is_pass(fbook->moves[hi & fbook_hash_mask]) && fbook->hashes[hi & fbook_hash_mask] != bs[i]->hash)
97 hi++;
98 if (fbook->hashes[hi & fbook_hash_mask] == bs[i]->hash)
99 hi = 'c';
101 fprintf(stderr, "%c %"PRIhash" (<%d> %s)\n", conflict,
102 bs[i]->hash & fbook_hash_mask, i, linebuf);
103 #endif
104 hash_t hi = bs[i]->hash;
105 while (!is_pass(fbook->moves[hi & fbook_hash_mask]) && fbook->hashes[hi & fbook_hash_mask] != bs[i]->hash)
106 hi++;
107 fbook->moves[hi & fbook_hash_mask] = *c;
108 fbook->hashes[hi & fbook_hash_mask] = bs[i]->hash;
110 coord_done(c);
113 for (int i = 0; i < 8; i++) {
114 board_done(bs[i]);
117 fclose(f);
119 return fbook;
122 void fbook_done(struct fbook *fbook)
124 free(fbook);