Moggy eyefillrate: Implement, based on Aja's suggestion long ago
[pachi/nmclean.git] / probdist.c
blob5e00b64f5b103d79b7e1b431f394661ed429db37
1 #include <assert.h>
2 #include <math.h>
3 #include <stdio.h>
4 #include <stdlib.h>
6 //#define DEBUG
7 #include "debug.h"
8 #include "move.h"
9 #include "probdist.h"
10 #include "random.h"
11 #include "board.h"
13 coord_t
14 probdist_pick(struct probdist *restrict pd, coord_t *restrict ignore)
16 fixp_t total = probdist_total(pd);
17 fixp_t stab = fast_irandom(total);
18 if (DEBUGL(6))
19 fprintf(stderr, "stab %f / %f\n", fixp_to_double(stab), fixp_to_double(total));
21 int r = 1;
22 coord_t c = board_size(pd->b) + 1;
23 while (stab > pd->rowtotals[r]) {
24 if (DEBUGL(6))
25 fprintf(stderr, "[%s] skipping row %f (%f)\n", coord2sstr(c, pd->b), fixp_to_double(pd->rowtotals[r]), fixp_to_double(stab));
27 stab -= pd->rowtotals[r];
28 r++; assert(r < board_size(pd->b));
30 c += board_size(pd->b);
31 while (!is_pass(*ignore) && *ignore <= c)
32 ignore++;
35 for (; c < board_size2(pd->b); c++) {
36 if (DEBUGL(6))
37 fprintf(stderr, "[%s] %f (%f)\n", coord2sstr(c, pd->b), fixp_to_double(pd->items[c]), fixp_to_double(stab));
39 assert(is_pass(*ignore) || c <= *ignore);
40 if (c == *ignore) {
41 if (DEBUGL(6))
42 fprintf(stderr, "\tignored\n");
43 ignore++;
44 continue;
47 if (stab <= pd->items[c])
48 return c;
49 stab -= pd->items[c];
52 fprintf(stderr, "overstab %f (total %f)\n", fixp_to_double(stab), fixp_to_double(total));
53 assert(0);
54 return -1;