libmap_queue_mqpick_ucb(): Resolve urgency ties fairly (randomly), instead of preferr...
[pachi.git] / mq.h
blob979aec6d96d0db2a1b832d08ac00615f444aefd0
1 #ifndef PACHI_MQ_H
2 #define PACHI_MQ_H
4 /* Move queues; in fact, they are more like move lists, usually used
5 * to accumulate equally good move candidates, then choosing from them
6 * randomly. But they are also used to juggle group lists (using the
7 * fact that coord_t == group_t). */
9 /* Warning: move_queue is further specialized upon in libmap_mq.
10 * Take care of that when doing any changes here. */
12 #include "move.h"
13 #include "random.h"
15 #define MQL 512 /* XXX: On larger board this might not be enough. */
16 struct move_queue {
17 unsigned int moves;
18 coord_t move[MQL];
19 /* Each move can have an optional tag or set of tags.
20 * The usage of these is user-dependent. */
21 unsigned char tag[MQL];
24 /* Pick a random move from the queue. */
25 static coord_t mq_pick(struct move_queue *q);
27 /* Add a move to the queue. */
28 static void mq_add(struct move_queue *q, coord_t c, unsigned char tag);
30 /* Cat two queues together. */
31 static void mq_append(struct move_queue *qd, struct move_queue *qs);
33 /* Check if the last move in queue is not a dupe, and remove it
34 * in that case. */
35 static void mq_nodup(struct move_queue *q);
37 /* Print queue contents on stderr. */
38 static void mq_print(struct move_queue *q, struct board *b, char *label);
41 static inline coord_t
42 mq_pick(struct move_queue *q)
44 return q->moves ? q->move[fast_random(q->moves)] : pass;
47 static inline void
48 mq_add(struct move_queue *q, coord_t c, unsigned char tag)
50 assert(q->moves < MQL);
51 q->tag[q->moves] = tag;
52 q->move[q->moves++] = c;
55 static inline void
56 mq_append(struct move_queue *qd, struct move_queue *qs)
58 assert(qd->moves + qs->moves < MQL);
59 memcpy(&qd->tag[qd->moves], qs->tag, qs->moves * sizeof(*qs->tag));
60 memcpy(&qd->move[qd->moves], qs->move, qs->moves * sizeof(*qs->move));
61 qd->moves += qs->moves;
64 static inline void
65 mq_nodup(struct move_queue *q)
67 for (unsigned int i = 1; i < 4; i++) {
68 if (q->moves <= i)
69 return;
70 if (q->move[q->moves - 1 - i] == q->move[q->moves - 1]) {
71 q->tag[q->moves - 1 - i] |= q->tag[q->moves - 1];
72 q->moves--;
73 return;
78 static inline void
79 mq_print(struct move_queue *q, struct board *b, char *label)
81 fprintf(stderr, "%s candidate moves: ", label);
82 for (unsigned int i = 0; i < q->moves; i++) {
83 fprintf(stderr, "%s ", coord2sstr(q->move[i], b));
85 fprintf(stderr, "\n");
88 #endif