aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortslil <tslil@posteo.de>2020-12-31 21:19:38 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commit26f77822201aae05c493e1f1b71631d89b1c564c (patch)
treebf77d4f7868019cd4f75c4dc014476348ccad0e1
parent567db82c8988932fe27e695e6dbf0e3e7b1c020a (diff)
Working on line-mode front-end
-rw-r--r--src/ctaklm.c152
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;