12 coord_transform(struct board
*b
, coord_t coord
, int i
)
14 #define HASH_VMIRROR 1
15 #define HASH_HMIRROR 2
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
));
31 fbook_init(char *filename
, struct board
*b
)
33 FILE *f
= fopen(filename
, "r");
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
;
46 fprintf(stderr
, "Loading opening fbook %s...\n", filename
);
48 /* Scratch board where we lay out the sequence;
49 * one for each transposition. */
51 for (int i
= 0; i
< 8; i
++) {
52 bs
[i
] = board_init(NULL
);
53 board_resize(bs
[i
], fbook
->bsize
- 2);
57 while (fgets(linebuf
, sizeof(linebuf
), f
)) {
59 linebuf
[strlen(linebuf
) - 1] = 0; // chop
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)
69 while (isspace(*line
)) line
++;
71 for (int i
= 0; i
< 8; 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
);
87 while (!isspace(*line
)) line
++;
88 while (isspace(*line
)) 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
);
98 char conflict
= is_pass(fbook
->moves
[bs
[i
]->hash
& fbook_hash_mask
]) ? '+' : 'C';
100 for (int j
= 0; j
< i
; j
++)
101 if (bs
[i
]->hash
== bs
[j
]->hash
)
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
)
107 if (fbook
->hashes
[hi
& fbook_hash_mask
] == bs
[i
]->hash
)
110 fprintf(stderr
, "%c %"PRIhash
":%"PRIhash
" (<%d> %s)\n", conflict
,
111 bs
[i
]->hash
& fbook_hash_mask
, bs
[i
]->hash
, i
, linebuf
);
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
)
116 fbook
->moves
[hi
& fbook_hash_mask
] = coord
;
117 fbook
->hashes
[hi
& fbook_hash_mask
] = bs
[i
]->hash
;
122 for (int i
= 0; i
< 8; i
++) {
131 void fbook_done(struct fbook
*fbook
)