fast_irandom(): Fix for largest stabs
[pachi/t.git] / probdist.c
blobba1cf9eabf14243568326bd33abf3d88feafb1e8
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 double total = probdist_total(pd) - PROBDIST_EPSILON;
17 assert(total >= 0);
18 double stab = fast_frandom() * total;
19 if (DEBUGL(6))
20 fprintf(stderr, "stab %f / %f\n", stab, total);
22 int r = 0;
23 coord_t c = 0;
24 while (stab > pd->rowtotals[r] + PROBDIST_EPSILON) {
25 if (DEBUGL(6))
26 fprintf(stderr, "[%s] skipping row %f (%f)\n", coord2sstr(c, pd->b), pd->rowtotals[r], stab);
28 stab -= pd->rowtotals[r];
29 r++; assert(r < board_size(pd->b));
31 c += board_size(pd->b);
32 while (!is_pass(*ignore) && *ignore <= c)
33 ignore++;
36 for (; c < board_size2(pd->b); c++) {
37 if (DEBUGL(6))
38 fprintf(stderr, "[%s] %f (%f)\n", coord2sstr(c, pd->b), pd->items[c], stab);
40 assert(is_pass(*ignore) || c <= *ignore);
41 if (c == *ignore) {
42 if (DEBUGL(6))
43 fprintf(stderr, "ignored\n");
44 ignore++;
45 continue;
48 if (stab <= pd->items[c])
49 return c;
50 stab -= pd->items[c];
53 fprintf(stderr, "overstab %f (total %f)\n", stab, total);
54 assert(0);
55 return -1;