From 49d4f7867927a47d9a9b598236f76b509cc9b7b5 Mon Sep 17 00:00:00 2001 From: tslil Date: Tue, 22 Dec 2020 22:40:31 -0500 Subject: Init --- .gitignore | 2 ++ Makefile | 18 ++++++++++++++++++ include/tak.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/tak.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ctaklm.c | 8 ++++++++ 5 files changed, 141 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 include/tak.c create mode 100644 include/tak.h create mode 100644 src/ctaklm.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..261c153 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +ctaklm diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..afc530a --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +IDIR=include +CFLAGS=-g -Wall -I$(IDIR) +LIBS= + +SRCS=$(wildcard src/*.c) $(wildcard include/*.c) +OBJS=$(SRCS:.c=.o) + +PROG=ctaklm + +%.o: %.c + cc -c $< -o $@ $(CFLAGS) + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o $(PROG) + +clean: + rm -f $(PROG) + rm -f $(OBJS) 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; + } +} diff --git a/include/tak.h b/include/tak.h new file mode 100644 index 0000000..5a7f2fa --- /dev/null +++ b/include/tak.h @@ -0,0 +1,54 @@ +#include +#include + +/* 16 bits arranged as follows: + + MSB : capstone or standing stone + 14-11: number of stones in the cell, 0x0-0xA valid, 0xF means empty + 0-10 : stack, LSB is top + +*/ +typedef uint16_t cell_t; + +#define CELL_EMPTY_VALUE 0b0111100000000000 +#define CELL_MASK_CAPSTAND 0b1000000000000000 +#define CELL_MASK_COUNT CELL_EMPTY_VALUE +#define CELL_MASK_STACK 0b0000011111111111 +#define CELL_MASK_NOTSTACK 0b1111100000000000 + +#define CELL_COUNT_MAX 0b0101000000000000 +#define CELL_COUNT_INC 0b0000100000000000 +#define CELL_COUNT_SHIFT 11 + +#define CELL_IS_EMPTY(x) ((x) == CELL_EMPTY_VALUE) +#define CELL_IS_CAPSTAND(x) ((x) & CELL_MASK_CAPSTAND) +#define CELL_TOP_IS_BLACK(x) ((x) & 1) +#define CELL_TOP_IS_WHITE(x) (~(CELL_TOP_IS_BLACK(x))) + +#define CELL_SET_TOP_BLACK(x) ((x) |= 0x0001) +#define CELL_SET_TOP_WHITE(x) ((x) &= 0xFFFE) +#define CELL_SET_CAPSTAND(x) ((x) |= CELL_MASK_CAPSTAND) + +#define CELL_GET_COUNT(x) ((uint8_t)(((x) & CELL_MASK_COUNT) >> CELL_COUNT_SHIFT)) +#define CELL_GET_STACK(x) ((x) & CELL_MASK_STACK) +#define CELL_GET_NOTSTACK(x) ((x) & CELL_MASK_NOTSTACK) + +enum ACTION_RESULT { A_OK, A_ILLEGAL, A_OVERFLOW }; + +typedef cell_t* board_t; +typedef uint64_t bit_board_t; // 8x8 board is exactly 8 bytes :) + +#define BITBOARD_SET(bb,location) ((bb) |= 1ULL << (location)) +#define BITBOARD_RST(bb,location) ((bb) &= ~(1ULL << (location))) + +enum STONE_VARIANT { STONE_FLAT, STONE_STANDING, STONE_CAPSTONE }; +#define STONE_IS_CAPSTAND(s) ((s == STONE_CAPSTONE) || (s == STONE_STANDING)) + +// Taking actions +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); + +// enum ACTION_RESULT move_stack(board_t *board, bit_board *capstand, uint8_t source, uint); + +// Querying things diff --git a/src/ctaklm.c b/src/ctaklm.c new file mode 100644 index 0000000..8330012 --- /dev/null +++ b/src/ctaklm.c @@ -0,0 +1,8 @@ +#include +#include +#include + +int main(int argc, char **argv) { + cell_t x = CELL_EMPTY_VALUE; + printf("Test %d\n",x); +} -- cgit v1.2.3