blob: d9545ac3cb64ae09af445b58757e3055d59df894 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#include "cnn1986_cache.h"
#define DATA_STONE_SHIFT 6
#define DATA_COUNT_SHIFT (DATA_STONE_SHIFT+2)
#define COLOUR_MASK 0x3F // 0b00111111
uint32_t cnn1986_num_cached, cnn1986_max_num_cached;
node_t *head = NULL, *tail = NULL;
void cnn1986_cache_free(void) {
node_t *c = head, *n;
while (c) {
n = c->next;
free(c);
c = n;
}
head = NULL;
tail = NULL;
}
int cnn1986_cache_seek(float *out_result) {
node_t *c = head;
if (c == NULL) return EXIT_FAILURE;
uint8_t comp_data[25], fail;
for (int k=0; k<25; k++) {
comp_data[k] = (colours[k] & COLOUR_MASK)
| (STONE_AT(k) << DATA_STONE_SHIFT)
| (COUNT_AT(k) << DATA_COUNT_SHIFT);
}
// We've checked c = head already, so uncoditionally test it
do {
// Compare
fail = 0;
if (c->black_count == black_count && c->white_count == white_count) {
for (int k=0; k<25; k++) {
if (comp_data[k] != c->data[k]) {
fail = 1;
break;
}
}
} else { fail = 1; }
// Either seek next or move to front and return
if (fail) {
c = c->next;
} else {
*out_result = c->result;
// Move to front
if (c != head) {
if (tail == c) tail=c->prev;
if (c->next) c->next->prev = c->prev;
c->prev->next = c->next;
c->prev = NULL;
c->next = head;
head->prev = c;
head = c;
}
return EXIT_SUCCESS;
}
} while (c);
// Failed to find it
return EXIT_FAILURE;
}
int cnn1986_cache_insert(float in_result) {
node_t *new = malloc(sizeof(node_t));
if (new == NULL) return EXIT_FAILURE;
// TODO: check errno
new->prev = NULL;
new->next = head;
if (head) head->prev = new;
head = new;
new->result = in_result;
new->white_count = white_count;
new->black_count = black_count;
for (int k=0; k<25; k++) {
new->data[k] = (colours[k] & COLOUR_MASK)
| (STONE_AT(k) << DATA_STONE_SHIFT)
| (COUNT_AT(k) << DATA_COUNT_SHIFT);
}
if (cnn1986_num_cached == 0) tail = new;
cnn1986_num_cached++;
if (cnn1986_num_cached > cnn1986_max_num_cached) {
tail = tail->prev;
free(tail->next);
tail->next = NULL;
cnn1986_num_cached--;
}
return EXIT_SUCCESS;
}
|