aboutsummaryrefslogtreecommitdiff
path: root/include/action_list.c
diff options
context:
space:
mode:
authortslil clingman <tslil@posteo.de>2021-01-25 00:14:31 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commit3db577276b055ff7c8a8ed22302e9333ca679c26 (patch)
treeacfbb652c6d923835f08e29cea69f42c6cdb52e1 /include/action_list.c
parentd96ea8235a63bcb75e8b13286e84ee1b4168d127 (diff)
Lots of bugfixes, mostly uint vs int. Still weirdness in game
Diffstat (limited to 'include/action_list.c')
-rw-r--r--include/action_list.c123
1 files changed, 61 insertions, 62 deletions
diff --git a/include/action_list.c b/include/action_list.c
index 9afb199..50eb266 100644
--- a/include/action_list.c
+++ b/include/action_list.c
@@ -6,12 +6,9 @@
static inline action_list_t *
action_list_prepend(action_list_t *list, const enum A_TYPE type,
- const uint8_t loc, const uint8_t data0,
+ const int8_t loc, const uint8_t data0,
const uint8_t data1);
-static inline void inline_previous_ply(void);
-static inline void inline_next_ply(void);
-
// ===================================================================
// Exported method implementations
// ===================================================================
@@ -28,8 +25,7 @@ void action_list_free(action_list_t *list) {
// Keep track of move offsets
static int8_t deltas[4];
-void action_list_init(const uint8_t new_board_size) {
- board_size = new_board_size;
+void action_list_init(void) {
deltas[0] = +board_size;
deltas[1] = -board_size;
deltas[2] = -1;
@@ -37,24 +33,23 @@ void action_list_init(const uint8_t new_board_size) {
}
action_list_t *action_list_generate(void) {
-
action_list_t *result = NULL;
- const uint8_t black = (ply & 1),
+ const uint8_t black = (ply < 2) ? (ply==1) : (ply & 1),
material = (black) ? black_count : white_count,
flat = material & 127,
- cap = (ply > 2 && (material & 128)),
- standing = (ply > 2 && (material & 127));
+ cap = (ply >= 2 && (material & 128)),
+ standing = (ply >= 2 && (material & 127));
// Step across the board
for (uint8_t row = 0; row < board_size; row++) {
for (uint8_t col = 0; col < board_size; col++) {
- // We'll need these at various points, the location of this
+ // We'll need these at various points: the location of this
// square and the maximum number of stones we could pick up
- const uint8_t loc = THE_COORDS(col, row);
+ const int8_t loc = THE_COORDS(col, row);
const uint8_t count = (COUNT_AT(loc) > board_size) ? board_size : COUNT_AT(loc);
// Only try moves after CPS
- if (count && ((colours[loc] & 1) == current_colour) && ply>2) {
+ if (ply >= 2 && count && ((colours[loc] & 1) == current_colour)) {
// There are stones, let's try moving them
// Pre-compute end-stops
@@ -68,12 +63,13 @@ action_list_t *action_list_generate(void) {
// Now we check for caps and walls
const uint8_t cap_top = STONE_AT(loc) == STONE_CAPSTONE;
- for (uint8_t d = 0; d < board_size-1; d++){
+ for (uint8_t d = 0; d < 4; d++){
+ const int8_t delta = deltas[d];
end_stops[d][1] = 1;
const uint8_t stop = end_stops[d][0];
end_stops[d][0] = 0;
for (uint8_t k = 1; k <= stop; k++) {
- const uint8_t stone = STONE_AT(loc+k*deltas[d]);
+ const uint8_t stone = STONE_AT(loc+k*delta);
if (stone == STONE_STANDING) {
if (cap_top) {
end_stops[d][1] = 0;
@@ -93,13 +89,12 @@ action_list_t *action_list_generate(void) {
* summands as steps
*/
for (enum MOVE_DIRECTION dir = M_UP; dir <= M_RIGHT; dir++) {
- uint8_t gaps, t;
for (uint8_t num = 1; num <= count; num++) {
for (uint8_t steps = 1;
steps <= end_stops[dir][0] && steps <= num;
steps++) {
// TODO: Generalise to board_size!
- gaps = 0x07 >> (board_size-steps-1);
+ uint8_t gaps = 0x07 >> (board_size-steps-1);
// 0b0000[0111] because 4-1=3 and 5-1=4
do {
/*
@@ -109,28 +104,40 @@ action_list_t *action_list_generate(void) {
const uint8_t last_drop_check =
(num > 1) ? (gaps & 1<<(num - 2)) : 1;
if (end_stops[dir][1] || last_drop_check)
- result = action_list_prepend(result, A_MOVE, loc, (dir<<4) | num, gaps);
+ result = action_list_prepend(result, A_MOVE, loc, gaps, (dir<<4) | num);
/*
* With thanks to
* https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
* we have the following magic to generate the next
* permutation of steps-many set bits
*/
- t = (gaps | (gaps - 1));
+ uint8_t t = (gaps | (gaps - 1));
gaps = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(gaps) + 1));
} while (gaps && (gaps + 1 <= (1<<(num-1))));
}
}
}
- } else if (material && count == 0) {
+ } else if (count == 0 && material) {
// Empty square, generate placements
if (flat) {
- result = action_list_prepend(result, A_PLACE, loc, STONE_FLAT, 0);
+ result = action_list_prepend(result,
+ A_PLACE,
+ loc,
+ STONE_FLAT,
+ 0);
if (standing)
- result = action_list_prepend(result, A_PLACE, loc, STONE_STANDING, 0);
+ result = action_list_prepend(result,
+ A_PLACE,
+ loc,
+ STONE_STANDING,
+ 0);
}
if (cap)
- result = action_list_prepend(result, A_PLACE, loc, STONE_CAPSTONE, 0);
+ result = action_list_prepend(result,
+ A_PLACE,
+ loc,
+ STONE_CAPSTONE,
+ 0);
}
}
}
@@ -138,9 +145,9 @@ action_list_t *action_list_generate(void) {
}
void action_take(action_list_t *action) {
- const uint8_t loc = action->loc;
+ const int8_t loc = action->loc;
if (action->type == A_PLACE) {
- const uint8_t black = (ply&1);
+ const uint8_t black = (current_colour == C_BLACK);
switch (action->data0) {
case STONE_FLAT: {
if (black) black_count--;
@@ -167,8 +174,8 @@ void action_take(action_list_t *action) {
} else {
const uint8_t gaps = action->data0,
num = action->data1 & 0x0F, // unpack
- dir = action->data1 & 0xF0,
- delta = deltas[dir];
+ dir = action->data1 >> 4;
+ int8_t delta = deltas[dir];
// Unfortunately num == 1 is a special case
if (num > 1) {
@@ -176,7 +183,7 @@ void action_take(action_list_t *action) {
// Use the Kernighan method to count the set bits
for (steps = 1; gaps_prime; steps++) gaps_prime &= gaps_prime - 1;
// then from the destination to the source
- for (uint8_t d = 0; d + 1 < num; d++) {
+ for (uint8_t d = 0; d + 1 <= num; d++) {
// transfer the top colour
colours[loc+steps*delta] <<= 1;
colours[loc+steps*delta] |= colours[loc] & 1;
@@ -209,14 +216,29 @@ void action_take(action_list_t *action) {
celldat[loc] -= NUM_INC;
}
}
- // Always
- inline_next_ply();
+ // Next ply
+ ply++;
+ if (ply == 2) {
+ current_colour = C_WHITE;
+ } else {
+ if (current_colour == C_BLACK) current_colour = C_WHITE;
+ else current_colour = C_BLACK;
+ }
}
void action_undo(action_list_t *action) {
- const uint8_t loc = action->loc;
+ // Previous ply
+ if (ply>0) ply--;
+ if (ply == 1) {
+ current_colour = C_WHITE;
+ } else {
+ if (current_colour == C_BLACK) current_colour = C_WHITE;
+ else current_colour = C_BLACK;
+ }
+
+ const int8_t loc = action->loc;
if (action->type == A_PLACE) {
- const uint8_t black = (ply&1);
+ const uint8_t black = (current_colour == C_BLACK);
celldat[loc] = 0;
if (action->data0 == STONE_CAPSTONE) {
if (black) black_count |= 128;
@@ -229,18 +251,18 @@ void action_undo(action_list_t *action) {
// See action_take for comments, this is the time reversal
const uint8_t gaps = action->data0,
num = action->data1 & 0x0F, // unpack
- dir = action->data1 & 0xF0,
- delta = deltas[dir];
+ dir = action->data1 >> 4;
+ const int8_t delta = deltas[dir];
uint8_t steps = 1, mask = 1;
if (num > 1) {
- for (uint8_t d = 0; d + 1 < num; d++) {
+ for (uint8_t d = 0; d + 1 <= num; d++) {
colours[loc] <<= 1;
colours[loc] |= colours[loc+steps*delta] & 1;
colours[loc+steps*delta] >>= 1;
celldat[loc] += NUM_INC;
- if (d + 2 == num) {
+ if (d + 1 == num) {
celldat[loc] &= NUM_MASK;
celldat[loc] |= STONE_AT(loc+steps*delta);
celldat[loc+steps*delta] &= NUM_MASK;
@@ -264,17 +286,16 @@ void action_undo(action_list_t *action) {
celldat[loc+delta] -= NUM_INC;
}
}
- inline_previous_ply();
}
void action_to_ptn(action_list_t* action, char* out_ptn) {
- const uint8_t loc = action->loc;
+ const int8_t loc = action->loc;
if (action->type == A_PLACE) {
generate_place(loc, action->data0, out_ptn);
} else {
const uint8_t gaps = action->data0,
num = action->data1 & 0x0F, // unpack
- dir = action->data1 & 0xF0;
+ dir = action->data1 >> 4;
uint8_t drops[board_size]; // we only ever need board_size-1 in
// drops actually, the last spot is to
@@ -301,7 +322,7 @@ void action_to_ptn(action_list_t* action, char* out_ptn) {
static inline action_list_t *
action_list_prepend(action_list_t *list, const enum A_TYPE type,
- const uint8_t loc, const uint8_t data0,
+ const int8_t loc, const uint8_t data0,
const uint8_t data1) {
action_list_t *new = malloc(sizeof(action_list_t));
// TODO: trap errno
@@ -312,25 +333,3 @@ action_list_prepend(action_list_t *list, const enum A_TYPE type,
new->data1 = data1;
return new;
}
-
-static inline void
-inline_next_ply(void) {
- ply++;
- if (ply == 2) {
- current_colour = C_WHITE;
- } else {
- if (current_colour == C_BLACK) current_colour = C_WHITE;
- else current_colour = C_BLACK;
- }
-}
-
-static inline void
-inline_previous_ply(void) {
- if (ply>0) ply--;
- if (ply == 1) {
- current_colour = C_WHITE;
- } else {
- if (current_colour == C_BLACK) current_colour = C_WHITE;
- else current_colour = C_BLACK;
- }
-}