#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 '*' 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(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(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 != PTN_VALID,stone,location%5,location/5); enum MOVE_DIRECTION direction; uint8_t steps; 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 != PTN_VALID,location%5,location/5, steps,drops[0],drops[1],drops[2],drops[3],drops[4]); char buf[10]; generate_move(5, 2+5*1, M_UP, 1, drops, buf); printf("Generated move: %s\n",buf); 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. */ 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; }