#include #include #include #include <3rd-party/linenoise.h> #include 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 '*' static 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); } static 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(' '); } } } static 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(mod - 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'); } } } static void print_board(void) { for (uint8_t k = 0; k<=board_size*(SQUARE_H+1)+1; k++) { print_board_line(k); } } static 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); for (uint8_t k = 0; k ")) != NULL) { if (!strncmp(line,"board",6)) { print_board(); } else if (!strncmp(line,"square",6)) { if (strnlen(line, 9) >= 9 && line[7] >= 'a' && line[7] <= '`'+board_size && line[8] >= '1' && line[8] <= '0'+board_size) { print_square(line[7]-'a', line[8]-'1'); } else { printf("Usage: square [a-%c][1-%c]\n",'`'+board_size,'0'+board_size); } } else { r = do_ptn(line); printf("%d\n",r); print_board(); } /* /\* Do something with the string. *\/ */ /* if (line[0] != '\0' && line[0] != '/') { */ /* printf("echo: '%s'\n", line); */ /* linenoiseHistoryAdd(line); /\* Add to the history. *\/ */ /* /\* linenoiseHistorySave("history.txt"); /\\* Save the history on disk. *\\/ *\/ */ /* } else if (!strncmp(line,"/historylen",11)) { */ /* /\* The "/historylen" command will change the history len. *\/ */ /* int len = atoi(line+11); */ /* linenoiseHistorySetMaxLen(len); */ /* } else if (!strncmp(line, "/mask", 5)) { */ /* linenoiseMaskModeEnable(); */ /* } else if (!strncmp(line, "/unmask", 7)) { */ /* linenoiseMaskModeDisable(); */ /* } else if (line[0] == '/') { */ /* printf("Unreconized command: %s\n", line); */ /* } */ free(line); } return 0; }