#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; } }