aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authortslil <tslil@posteo.de>2021-01-03 17:36:12 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commit93bb0f481e9709e3aa737c889ce9df0ad9de1585 (patch)
tree98a90b318706613827d3cadf2b72824f5192e76d /include
parent60dfb616282023dbc1f567355357e27018693077 (diff)
Set dialect to C99
Diffstat (limited to 'include')
-rw-r--r--include/tak.c124
1 files changed, 64 insertions, 60 deletions
diff --git a/include/tak.c b/include/tak.c
index b1a20f2..cd9c23c 100644
--- a/include/tak.c
+++ b/include/tak.c
@@ -39,7 +39,7 @@ reset_state(const uint8_t new_board_size) {
}
ply = 0;
- won = -1; // i may live to regret this hack
+ won = 0xFF; // i may live to regret this hack
current_colour = C_BLACK;
for (uint8_t k = 0; k < NUM_SQUARES; k++ ) {
@@ -64,36 +64,40 @@ next_ply(void) {
enum E_RESULT
try_place(const int8_t location, const enum COLOUR colour,
- const enum STONE_VARIANT stone)
+ const enum STONE_VARIANT stone)
{
// Game is over?
- if (won < -1) return GAME_END;
+ if (won < 0xFF) return GAME_END;
// Can't place on an occupied square
if (COUNT_AT(location)) {
return ACT_ILLEGAL;
} else {
switch (stone) {
- case STONE_STANDING: if (ply < 2) return ACT_ILLEGAL;
+ case STONE_STANDING:
+ if (ply < 2) return ACT_ILLEGAL;
+ // behold the magic GCC comment which defeates
+ // -Wimplicit-fallthrough:
+ // fall through
case STONE_FLAT: {
- if (colour == C_BLACK) {
- if (black_count & 127) black_count--;
- else return ACT_ILLEGAL;
- } else {
- if (white_count & 127) white_count--;
- else return ACT_ILLEGAL;
- }
- break;
+ if (colour == C_BLACK) {
+ if (black_count & 127) black_count--;
+ else return ACT_ILLEGAL;
+ } else {
+ if (white_count & 127) white_count--;
+ else return ACT_ILLEGAL;
+ }
+ break;
}
case STONE_CAPSTONE: {
- if (ply < 2) return ACT_ILLEGAL;
- if (colour == C_BLACK) {
- if (black_count & 128) black_count &= 127;
- else return ACT_ILLEGAL;
- } else {
- if (white_count & 128) white_count &= 127;
- else return ACT_ILLEGAL;
- }
- break;
+ if (ply < 2) return ACT_ILLEGAL;
+ if (colour == C_BLACK) {
+ if (black_count & 128) black_count &= 127;
+ else return ACT_ILLEGAL;
+ } else {
+ if (white_count & 128) white_count &= 127;
+ else return ACT_ILLEGAL;
+ }
+ break;
}
}
@@ -109,20 +113,20 @@ try_place(const int8_t location, const enum COLOUR colour,
static void
push_stones(const int8_t location, const uint8_t count, const uint8_t new_colours,
- const enum STONE_VARIANT top_stone) {
+ const enum STONE_VARIANT top_stone) {
colours[location] = (colours[location] << count) | new_colours;
celldat[location] = ((celldat[location] + ((count << NUM_SHIFT))) & NUM_MASK) | top_stone;
}
enum E_RESULT
try_move(const int8_t location, const enum MOVE_DIRECTION direction,
- const uint8_t steps, const uint8_t drops[5]) {
+ const uint8_t steps, const uint8_t drops[5]) {
// Game is over?
- if (won < -1) return GAME_END;
+ if (won < 0xFF) return GAME_END;
// Can't do this
if (steps == 0 || steps > 5) return ACT_ILLEGAL;
// Is the desired direction and count on the board?
- int8_t delta = 0;
+ uint8_t delta = 0;
switch (direction) {
case M_UP: {
delta = +board_size;
@@ -163,11 +167,11 @@ try_move(const int8_t location, const enum MOVE_DIRECTION direction,
return ACT_ILLEGAL;
// Check for wall
if ( (STONE_AT(location+(k+1)*delta) == STONE_STANDING)
- // If not last drop, or not dropping just one, or not a cap
- && ( (k+1 < steps)
- || (drops[k] != 1)
- || (STONE_AT(location) != STONE_CAPSTONE) )
- )
+ // If not last drop, or not dropping just one, or not a cap
+ && ( (k+1 < steps)
+ || (drops[k] != 1)
+ || (STONE_AT(location) != STONE_CAPSTONE) )
+ )
return ACT_ILLEGAL;
total += drops[k];
}
@@ -183,9 +187,9 @@ try_move(const int8_t location, const enum MOVE_DIRECTION direction,
for (uint8_t k = 0; k < steps; k++) {
j -= drops[k];
push_stones(location+(k+1)*delta,
- drops[k],
- (colours[location] >> j) & (0xFFFF >> (0x10 - drops[k])),
- (k == steps - 1) ? STONE_AT(location) : STONE_FLAT);
+ drops[k],
+ (colours[location] >> j) & (0xFFFF >> (0x10 - drops[k])),
+ (k == steps - 1) ? STONE_AT(location) : STONE_FLAT);
}
// Then we drop them from the source
colours[location] >>= total;
@@ -204,49 +208,49 @@ try_move(const int8_t location, const enum MOVE_DIRECTION direction,
// direction = 0 --> left-to-right, direction = 1 --> bottom-to-top
static uint8_t
dfs_road(uint8_t dfs_stack[NUM_SQUARES], uint8_t dfs_pntr,
- const enum COLOUR colour, const uint8_t direction) {
+ const enum COLOUR colour, const uint8_t direction) {
while (dfs_pntr > 0) {
const uint8_t cur = dfs_stack[--dfs_pntr];
// Made it to the other side?
if ( (direction == 1 && cur >= board_size * (board_size - 1))
- || (direction == 0 && cur % board_size == 1) )
- return 1;
+ || (direction == 0 && cur % board_size == 1) )
+ return 1;
// Check the four neighbours of this cell, provided they exist,
// are inhabited, and are of the appropriate colour
// Direction: > (same row)
if ( ((cur % board_size) + 1 < board_size)
- && (COUNT_AT(cur + 1)) // wont ever be out of bounds
- && ((colours[cur+1] & 1) == colour)
- && ((celldat[cur+1] & DFS_MASK) == 0) ) {
+ && (COUNT_AT(cur + 1)) // wont ever be out of bounds
+ && ((colours[cur+1] & 1) == colour)
+ && ((celldat[cur+1] & DFS_MASK) == 0) ) {
dfs_stack[dfs_pntr++] = cur + 1;
celldat[cur+1] |= DFS_MASK;
}
// Direction: < (same row)
if ( (cur % board_size > 0)
- && (COUNT_AT(cur - 1)) // wont ever be out of bounds
- && ((colours[cur-1] & 1) == colour)
- && ((celldat[cur-1] & DFS_MASK) == 0) ) {
+ && (COUNT_AT(cur - 1)) // wont ever be out of bounds
+ && ((colours[cur-1] & 1) == colour)
+ && ((celldat[cur-1] & DFS_MASK) == 0) ) {
dfs_stack[dfs_pntr++] = cur - 1;
celldat[cur-1] |= DFS_MASK;
}
// Direction: +
if ( (cur + board_size < NUM_SQUARES)
- && (COUNT_AT(cur + board_size))
- && ((colours[cur+board_size] & 1) == colour)
- && ((celldat[cur+board_size] & DFS_MASK) == 0) ) {
+ && (COUNT_AT(cur + board_size))
+ && ((colours[cur+board_size] & 1) == colour)
+ && ((celldat[cur+board_size] & DFS_MASK) == 0) ) {
dfs_stack[dfs_pntr++] = cur + board_size;
celldat[cur+board_size] |= DFS_MASK;
}
// Direction: -
if ( (cur >= board_size)
- && (COUNT_AT(cur - board_size))
- && ((colours[cur-board_size] & 1) == colour)
- && ((celldat[cur-board_size] & DFS_MASK) == 0) ) {
+ && (COUNT_AT(cur - board_size))
+ && ((colours[cur-board_size] & 1) == colour)
+ && ((celldat[cur-board_size] & DFS_MASK) == 0) ) {
dfs_stack[dfs_pntr++] = cur - board_size;
celldat[cur-board_size] |= DFS_MASK;
}
@@ -275,7 +279,7 @@ check_road_colour(const enum COLOUR colour) {
dfs_pntr = 0;
for (uint8_t y=0; y<board_size; y++) {
if ( COUNT_AT(THE_COORDS(0, y)) &&
- (colours[THE_COORDS(0, y)] & 1) == colour) {
+ (colours[THE_COORDS(0, y)] & 1) == colour) {
dfs_stack[dfs_pntr++] = THE_COORDS(0, y);
celldat[THE_COORDS(0, y)] |= DFS_MASK;
}
@@ -290,7 +294,7 @@ check_road_colour(const enum COLOUR colour) {
dfs_pntr = 0;
for (uint8_t x=0; x<board_size; x++) {
if ( COUNT_AT(THE_COORDS(x, 0)) &&
- (colours[THE_COORDS(x, 0)] & 1) == colour) {
+ (colours[THE_COORDS(x, 0)] & 1) == colour) {
dfs_stack[dfs_pntr++] = THE_COORDS(x, 0);
celldat[THE_COORDS(x, 0)] |= DFS_MASK;
}
@@ -344,7 +348,7 @@ check_win(void) {
enum E_RESULT
parse_place(const uint8_t board_size, char *ptn,
- uint8_t *out_location, enum STONE_VARIANT *out_stone) {
+ uint8_t *out_location, enum STONE_VARIANT *out_stone) {
if (board_size < 5 || board_size > 6) return PTN_INVALID;
@@ -378,8 +382,8 @@ parse_place(const uint8_t board_size, char *ptn,
enum E_RESULT
parse_move(const uint8_t board_size, char *ptn,
- uint8_t *out_location, enum MOVE_DIRECTION *out_direction,
- uint8_t *out_steps, uint8_t out_drops[5]) {
+ uint8_t *out_location, enum MOVE_DIRECTION *out_direction,
+ uint8_t *out_steps, uint8_t out_drops[5]) {
if (board_size < 5 || board_size > 6) return PTN_INVALID;
@@ -454,7 +458,7 @@ parse_move(const uint8_t board_size, char *ptn,
void
generate_place(const uint8_t board_size, const uint8_t in_location,
- const enum STONE_VARIANT in_stone, char out_ptn[4]) {
+ const enum STONE_VARIANT in_stone, char out_ptn[4]) {
switch (in_stone) {
case STONE_FLAT: { break; }
case STONE_STANDING: { *out_ptn = 'S'; out_ptn++; break; }
@@ -471,9 +475,9 @@ generate_place(const uint8_t board_size, const uint8_t in_location,
void
generate_move(const uint8_t board_size, const uint8_t in_location,
- const enum MOVE_DIRECTION in_direction,
- const uint8_t in_steps, const uint8_t in_drops[5],
- char out_ptn[10]) {
+ const enum MOVE_DIRECTION in_direction,
+ const uint8_t in_steps, const uint8_t in_drops[5],
+ char out_ptn[10]) {
uint8_t total = 0;
for (uint8_t k = 0; k<in_steps; k++) total+=in_drops[k];
if (total > 1) {
@@ -519,7 +523,7 @@ is_not_placement(char *ptn) {
enum E_RESULT
do_ptn(char *ptn) {
// Game over?
- if (won < -1) return GAME_END;
+ if (won < 0xFF) return GAME_END;
enum E_RESULT res;
uint8_t location;
@@ -530,7 +534,7 @@ do_ptn(char *ptn) {
enum MOVE_DIRECTION direction;
// Parse it as a move
res = parse_move(board_size, ptn, &location,
- &direction, &steps, drops);
+ &direction, &steps, drops);
// If valid PTN, try to do it
if (res == PTN_VALID) {
if (ply < 2) return ACT_ILLEGAL;
@@ -552,7 +556,7 @@ do_ptn(char *ptn) {
// more conservative here :)
if (ply > board_size) {
won = check_win();
- if (won < -1) return GAME_END;
+ if (won < 0xFF) return GAME_END;
}
}