aboutsummaryrefslogtreecommitdiff
path: root/include/tps.c
diff options
context:
space:
mode:
authortslil clingman <tslil@posteo.de>2021-10-05 18:22:23 -0400
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commitcf175fc346f1b208766b1f55d3673a7b208f322a (patch)
tree3dabfd672b73e7d0756d8259e59464d1f560aee6 /include/tps.c
parent640d404b3cf3324aca4424fc3da4806d4562d0e4 (diff)
Welcome geminict!
This is a special interface to negamax_cnn1986 which is designed to generate output for use in a CGI tak interface to be used over gemini. Also in this commit is a reformating of the various source files to use the traditional tab width of 8 spaces.
Diffstat (limited to 'include/tps.c')
-rw-r--r--include/tps.c386
1 files changed, 193 insertions, 193 deletions
diff --git a/include/tps.c b/include/tps.c
index be25c4f..7be0e8d 100644
--- a/include/tps.c
+++ b/include/tps.c
@@ -8,155 +8,155 @@
enum TPS_RESULT
load_tps(char* tps) {
- // TODO: Ensure NULL termination?
- if (tps == NULL) return TPS_INVALID;
-
- uint8_t prefix = 0;
- // Check if we're likely of the form [TPS "blah"]
- if (!strncmp(tps, "[TPS \"", 6)) {
- prefix=1;
- // Now we can worry about just the TPS part
- tps += 6;
- }
-
- // Reset everything
- reset_state(board_size);
-
- // Parse squares, NOTE: We assume that board_size matches TPS size.
- int col = 0, row = board_size-1, skip, parsing = 1;
- while (parsing) {
- switch (*tps) {
- case ' ': {
- // we're done
- parsing = 0;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- case 'x': {
- // empty squares
- tps++; TPS_ASSERT_MORE;
- skip = 0;
- if (*tps >= '2' && *tps <= '0'+board_size) {
- skip = *tps - '1';
- tps++; TPS_ASSERT_MORE;
- } else if (*tps != ',' && *tps != '/' && *tps != ' ') {
- return TPS_INVALID;
- }
- col += skip;
- if (col >= board_size + 1) return TPS_INVALID;
- break;
- }
- case '/': {
- // next row
- if (col + 1 != board_size) return TPS_INVALID;
- row--; col = 0;
- if (row < 0) return TPS_INVALID;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- case ',': {
- // next column
- col++;
- if (col >= board_size) return TPS_INVALID;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- default: {
- const int l = THE_COORDS(col, row);
- uint8_t num_read = 0, reading = 1;
- // Read in a stack of colours, optionally terminated by an S
- // or C to change the top stone type
- while (reading) {
- switch (*tps) {
- // Reading a stone colour
- case '2': {
- // check next letter to make sure we have the material
- tps++; TPS_ASSERT_MORE;
- if (*tps == 'C') {
- if (black_count & 128) black_count &= 127;
- else return TPS_INVALID;
- } else if (black_count & 127) {
- black_count--;
- } else return TPS_INVALID;
- colours[l] <<= 1;
- celldat[l] += NUM_INC;
- colours[l] |= 1;
- num_read++;
- break;
- }
- case '1': {
- tps++; TPS_ASSERT_MORE;
- if (*tps == 'C') {
- if (white_count & 128) white_count &= 127;
- else return TPS_INVALID;
- } else if (white_count & 127) {
- white_count--;
- } else return TPS_INVALID;
- colours[l] <<= 1;
- celldat[l] += NUM_INC;
- num_read++;
- break;
- }
- case 'S': {
- // Have we already read a stone type?
- if (STONE_AT(l) != STONE_FLAT) return TPS_INVALID;
- celldat[l] |= STONE_STANDING;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- case 'C': {
- if (STONE_AT(l) != STONE_FLAT) return TPS_INVALID;
- celldat[l] |= STONE_CAPSTONE;
- tps++; TPS_ASSERT_MORE;
- break;
- }
- case ',': // fall-through
- case '/': {
- // done here
- reading=0;
- break;
- }
- default: return TPS_INVALID;
- }
- if (num_read > 0xF) return TPS_INVALID;
- }
- }
- }
+ // TODO: Ensure NULL termination?
+ if (tps == NULL) return TPS_INVALID;
+
+ uint8_t prefix = 0;
+ // Check if we're likely of the form [TPS "blah"]
+ if (!strncmp(tps, "[TPS \"", 6)) {
+ prefix=1;
+ // Now we can worry about just the TPS part
+ tps += 6;
+ }
+
+ // Reset everything
+ reset_state(board_size);
+
+ // Parse squares, NOTE: We assume that board_size matches TPS size.
+ int col = 0, row = board_size-1, skip, parsing = 1;
+ while (parsing) {
+ switch (*tps) {
+ case ' ': {
+ // we're done
+ parsing = 0;
+ tps++; TPS_ASSERT_MORE;
+ break;
+ }
+ case 'x': {
+ // empty squares
+ tps++; TPS_ASSERT_MORE;
+ skip = 0;
+ if (*tps >= '2' && *tps <= '0'+board_size) {
+ skip = *tps - '1';
+ tps++; TPS_ASSERT_MORE;
+ } else if (*tps != ',' && *tps != '/' && *tps != ' ') {
+ return TPS_INVALID;
}
-
- // Now it's time to parse the ply number. First, the active player
- if (*tps != '1' && *tps != '2') return TPS_INVALID;
- ply += *tps - '1';
+ col += skip;
+ if (col >= board_size + 1) return TPS_INVALID;
+ break;
+ }
+ case '/': {
+ // next row
+ if (col + 1 != board_size) return TPS_INVALID;
+ row--; col = 0;
+ if (row < 0) return TPS_INVALID;
tps++; TPS_ASSERT_MORE;
-
- // Space
- if (*tps != ' ') return TPS_INVALID;
+ break;
+ }
+ case ',': {
+ // next column
+ col++;
+ if (col >= board_size) return TPS_INVALID;
tps++; TPS_ASSERT_MORE;
-
- // Turn number, atoi doesn't detect errors so let's do it ourselves
- uint8_t p = 0;
- do {
- p *= 10;
- if (*tps >= '0' && *tps <= '9') {
- p += *tps - '0';
- } else return TPS_INVALID;
- tps++;
- } while ( (prefix && *tps && *tps != '"') || (!prefix && *tps) );
- if (p == 0) return TPS_INVALID;
- ply += 2*(p - 1);
-
- current_colour = (ply & 1) ? C_BLACK : C_WHITE;
- if (ply < 2) current_colour = C_BLACK - current_colour;
-
- if (prefix) {
- tps++; TPS_ASSERT_MORE;
- if (*tps != ']' ) return TPS_INVALID;
-
- tps++;
- if (*tps != 0) return TPS_INVALID;
+ break;
+ }
+ default: {
+ const int l = THE_COORDS(col, row);
+ uint8_t num_read = 0, reading = 1;
+ // Read in a stack of colours, optionally terminated by an S
+ // or C to change the top stone type
+ while (reading) {
+ switch (*tps) {
+ // Reading a stone colour
+ case '2': {
+ // check next letter to make sure we have the material
+ tps++; TPS_ASSERT_MORE;
+ if (*tps == 'C') {
+ if (black_count & 128) black_count &= 127;
+ else return TPS_INVALID;
+ } else if (black_count & 127) {
+ black_count--;
+ } else return TPS_INVALID;
+ colours[l] <<= 1;
+ celldat[l] += NUM_INC;
+ colours[l] |= 1;
+ num_read++;
+ break;
+ }
+ case '1': {
+ tps++; TPS_ASSERT_MORE;
+ if (*tps == 'C') {
+ if (white_count & 128) white_count &= 127;
+ else return TPS_INVALID;
+ } else if (white_count & 127) {
+ white_count--;
+ } else return TPS_INVALID;
+ colours[l] <<= 1;
+ celldat[l] += NUM_INC;
+ num_read++;
+ break;
+ }
+ case 'S': {
+ // Have we already read a stone type?
+ if (STONE_AT(l) != STONE_FLAT) return TPS_INVALID;
+ celldat[l] |= STONE_STANDING;
+ tps++; TPS_ASSERT_MORE;
+ break;
+ }
+ case 'C': {
+ if (STONE_AT(l) != STONE_FLAT) return TPS_INVALID;
+ celldat[l] |= STONE_CAPSTONE;
+ tps++; TPS_ASSERT_MORE;
+ break;
+ }
+ case ',': // fall-through
+ case '/': {
+ // done here
+ reading=0;
+ break;
+ }
+ default: return TPS_INVALID;
+ }
+ if (num_read > 0xF) return TPS_INVALID;
}
-
- return TPS_OK;
+ }
+ }
+ }
+
+ // Now it's time to parse the ply number. First, the active player
+ if (*tps != '1' && *tps != '2') return TPS_INVALID;
+ ply += *tps - '1';
+ tps++; TPS_ASSERT_MORE;
+
+ // Space
+ if (*tps != ' ') return TPS_INVALID;
+ tps++; TPS_ASSERT_MORE;
+
+ // Turn number, atoi doesn't detect errors so let's do it ourselves
+ uint8_t p = 0;
+ do {
+ p *= 10;
+ if (*tps >= '0' && *tps <= '9') {
+ p += *tps - '0';
+ } else return TPS_INVALID;
+ tps++;
+ } while ( (prefix && *tps && *tps != '"') || (!prefix && *tps) );
+ if (p == 0) return TPS_INVALID;
+ ply += 2*(p - 1);
+
+ current_colour = (ply & 1) ? C_BLACK : C_WHITE;
+ if (ply < 2) current_colour = C_BLACK - current_colour;
+
+ if (prefix) {
+ tps++; TPS_ASSERT_MORE;
+ if (*tps != ']' ) return TPS_INVALID;
+
+ tps++;
+ if (*tps != 0) return TPS_INVALID;
+ }
+
+ return TPS_OK;
}
// ===================================================================
@@ -165,53 +165,53 @@ load_tps(char* tps) {
void
generate_tps(char *out_tps) {
- strcpy(out_tps, "[TPS \"");
- out_tps += 6;
-
- for (int8_t row = board_size - 1; row >= 0; row--) {
- for (int8_t col = 0; col < board_size; col++) {
- const int8_t l = THE_COORDS(col, row);
- const uint8_t count = COUNT_AT(l);
- if (count) {
- colour_stack_t c = colours[l], s = 1<<(count - 1);
- for (int k=0; k<count; k++, s >>=1, out_tps++) {
- if (c & s) *out_tps = '2';
- else *out_tps = '1';
- }
- switch (STONE_AT(l)) {
- case STONE_CAPSTONE: {
- *out_tps = 'C'; out_tps++; break;
- }
- case STONE_STANDING: {
- *out_tps = 'S'; out_tps++; break;
- }
- default: break;
- }
- } else {
- int8_t skip = 1;
- while (col < board_size && COUNT_AT(l+skip) == 0) {
- skip++;
- col++;
- }
- *out_tps = 'x'; out_tps++;
- if (skip > 1) {
- *out_tps = '0'+skip; out_tps++;
- }
- }
- if (col + 1 < board_size) {
- *out_tps = ','; out_tps++;
- }
- }
- if (row > 0) {
- *out_tps = '/'; out_tps++;
- }
+ strcpy(out_tps, "[TPS \"");
+ out_tps += 6;
+
+ for (int8_t row = board_size - 1; row >= 0; row--) {
+ for (int8_t col = 0; col < board_size; col++) {
+ const int8_t l = THE_COORDS(col, row);
+ const uint8_t count = COUNT_AT(l);
+ if (count) {
+ colour_stack_t c = colours[l], s = 1<<(count - 1);
+ for (int k=0; k<count; k++, s >>=1, out_tps++) {
+ if (c & s) *out_tps = '2';
+ else *out_tps = '1';
}
-
- *out_tps = ' '; out_tps++;
- *out_tps = '1' + (ply & 1); out_tps++;
- *out_tps = ' '; out_tps++;
-
- out_tps += sprintf(out_tps, "%d", ply/2 + 1);
-
- strcpy(out_tps, "\"]");
+ switch (STONE_AT(l)) {
+ case STONE_CAPSTONE: {
+ *out_tps = 'C'; out_tps++; break;
+ }
+ case STONE_STANDING: {
+ *out_tps = 'S'; out_tps++; break;
+ }
+ default: break;
+ }
+ } else {
+ int8_t skip = 1;
+ while (col < board_size && COUNT_AT(l+skip) == 0) {
+ skip++;
+ col++;
+ }
+ *out_tps = 'x'; out_tps++;
+ if (skip > 1) {
+ *out_tps = '0'+skip; out_tps++;
+ }
+ }
+ if (col + 1 < board_size) {
+ *out_tps = ','; out_tps++;
+ }
+ }
+ if (row > 0) {
+ *out_tps = '/'; out_tps++;
+ }
+ }
+
+ *out_tps = ' '; out_tps++;
+ *out_tps = '1' + (ply & 1); out_tps++;
+ *out_tps = ' '; out_tps++;
+
+ out_tps += sprintf(out_tps, "%d", ply/2 + 1);
+
+ strcpy(out_tps, "\"]");
}