From 49d4f7867927a47d9a9b598236f76b509cc9b7b5 Mon Sep 17 00:00:00 2001 From: tslil Date: Tue, 22 Dec 2020 22:40:31 -0500 Subject: Init --- include/tak.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 include/tak.c (limited to 'include/tak.c') 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; + } +} -- cgit v1.2.3