ELO: Use probability distribution over available moves, not whole board
[pachi/json.git] / probdist.c
blobacdc6d24b797d5225b28ad3fb25b603a6034dfcd
1 #include <assert.h>
2 #include <math.h>
3 #include <stdio.h>
4 #include <stdlib.h>
6 #include "move.h"
7 #include "probdist.h"
8 #include "random.h"
10 struct probdist *
11 probdist_init(struct probdist *pd, int n)
13 if (!pd) pd = malloc(sizeof(*pd));
14 pd->n = n;
15 pd->items = calloc(n, sizeof(pd->items[0]));
16 pd->total = 0;
17 return pd;
20 coord_t
21 probdist_pick(struct probdist *pd)
23 assert(pd->total > -1); // -1..0 is rounding error
24 if (pd->total < __FLT_EPSILON__)
25 return pass;
26 float stab = (float) fast_random(65536) / 65536 * pd->total;
27 float sum = 0;
28 //fprintf(stderr, "stab %f / %f\n", stab, pd->total);
29 for (int i = 0; i < pd->n; i++) {
30 sum += pd->items[i];
31 if (stab < sum)
32 return i;
34 //fprintf(stderr, "overstab %f (total %f, sum %f)\n", stab, pd->total, sum);
35 // This can sometimes happen when also punching due to rounding errors,.
36 // Just assert that the difference is tiny.
37 assert(fabs(pd->total - stab) < 1);
38 return pass;
41 void
42 probdist_done(struct probdist *pd) {
43 free(pd->items);