diff options
Diffstat (limited to 'include/tak.c')
| -rw-r--r-- | include/tak.c | 59 |
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; + } +} |
