summaryrefslogtreecommitdiff
path: root/src/pptdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pptdb.c')
-rw-r--r--src/pptdb.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/pptdb.c b/src/pptdb.c
new file mode 100644
index 0000000..e335d8e
--- /dev/null
+++ b/src/pptdb.c
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <tak.h>
+
+uint64_t heights[16];
+
+// Warning: performs _no_ checks on input whatsoever
+static enum E_RESULT
+parse_line(char *pt, const ssize_t read) {
+ ssize_t idx = 0;
+ enum E_RESULT r;
+ for(;;) {
+ if (pt[idx] == 'P') {
+ // P [A-F][1-6] [CF]?,
+ idx+=2;
+ enum STONE_VARIANT stone;
+ const uint8_t col = pt[idx]-'A', row = pt[idx+1]-'1';
+
+ if (idx + 3 < read) {
+ switch (pt[idx+3]) {
+ case 'W': { stone = STONE_STANDING; break; }
+ case 'C': { stone = STONE_CAPSTONE; break; }
+ default: { stone = STONE_FLAT; break; }
+ }
+ } else { stone = STONE_FLAT; }
+
+ /* char buf[100]; */
+ /* generate_place(board_size, THE_COORDS(col,row), stone, buf); */
+ /* puts(buf); */
+
+ r = try_place(THE_COORDS(col,row), current_colour, stone);
+ if (r != ACT_OK) return r;
+ } else if (pt[idx] == 'M') {
+ // M [A-F][1-6] [A-F][1-6]( [1-6])+,
+ idx+=2;
+ uint8_t drops[board_size];
+ const uint8_t s_col =pt[idx]-'A', s_row=pt[idx+1]-'1',
+ d_col=pt[idx+3]-'A', d_row=pt[idx+4]-'1';
+ idx+=4;
+
+ enum MOVE_DIRECTION dir;
+ if (s_col < d_col) dir=M_RIGHT;
+ else if (s_col > d_col) dir=M_LEFT;
+ else if (s_row < d_row) dir=M_UP;
+ else if (s_row > d_row) dir=M_DOWN;
+
+ uint8_t steps = 0;
+ do {
+ idx+=2;
+ drops[steps++] = pt[idx] - '0';
+ } while (idx+2<read && pt[idx+1] != ',');
+
+ /* char buf[100]; */
+ /* generate_move(board_size, THE_COORDS(s_col,s_row), dir, steps, drops, buf); */
+ /* puts(buf); */
+
+ r = try_move(THE_COORDS(s_col, s_row), dir, steps, drops);
+
+ if (r != ACT_OK) return r;
+
+ // Measure height of stacks exceeding 1
+ for (int k = 0; k < board_size * board_size; k++) {
+ if (COUNT_AT(k)>1) heights[COUNT_AT(k)]+=1;
+ }
+ }
+ while (idx<read && pt[idx++]!=',');
+ if (idx>=read) return ACT_OK;
+ next_ply();
+ }
+ return ACT_OK;
+}
+
+
+int
+main(int argc, char **argv) {
+ (void)(argc);
+
+ enum E_RESULT r;
+ enum WIN_TYPE win;
+ uint32_t games = 0, overflow=0, illegal = 0;
+ uint32_t road_wins=0, flat_wins=0, road_turns=0, flat_turns=0;
+
+ for (int k = 0; k < 16; k++) heights[k] = 0;
+
+ FILE *playtak;
+ ssize_t read;
+ size_t len = 0;
+ char *line = NULL;
+
+ const uint8_t size = argv[1][0]-'0';
+ playtak = fopen(argv[2], "r");
+ if (playtak == NULL) exit(EXIT_FAILURE);
+
+ while ((read = getline(&line, &len, playtak)) != -1) {
+ reset_state(size);
+ r = parse_line(line,read);
+ if (r == ACT_ILLEGAL) {
+ illegal++;
+ printf("Culprit: (%ld) %s",read,line);
+ } else if (r == ACT_OVERFLOW) {
+ overflow++;
+ } else {
+ win = check_win();
+ if (win == WIN_FLAT_BLACK || win == WIN_FLAT_WHITE || win == WIN_DRAW) {
+ flat_wins++;
+ flat_turns += ply/2+1;
+ } else if (win == WIN_DRAGON || win == WIN_ROAD_BLACK || win == WIN_ROAD_WHITE){
+ road_wins++;
+ road_turns += ply/2+1;
+ }
+ }
+ games++;
+ }
+
+ fclose(playtak);
+ if (line) free(line);
+
+ printf("Read %d games\n",games);
+ printf("Illegals: %d\nOverflows: %d\nRoad wins: %d\nFlat wins: %d\n\
+Average turns to road win: %.3f\nAverage turns to flat win: %f\n",
+ illegal,overflow, road_wins, flat_wins,
+ (double)(road_turns)/(double)(road_wins),
+ (double)(flat_turns)/(double)(flat_wins));
+ for (int k = 2; k < 16; k++) {
+ printf("Height %2d: %7ld\n",k,heights[k]);
+ }
+
+ exit(EXIT_SUCCESS);
+}