From 15e1d1008f05522570a9c80544b7ef24cf7c73df Mon Sep 17 00:00:00 2001 From: tslil Date: Wed, 30 Dec 2020 21:00:08 -0500 Subject: Board printing --- include/tak.h | 2 +- src/ctaklm.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 134 insertions(+), 8 deletions(-) diff --git a/include/tak.h b/include/tak.h index d161640..0a6fcf1 100644 --- a/include/tak.h +++ b/include/tak.h @@ -20,7 +20,7 @@ typedef uint16_t colour_stack_t; #define STONE_MASK 0b00000011 #define STONE_AT(l) (celldat[(l)] & STONE_MASK) #define COUNT_AT(l) (celldat[(l)] >> NUM_SHIFT) -#define THE_COORDS(x,y) ((x)+(y)*board_size) +#define THE_COORDS(col,row) ((col)+(row)*board_size) uint8_t board_size; data_t celldat[36]; diff --git a/src/ctaklm.c b/src/ctaklm.c index 1342770..dee1855 100644 --- a/src/ctaklm.c +++ b/src/ctaklm.c @@ -5,26 +5,147 @@ #include <3rd-party/linenoise.h> #include -int main(int argc, char **argv) { +char *rev = "\033[7m"; + +char *blk = "\033[41m", *wht = "\033[44m"; + +char *und = "\033[4m"; +char *rst = "\033[0m"; + +#define SQUARE_W 5 +#define SQUARE_H 3 + +#define CHAR_FLT '#' +#define CHAR_STN '/' +#define CHAR_CAP '*' + +void +put_stone(const enum STONE_VARIANT stone, const enum COLOUR colour, + const uint8_t top, const uint8_t beyond_carry_limit) { + if (beyond_carry_limit) { + fputs(und,stdout); + } else { + if (colour == C_BLACK) fputs(blk, stdout); + else fputs(wht,stdout); + } + if (top) { + switch (stone) { + case STONE_FLAT: putchar(CHAR_FLT); break; + case STONE_STANDING: putchar(CHAR_STN); break; + case STONE_CAPSTONE: putchar(CHAR_CAP); break; + } + } else { + putchar( (colour == C_BLACK) ? 'B' : 'W' ); + } + fputs(rst,stdout); +} + +void +print_cell_line(const uint8_t line, + const uint8_t col, const uint8_t row) { + + const uint8_t location = THE_COORDS(col, row), + stack_size = COUNT_AT(location); + + uint8_t idx; + for (uint8_t k = 0; k < SQUARE_W; k++) { + idx = line + k*SQUARE_H; + // Are we in the last column to be displayed? + if ((k+1)*SQUARE_H > stack_size) { + // If so, then if we can't fill it offset the starting line so + // that it fills from the bottom up instead of the top down + if (line < (k+1)*SQUARE_H - stack_size ) { + // skip these lines + idx = 0xFF; + } else { + // offset back + idx -= (k+1)*SQUARE_H - stack_size; + } + } + if (idx < stack_size) { + put_stone(STONE_AT(location), colours[location] & (1 << idx), + idx == 0, idx >= board_size); + } else { + putchar(' '); + } + } +} + +void +print_board_line(const uint8_t line) { + const uint8_t mod = line % (SQUARE_H + 1), + row = board_size - line/(SQUARE_H + 1) - 1; + + if (mod == (SQUARE_H + 1)/2 ) printf("%d. ",row + 1); + else fputs(" ",stdout); + + if (mod == 0) { + for (uint8_t x = 0; x < board_size; x++) { + putchar('+'); + for (uint8_t k = 0; k < SQUARE_W; k++) putchar('-'); + } + puts("+"); + } else { + if (line < board_size*(SQUARE_H+1)) { + for (uint8_t x = 0; x < board_size; x++) { + putchar('|'); + print_cell_line(line - 1 , x, row); + } + puts("|"); + } else { + for (uint8_t x = 0; x < board_size; x++) { + for (uint8_t k = 0; k <= SQUARE_W/2; k++) putchar(' '); + printf("%c.",x+'a'); + for (uint8_t k = 0; k < SQUARE_W-SQUARE_W/2-2; k++) putchar(' '); + } + putchar('\n'); + } + } +} + +void +print_square(const uint8_t col, const uint8_t row) { + if (row < board_size && col < board_size) { + printf("%c%c: ",'a'+col,'1'+row); + const uint8_t stack_size = COUNT_AT(THE_COORDS(col, row)); + if (stack_size > 0) { + uint8_t mask = 1 << (stack_size - 1); + for (uint8_t k = 0; k < stack_size; k++, mask >>= 1) { + put_stone(STONE_AT(THE_COORDS(col, row)), + colours[THE_COORDS(col, row)] & mask, + k+1 == stack_size, + stack_size-k >= board_size); + } + printf("%s <-- top\n",rst); + } else { + puts("(empty)"); + } + } else { + printf("Requested square not on board (%d x %d).\n",board_size,board_size); + } +} + +int +main(int argc, char **argv) { reset_state(5); - enum E_RESULT r = try_place(0, C_BLACK, STONE_FLAT); - r = try_place(1, C_BLACK, STONE_FLAT); + enum E_RESULT r = try_place(THE_COORDS(0, 4), C_WHITE, STONE_STANDING); print_square(0, 4); + r = try_place(THE_COORDS(1, 4), C_BLACK, STONE_CAPSTONE); print_square(1, 4); uint8_t drops[5] = {1,0,0,0,0}; - r = try_move(1, M_LEFT, 1, drops); + r = try_move(THE_COORDS(1, 4), M_LEFT, 1, drops); print_square(0, 4); uint8_t location; enum STONE_VARIANT stone; r = parse_place(5, "Cb3", &location, &stone); - printf("Place <%d>: stone %d at (%d,%d)\n",r,stone,location%5,location/5); + printf("Place <%d>: stone %d at (%d,%d)\n",r != PTN_VALID,stone,location%5,location/5); enum MOVE_DIRECTION direction; uint8_t steps; - r = parse_move(5, "3c2+12", &location, &direction, &steps, drops); + r = parse_move(5, "1c2+", &location, &direction, &steps, drops); printf("Move <%d>: from (%d,%d) step %d sequence [%d,%d,%d,%d,%d]\n", - r,location%5,location/5, + r != PTN_VALID,location%5,location/5, steps,drops[0],drops[1],drops[2],drops[3],drops[4]); char buf[10]; @@ -34,6 +155,11 @@ int main(int argc, char **argv) { generate_place(5,1+5*2, STONE_CAPSTONE, buf); printf("Generated place: %s\n",buf); + for (uint8_t k = 0; k<=board_size*(SQUARE_H+1)+1; k++) { + print_board_line(k); + } + + return 0; char *line; while((line = linenoise("hello> ")) != NULL) { /* Do something with the string. */ -- cgit v1.3.1