diff options
| author | tslil clingman <tslil@posteo.de> | 2021-10-05 18:22:23 -0400 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-08-28 19:37:41 +0100 |
| commit | cf175fc346f1b208766b1f55d3673a7b208f322a (patch) | |
| tree | 3dabfd672b73e7d0756d8259e59464d1f560aee6 /include/tps.c | |
| parent | 640d404b3cf3324aca4424fc3da4806d4562d0e4 (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.c | 386 |
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, "\"]"); } |
