summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortslil <tslil@posteo.de>2020-12-30 21:00:08 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commit15e1d1008f05522570a9c80544b7ef24cf7c73df (patch)
tree22287e3d82bb4937cb190af121b8b17ff1bc527f
parent77de899d5b1abfabe40371f2f6fa4517ace0e28c (diff)
Board printing
-rw-r--r--include/tak.h2
-rw-r--r--src/ctaklm.c140
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 <tak.h>
-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. */