summaryrefslogtreecommitdiff
path: root/include/ptn.c
diff options
context:
space:
mode:
authortslil <tslil@posteo.de>2020-12-28 20:56:46 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commitfd22e4cf3198c1e63cf26dd5fdce588a1e969ac1 (patch)
tree363215345250b1f0aa223ce97671589fa2837a0f /include/ptn.c
parentf706a6a0546400cb6a1925f25dc010ffce2afd49 (diff)
Started on PTN stuff
Diffstat (limited to 'include/ptn.c')
-rw-r--r--include/ptn.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/include/ptn.c b/include/ptn.c
new file mode 100644
index 0000000..58648b9
--- /dev/null
+++ b/include/ptn.c
@@ -0,0 +1,86 @@
+#include "ptn.h"
+
+#define ASSERT_NONEMPTY { if (ptn == 0 || *ptn == 0) return PTN_INVALID; }
+#define ASSERT_MORE { if (*ptn == 0) return PTN_INVALID; }
+
+enum PTN_PARSE_RESULT
+parse_place(const uint8_t board_size, char *ptn,
+ uint8_t *location, enum STONE_VARIANT *stone) {
+
+ ASSERT_NONEMPTY;
+
+ *stone = STONE_FLAT;
+ switch (*ptn) {
+ case 'C' : { ptn++; *stone = STONE_CAPSTONE; break; };
+ case 'S' : { ptn++; *stone = STONE_STANDING; break; };
+ case 'F' : { ptn++; break; };
+ }
+
+ ASSERT_MORE;
+
+ if ( (*ptn < 'a') || (*ptn > '`' + board_size) ) return PTN_INVALID;
+ *location = *ptn - 'a';
+
+ ptn++; ASSERT_MORE;
+
+ if ( (*ptn < '1') || (*ptn > board_size + '0') ) return PTN_INVALID;
+ *location += board_size * (*ptn - '1');
+
+ if (*(++ptn) > 0) return PTN_INVALID;
+
+ return PTN_VALID;
+}
+
+enum PTN_PARSE_RESULT
+parse_move(const uint8_t board_size, char *ptn,
+ uint8_t *location, enum MOVE_DIRECTION *direction,
+ uint8_t *steps, uint8_t drops[5]) {
+
+ ASSERT_NONEMPTY;
+
+ uint8_t picked_up = 0;
+
+ if ( (*ptn >= '1') && (*ptn <= '0' + board_size)) {
+ picked_up = *ptn - '0';
+ ptn++; ASSERT_MORE;
+ }
+
+ if ( (*ptn < 'a') || (*ptn > '`' + board_size) ) return PTN_INVALID;
+ *location = *ptn - 'a';
+
+ ptn++; ASSERT_MORE;
+
+ if ( (*ptn < '1') || (*ptn > board_size + '0') ) return PTN_INVALID;
+ *location += board_size * (*ptn - '1');
+
+ ptn++; ASSERT_MORE;
+
+ switch (*ptn) {
+ case '+': { *direction = M_UP; break; }
+ case '-': { *direction = M_DOWN; break; }
+ case '<': { *direction = M_LEFT; break; }
+ case '>': { *direction = M_RIGHT; break; }
+ default: return PTN_INVALID;
+ }
+
+ ptn++; ASSERT_MORE;
+
+ *steps = 0;
+ uint8_t total = 0;
+ while (*ptn) {
+ if ( (*ptn < '1') || (*ptn > '0' + board_size) ) {
+ return PTN_INVALID;
+ }
+ // TODO: Correct?
+ if ( (*steps >= board_size) && *ptn) return PTN_INVALID;
+
+ drops[*steps] = *ptn - '0';
+ total += drops[*steps];
+ *steps += 1;
+ ptn++;
+ }
+
+ if ( (picked_up > 0) && (total != picked_up) ) return PTN_INVALID;
+
+ return PTN_VALID;
+}