10 #include "patternsp.h"
11 #include "patternprob.h"
14 /* We try to avoid needlessly reloading probability dictionary
15 * since it may take rather long time. */
16 static struct pattern_pdict
*cached_dict
;
18 struct pattern_pdict
*
19 pattern_pdict_init(char *filename
, struct pattern_config
*pc
)
27 filename
= "patterns.prob";
28 FILE *f
= fopen(filename
, "r");
31 fprintf(stderr
, "No pattern probtable, will not use learned patterns.\n");
35 struct pattern_pdict
*dict
= calloc2(1, sizeof(*dict
));
37 dict
->table
= calloc2(pc
->spat_dict
->nspatials
+ 1, sizeof(*dict
->table
));
39 char *sphcachehit
= malloc(pc
->spat_dict
->nspatials
);
40 hash_t (*sphcache
)[PTH__ROTATIONS
] = malloc(pc
->spat_dict
->nspatials
* sizeof(sphcache
[0]));
44 while (fgets(sbuf
, sizeof(sbuf
), f
)) {
45 struct pattern_prob
*pb
= calloc2(1, sizeof(*pb
));
49 if (buf
[0] == '#') continue;
50 while (isspace(*buf
)) buf
++;
51 while (!isspace(*buf
)) buf
++; // we recompute the probability
52 while (isspace(*buf
)) buf
++;
53 c
= strtol(buf
, &buf
, 10);
54 while (isspace(*buf
)) buf
++;
55 o
= strtol(buf
, &buf
, 10);
56 pb
->prob
= (floating_t
) c
/ o
;
57 while (isspace(*buf
)) buf
++;
58 str2pattern(buf
, &pb
->p
);
60 uint32_t spi
= pattern2spatial(dict
, &pb
->p
);
61 pb
->next
= dict
->table
[spi
];
62 dict
->table
[spi
] = pb
;
64 /* We rehash spatials in the order of loaded patterns. This way
65 * we make sure that the most popular patterns will be hashed
66 * last and therefore take priority. */
67 if (!sphcachehit
[spi
]) {
69 for (int r
= 0; r
< PTH__ROTATIONS
; r
++)
70 sphcache
[spi
][r
] = spatial_hash(r
, &pc
->spat_dict
->spatials
[spi
]);
72 for (int r
= 0; r
< PTH__ROTATIONS
; r
++)
73 spatial_dict_addh(pc
->spat_dict
, sphcache
[spi
][r
], spi
);
81 spatial_dict_hashstats(pc
->spat_dict
);
85 fprintf(stderr
, "Loaded %d pattern-probability pairs.\n", i
);
91 pattern_rate_moves(struct pattern_setup
*pat
,
92 struct board
*b
, enum stone color
,
93 struct pattern
*pats
, floating_t
*probs
)
96 for (int f
= 0; f
< b
->flen
; f
++) {
99 struct move mo
= { .coord
= b
->f
[f
], .color
= color
};
100 if (is_pass(mo
.coord
))
102 if (!board_is_valid_move(b
, &mo
))
105 pattern_match(&pat
->pc
, pat
->ps
, &pats
[f
], b
, &mo
);
106 floating_t prob
= pattern_prob(pat
->pd
, &pats
[f
]);