fbook: Properly flip not just sequences, but also the final coordinate
[pachi/json.git] / fbook.c
blob3713d3f47eb8c265364b8b8af0ebec6969202a54
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"
11 static coord_t
12 coord_transform(struct board *b, coord_t coord, int i)
14 #define HASH_VMIRROR 1
15 #define HASH_HMIRROR 2
16 #define HASH_XYFLIP 4
17 if (i & HASH_VMIRROR) {
18 coord = coord_xy(b, coord_x(coord, b), board_size(b) - 1 - coord_y(coord, b));
20 if (i & HASH_HMIRROR) {
21 coord = coord_xy(b, board_size(b) - 1 - coord_x(coord, b), coord_y(coord, b));
23 if (i & HASH_XYFLIP) {
24 coord = coord_xy(b, coord_y(coord, b), coord_x(coord, b));
26 return coord;
30 struct fbook *
31 fbook_init(char *filename, struct board *b)
33 FILE *f = fopen(filename, "r");
34 if (!f) {
35 perror(filename);
36 return NULL;
39 struct fbook *fbook = calloc(1, sizeof(*fbook));
40 fbook->bsize = board_size(b);
41 fbook->handicap = b->handicap;
42 for (int i = 0; i < 1<<fbook_hash_bits; i++)
43 fbook->moves[i] = pass;
45 if (DEBUGL(1))
46 fprintf(stderr, "Loading opening fbook %s...\n", filename);
48 /* Scratch board where we lay out the sequence;
49 * one for each transposition. */
50 struct board *bs[8];
51 for (int i = 0; i < 8; i++) {
52 bs[i] = board_init(NULL);
53 board_resize(bs[i], fbook->bsize - 2);
56 char linebuf[1024];
57 while (fgets(linebuf, sizeof(linebuf), f)) {
58 char *line = linebuf;
59 linebuf[strlen(linebuf) - 1] = 0; // chop
61 /* Format of line is:
62 * BSIZE COORD COORD COORD... | COORD
63 * We descend up to |, then add the new node
64 * with value minimax(1000), forcing UCT to
65 * always pick that node immediately. */
66 int bsize = strtol(line, &line, 10);
67 if (bsize != fbook->bsize - 2)
68 continue;
69 while (isspace(*line)) line++;
71 for (int i = 0; i < 8; i++) {
72 board_clear(bs[i]);
73 bs[i]->last_move.color = S_WHITE;
76 while (*line != '|') {
77 coord_t *c = str2coord(line, fbook->bsize);
79 for (int i = 0; i < 8; i++) {
80 coord_t coord = coord_transform(b, *c, i);
81 struct move m = { .coord = coord, .color = stone_other(bs[i]->last_move.color) };
82 int ret = board_play(bs[i], &m);
83 assert(ret >= 0);
86 coord_done(c);
87 while (!isspace(*line)) line++;
88 while (isspace(*line)) line++;
91 line++;
92 while (isspace(*line)) line++;
94 coord_t *c = str2coord(line, fbook->bsize);
95 for (int i = 0; i < 8; i++) {
96 coord_t coord = coord_transform(b, *c, i);
97 #if 0
98 char conflict = is_pass(fbook->moves[bs[i]->hash & fbook_hash_mask]) ? '+' : 'C';
99 if (conflict == 'C')
100 for (int j = 0; j < i; j++)
101 if (bs[i]->hash == bs[j]->hash)
102 conflict = '+';
103 if (conflict == 'C') {
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 if (fbook->hashes[hi & fbook_hash_mask] == bs[i]->hash)
108 hi = 'c';
110 fprintf(stderr, "%c %"PRIhash":%"PRIhash" (<%d> %s)\n", conflict,
111 bs[i]->hash & fbook_hash_mask, bs[i]->hash, i, linebuf);
112 #endif
113 hash_t hi = bs[i]->hash;
114 while (!is_pass(fbook->moves[hi & fbook_hash_mask]) && fbook->hashes[hi & fbook_hash_mask] != bs[i]->hash)
115 hi++;
116 fbook->moves[hi & fbook_hash_mask] = coord;
117 fbook->hashes[hi & fbook_hash_mask] = bs[i]->hash;
119 coord_done(c);
122 for (int i = 0; i < 8; i++) {
123 board_done(bs[i]);
126 fclose(f);
128 return fbook;
131 void fbook_done(struct fbook *fbook)
133 free(fbook);