aboutsummaryrefslogtreecommitdiff
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
parentf706a6a0546400cb6a1925f25dc010ffce2afd49 (diff)
Started on PTN stuff
-rw-r--r--include/enums.h5
-rw-r--r--include/ptn.c86
-rw-r--r--include/ptn.h13
-rw-r--r--include/state.c (renamed from include/tak.c)22
-rw-r--r--include/state.h24
-rw-r--r--include/tak.h32
-rw-r--r--src/ctaklm.c6
7 files changed, 134 insertions, 54 deletions
diff --git a/include/enums.h b/include/enums.h
new file mode 100644
index 0000000..1df2a4b
--- /dev/null
+++ b/include/enums.h
@@ -0,0 +1,5 @@
+enum COLOUR { C_WHITE, C_BLACK };
+enum STONE_VARIANT { STONE_FLAT, STONE_STANDING, STONE_CAPSTONE };
+enum MOVE_DIRECTION { M_UP, M_DOWN, M_LEFT, M_RIGHT };
+enum ACTION_RESULT { A_OK, A_ILLEGAL, A_OVERFLOW };
+enum WIN_RESULT { W_NONE, W_ROAD_WHITE, W_ROAD_BLACK, W_FLAT_WHITE, W_FLAT_BLACK };
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;
+}
diff --git a/include/ptn.h b/include/ptn.h
new file mode 100644
index 0000000..715a7d0
--- /dev/null
+++ b/include/ptn.h
@@ -0,0 +1,13 @@
+#include <stdint.h>
+#include "enums.h"
+
+enum PTN_PARSE_RESULT { PTN_VALID, PTN_INVALID };
+
+enum PTN_PARSE_RESULT
+parse_place(const uint8_t board_size, char *ptn,
+ uint8_t *location, enum STONE_VARIANT *stone);
+
+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]);
diff --git a/include/tak.c b/include/state.c
index d772b5d..1505881 100644
--- a/include/tak.c
+++ b/include/state.c
@@ -1,4 +1,4 @@
-#include "tak.h"
+#include <state.h>
// -------------------------------------------------------------------
// Helpers
@@ -18,20 +18,11 @@
// -------------------------------------------------------------------
// Game management
-uint8_t init_game() {
- colours = calloc(board_size * board_size, sizeof(colour_stack_t));
- if (colours == NULL) return -1;
- celldat = calloc(board_size * board_size, sizeof(data_t));
- if (celldat == NULL) return -1;
-
- reset_game();
- return 0;
-}
-
void reset_game() {
if (board_size == 6) {
white_flats = 30; black_flats = 30;
} else {
+ board_size = 5;
white_flats = 21; black_flats = 21;
}
white_caps = 1; black_caps = 1;
@@ -43,11 +34,6 @@ void reset_game() {
}
}
-void free_game() {
- free(colours);
- free(celldat);
-}
-
// -------------------------------------------------------------------
// Place stone
@@ -109,9 +95,9 @@ drop_stones(const int8_t location, const uint8_t count) {
enum ACTION_RESULT
try_move(const int8_t location, const enum MOVE_DIRECTION direction,
- const uint8_t steps, const uint8_t * const drops) {
+ const uint8_t steps, const uint8_t drops[5]) {
// Can't do this
- if (steps == 0) return A_ILLEGAL;
+ if (steps == 0 || steps > 5) return A_ILLEGAL;
int8_t delta;
// Is the desired direction and count on the board?
diff --git a/include/state.h b/include/state.h
new file mode 100644
index 0000000..428a998
--- /dev/null
+++ b/include/state.h
@@ -0,0 +1,24 @@
+#include <stdint.h>
+#include "enums.h"
+
+static uint8_t board_size = 5;
+
+typedef uint16_t colour_stack_t;
+typedef uint8_t data_t;
+
+static colour_stack_t colours[36];
+static data_t celldat[36];
+static uint8_t white_flats, black_flats, white_caps, black_caps, turn;
+
+void reset_game(void);
+
+enum ACTION_RESULT
+try_place(const int8_t location, const enum COLOUR colour,
+ const enum STONE_VARIANT stone);
+
+enum ACTION_RESULT
+try_move(const int8_t location, const enum MOVE_DIRECTION direction,
+ const uint8_t steps, const uint8_t drops[5]);
+
+enum WIN_RESULT
+check_win(const enum COLOUR colour);
diff --git a/include/tak.h b/include/tak.h
deleted file mode 100644
index c7135ab..0000000
--- a/include/tak.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stdlib.h>
-#include <stdint.h>
-
-static uint8_t board_size = 5;
-
-typedef uint16_t colour_stack_t;
-typedef uint8_t data_t;
-
-enum COLOUR { C_WHITE, C_BLACK };
-enum STONE_VARIANT { STONE_FLAT, STONE_STANDING, STONE_CAPSTONE };
-enum MOVE_DIRECTION { M_UP, M_DOWN, M_LEFT, M_RIGHT };
-enum ACTION_RESULT { A_OK, A_ILLEGAL, A_OVERFLOW };
-enum WIN_RESULT { W_NONE, W_ROAD_WHITE, W_ROAD_BLACK, W_FLAT_WHITE, W_FLAT_BLACK };
-
-static colour_stack_t *colours = 0;
-static data_t *celldat = 0;
-static uint8_t white_flats, black_flats, white_caps, black_caps, turn;
-
-uint8_t init_game(void);
-void reset_game(void);
-void free_game(void);
-
-enum ACTION_RESULT
-try_place(const int8_t location, const enum COLOUR colour,
- const enum STONE_VARIANT stone);
-
-enum ACTION_RESULT
-try_move(const int8_t location, const enum MOVE_DIRECTION direction,
- const uint8_t steps, const uint8_t * const drops);
-
-enum WIN_RESULT
-check_win(const enum COLOUR colour);
diff --git a/src/ctaklm.c b/src/ctaklm.c
index bbf815c..3585bec 100644
--- a/src/ctaklm.c
+++ b/src/ctaklm.c
@@ -1,10 +1,10 @@
#include <stdlib.h>
#include <stdio.h>
-#include <tak.h>
+#include <state.h>
int main(int argc, char **argv) {
- init_game();
+ reset_game();
enum ACTION_RESULT res = try_place(0, 0x0001, STONE_FLAT);
res = try_place(1, 0x0001, STONE_FLAT);
@@ -13,6 +13,4 @@ int main(int argc, char **argv) {
printf("Result: %d\n",res);
printf("%o %o \n",colours[0],celldat[0]);
-
- free_game();
}