diff options
| -rw-r--r-- | src/ctaklm.c | 152 |
1 files changed, 114 insertions, 38 deletions
diff --git a/src/ctaklm.c b/src/ctaklm.c index ad8ab6e..52c29da 100644 --- a/src/ctaklm.c +++ b/src/ctaklm.c @@ -5,12 +5,8 @@ #include <3rd-party/linenoise.h> #include <tak.h> -char *rev = "\033[7m"; - -char *blk = "\033[41m", *wht = "\033[44m"; - -char *und = "\033[4m"; -char *rst = "\033[0m"; +const char *blk = "\033[41m", *wht = "\033[44m"; +const char *rev = "\033[7m", *und = "\033[4m", *rst = "\033[0m"; #define SQUARE_W 5 #define SQUARE_H 3 @@ -71,14 +67,19 @@ print_cell_line(const uint8_t line, } } +// It takes board_size*(SQUARE_H+1)+1 lines to print the board, they +// may be requested in any order and at any time 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; + // Print leader, either row number if half-way through square or + // padding spaces otherwise if (mod == (SQUARE_H + 1)/2 ) printf("%d. ",row + 1); else fputs(" ",stdout); + // Top and bottom of squares receive borders if (mod == 0) { for (uint8_t x = 0; x < board_size; x++) { putchar('+'); @@ -86,6 +87,7 @@ print_board_line(const uint8_t line) { } puts("+"); } else { + // Interior of board should be filled by borders and pieces if (line < board_size*(SQUARE_H+1)) { for (uint8_t x = 0; x < board_size; x++) { putchar('|'); @@ -93,6 +95,7 @@ print_board_line(const uint8_t line) { } puts("|"); } else { + // Bottom of board has column markers for (uint8_t x = 0; x < board_size; x++) { for (uint8_t k = 0; k <= SQUARE_W/2; k++) putchar(' '); printf("%c.",x+'a'); @@ -103,13 +106,15 @@ print_board_line(const uint8_t line) { } } +// Simple wrapper to print the whole board in one go static void print_board(void) { - for (uint8_t k = 0; k<=board_size*(SQUARE_H+1)+1; k++) { + for (uint8_t k = 0; k<board_size*(SQUARE_H+1)+2; k++) { print_board_line(k); } } +// Print the contents of a single square static void print_square(const uint8_t col, const uint8_t row) { if (row < board_size && col < board_size) { @@ -123,32 +128,114 @@ print_square(const uint8_t col, const uint8_t row) { k+1 == stack_size, stack_size-k >= board_size); } - printf("%s <-- top\n",rst); + puts("<-- top"); } else { puts("(empty)"); } } else { - printf("Requested square not on board (%d x %d).\n",board_size,board_size); + printf("Requested square not on board (%dx%d).\n",board_size,board_size); } } -int -main(int argc, char **argv) { - reset_state(5); +static void +print_info(void) { + printf("Turn: %d\nActive player: %s%s%s%s\n", + ply/2, + (ply & 1) ? blk : wht, + (ply & 1) ? "Black" : "White", + rst, + (ply < 2) ? " (counter-play start)" : ""); + printf("Flats remaining: %sWhite%s %02d, %sBlack%s %02d\n", + wht,rst,white_flats, + blk,rst,black_flats); + printf("Caps remaining: %sWhite%s %d, %sBlack%s %d\n", + wht,rst,white_caps, + blk,rst,black_caps); +} + +char *gamelog = 0; +uint8_t auto_board = 0xFF, auto_info = 0xFF; - for (uint8_t k = 0; k<board_size; k++) { - try_place(THE_COORDS(1, k), C_WHITE, STONE_FLAT); - if (k+1<board_size) - try_place(THE_COORDS(0, k), C_BLACK, STONE_FLAT); +static void +handle_turn(char *line) { + switch (do_ptn(line)) { + case PTN_INVALID : { + puts("Invalid PTN."); + break; + } + case ACT_ILLEGAL : { + puts("Illegal action."); + break; + } + case ACT_OVERFLOW : { + puts("Stack move would cause internal overflow, and we can't allow for that :)"); + break; + } + case WIN_DRAGON: + case WIN_FLAT_BLACK: + case WIN_FLAT_WHITE: + case WIN_ROAD_BLACK: + case WIN_ROAD_WHITE: { + puts(gamelog); + break; + } + // Valid, append to game log + default: { + // I _could_ dynamically compute the size but ... don't let + // `perfect' be the enemy of `good' ? + char prepend[8]; + if (ply & 1) { + snprintf(prepend, 7, "%s%d. ", + (ply == 1) ? "" : "\n", ply/2+1); + } else { + strcpy(prepend, " "); + } + // Make room for this line + gamelog = realloc(gamelog, + strlen(gamelog) + + strlen(prepend) + + strlen(line) + 1); + strcat(gamelog,prepend); + strcat(gamelog,line); + if (auto_info) print_info(); + if (auto_board) print_board(); + } } +} - check_win(); +static void +new_game(uint8_t size) { + reset_state(size); + printf("New %dx%d game!\n",size,size); + if (gamelog) gamelog = realloc(gamelog, sizeof(char)); + else gamelog = malloc(sizeof(char)); + gamelog[0] = 0; +} + +int +main(int argc, char **argv) { + new_game(5); - enum E_RESULT r; char *line; while((line = linenoise("ctaklm> ")) != NULL) { if (!strncmp(line,"board",6)) { print_board(); + } else if (!strncmp(line,"info",5)) { + print_info(); + } else if (!strncmp(line,"log",3)) { + puts(gamelog); + } else if (!strncmp(line,"auto",4)) { + if (!strncmp(line,"auto board",10)) { + auto_board = ~auto_board; + printf("Automatic board display %s.\n", + (auto_board) ? "Enabled" : "Disabled"); + } else if (!strncmp(line,"auto info",9)) { + auto_info = ~auto_info; + printf("Automatic info display %s.\n", + (auto_info) ? "Enabled" : "Disabled"); + } else { + puts("Usage: auto (board|info)"); + } } else if (!strncmp(line,"square",6)) { if (strnlen(line, 9) >= 9 && line[7] >= 'a' && line[7] <= '`'+board_size @@ -157,29 +244,18 @@ main(int argc, char **argv) { } else { printf("Usage: square [a-%c][1-%c]\n",'`'+board_size,'0'+board_size); } + } else if (!strncmp(line,"new",3)) { + if (line[3] == 0) { + new_game(5); + } else if (strnlen(line,5) >= 5 && line[4] >= '5' && line[4] <= '6') { + new_game(line[4]-'0'); + } else { + puts("Usage: new [56]\n"); + } } else { - r = do_ptn(line); - printf("%d\n",r); - print_board(); + handle_turn(line); } - /* /\* 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; |
