aboutsummaryrefslogtreecommitdiff
path: root/include/tak.c
diff options
context:
space:
mode:
Diffstat (limited to 'include/tak.c')
-rw-r--r--include/tak.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/include/tak.c b/include/tak.c
new file mode 100644
index 0000000..a4c053b
--- /dev/null
+++ b/include/tak.c
@@ -0,0 +1,59 @@
+#include "tak.h"
+
+// Be sure not to set higher bits in colour than LSB
+void set_stone(board_t board, bit_board_t *capstand,
+ const uint8_t location,
+ const uint8_t colour,
+ const enum STONE_VARIANT stone) {
+
+ board[location] = (STONE_IS_CAPSTAND(stone) ? CELL_MASK_CAPSTAND : 0x0000)
+ | CELL_COUNT_INC | colour;
+ if (stone == STONE_CAPSTONE) BITBOARD_SET(*capstand, location);
+}
+
+// This can overflow, checks are elsewhere
+void push_cells_stack(board_t board, bit_board_t *capstand,
+ const uint8_t location, const uint8_t count,
+ const uint8_t colours,
+ const enum STONE_VARIANT top_stone) {
+
+ if (top_stone == STONE_CAPSTONE) BITBOARD_RST(*capstand, location);
+
+ const cell_t cell = board[location];
+ const uint8_t new_count = CELL_GET_COUNT(cell) + count;
+ const uint8_t new_stack = (CELL_GET_STACK(cell) << count) | colours;
+
+ board[location] = (STONE_IS_CAPSTAND(top_stone) ? CELL_MASK_CAPSTAND : 0x0000)
+ | ((new_count > 0xA) ? 0xA : new_count)
+ | (new_stack & CELL_MASK_STACK);
+}
+
+// Calling this with count = 0 is destructive
+void drop_cells_stack(board_t board, bit_board_t *capstand,
+ const uint8_t location, const uint8_t count) {
+
+ // NOTE: We always clear the bitboard and capstand flags as it's not
+ // possible that those stones are underneath anything.
+
+ BITBOARD_RST(*capstand, location);
+ const uint8_t cur_count = CELL_GET_COUNT(board[location]);
+ if (count >= cur_count) {
+ board[location] = CELL_EMPTY_VALUE;
+ } else {
+ board[location] = ((cur_count - count) << CELL_COUNT_SHIFT)
+ | (CELL_GET_STACK(board[location]) >> count);
+ }
+}
+
+enum ACTION_RESULT try_place_stone(board_t board, bit_board_t *capstand,
+ const uint8_t location, const uint8_t colour,
+ const enum STONE_VARIANT stone)
+{
+ // Can't place on an occupied square
+ if (CELL_IS_EMPTY(board[location])) {
+ set_stone(board, capstand, location, colour, stone);
+ return A_OK;
+ } else {
+ return A_ILLEGAL;
+ }
+}