From 84d17dd73a8ef43ef9e284c4455f79f67f7bd98d Mon Sep 17 00:00:00 2001 From: tslil Date: Fri, 8 Jan 2021 17:37:13 -0500 Subject: Fixed a small bug in PTN parsing, other stuff --- extract.sh | 61 ++++++++++++++++++++++++++-------------------------- include/tak.c | 15 ++++++++----- src/ctaklm.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/pptdb.c | 65 ++++++++++++++++++++++++++++++++----------------------- 4 files changed, 144 insertions(+), 66 deletions(-) diff --git a/extract.sh b/extract.sh index a48e5ab..77c0ddc 100755 --- a/extract.sh +++ b/extract.sh @@ -3,48 +3,47 @@ db_file=games_anon.db query() { - echo "SELECT $1 FROM games WHERE (size == $2) \ -and ((result == 'R-0') or (result == '0-R'));" -# and (result != '1-0') and (result != '0-1') and (result != '0-0')\ -# and (result != '1/2-1/2');" + query="(size == $1) and (result != '1-0') and (result != '0-1') and (result != '0-0')" + selct="" + # for player in rabbitboy84 fwwwwibib archvenison Simmon AaaarghBot; do + for player in; do + selct="$selct(player_black == '$player') or (player_white == '$player') or " + done; + if [ -n "$selct" ]; then + query="$query and (${selct:0:-4})" + fi + echo "SELECT $2 FROM games WHERE $query;" } extract() { + size="$1" + things="$2" if [ ! -f "data/$db_file" ]; then wget "https://www.playtak.com/games_anon.db" -O "data/$db_file" fi - for size in 5; do - echo Extracing games of size "$size"... - sqlite3 "data/$db_file" "$(query $1 $size)" | shuf > "data/playtak-$size" - done + echo Extracing games of size "$size"... + sqlite3 "data/$db_file" "$(query $size $things)" | shuf > "data/playtak-$size" } process() { - num_games=$1 - echo -e "Beginning to process data\n" - for i in 5; do - echo "Size $i..." - ./pptdb "$i" "data/playtak-$i" > "data/check-$i" - tail -n21 "data/check-$i" - echo -e "\tStripping overflows and illegal games..." - grep -Fvxf "data/check-$i" "data/playtak-$i" > "data/good-playtak-$i" - echo -e "\tChoosing $num_games from what remains ..." - shuf -n $num_games "data/good-playtak-$i" > "data/smalltak-$i" - echo -en "\tGenerating training data... " - ./pptdb "$i" "data/smalltak-$i" generate - echo -e "\tWrote $(wc -l data/training-$i.csv | cut -d\ -f1) samples. Shuffling these..." - tail -n+2 "data/training-$i.csv" | shuf > "data/shuf-$i.csv" - head -n 1 "data/training-$i.csv" | cat "data/shuf-$i.csv" > "data/smalltrain-$i.csv" - rm "data/shuf-$i.csv" - mv "data/smalltrain-5.csv" "data/training-5.csv " - echo -e "\n\tDone! Sample training data in data/training-$i.csv" - done + size=$1 + num_games=$2 + ./pptdb "$size" "data/playtak-$size" > "data/check-$size" + tail -n22 "data/check-$size" + echo -e "\tStripping overflows and illegal games..." + grep -Fvxf "data/check-$size" "data/playtak-$size" > "data/good-playtak-$size" + echo -e "\tChoosing $num_games from what remains ..." + shuf -n $num_games "data/good-playtak-$size" > "data/smalltak-$size" + echo -en "\tGenerating training data... " + ./pptdb "$size" "data/smalltak-$size" generate + echo -e "\n\tDone! Wrote $(wc -l data/training-$size.csv | cut -d\ -f1) samples to data/training-$size.csv." } -if [ ! -f "data/playtak-5" ]; then - extract notation,result -fi make pptdb -process 20000 +for size in 5 6; do + extract $size notation,result + process $size 20000 + echo +done diff --git a/include/tak.c b/include/tak.c index 1d29694..bb06a16 100644 --- a/include/tak.c +++ b/include/tak.c @@ -319,10 +319,11 @@ check_win(void) { } else { return WIN_ROAD_BLACK; } - } else { + } else if (rw == WIN_ROAD_WHITE) { return rw; } + // Do we do a flat count? int8_t total = 0, board_full = 1; for (uint8_t k = 0; k < NUM_SQUARES; k++) { if (COUNT_AT(k) == 0) { @@ -331,14 +332,14 @@ check_win(void) { total += ((colours[k] & 1) == C_BLACK) ? +1 : -1 ; } } - - // Do we do a flat count? if (black_count == 0 || white_count == 0 || board_full) { // Decide based on count if (total > 0) return WIN_FLAT_BLACK; else if (total < 0) return WIN_FLAT_WHITE; else return WIN_DRAW; } + + return 0xFF; } // =================================================================== // PTN place parser @@ -424,7 +425,7 @@ parse_move(const uint8_t board_size, char *ptn, // assume n = 1 ptn++; if (*ptn == 0) { - *out_steps = picked_up; + *out_steps = 1; out_drops[0] = picked_up; return PTN_VALID; } @@ -556,7 +557,11 @@ do_ptn(char *ptn) { // more conservative here :) if (ply >= board_size) { won = check_win(); - if (won < 0xFF) return GAME_END; + if (won < 0xFF) { + // Winning move, but no need to update current colour + ply++; + return GAME_END; + } } // Only step if the game isn't over yet next_ply(); diff --git a/src/ctaklm.c b/src/ctaklm.c index 9d369f8..3d4310c 100644 --- a/src/ctaklm.c +++ b/src/ctaklm.c @@ -190,16 +190,17 @@ end_game(char *line, char *win) { putchar('\n'); } -static void +static int handle_turn(char *line) { // Track win state uint8_t new_win = (won == 0xFF); switch (do_ptn(line)) { // Errors - case PTN_INVALID: { puts("Invalid PTN."); break; } - case ACT_ILLEGAL: { puts("Illegal action."); break; } + case PTN_INVALID: { puts("Invalid PTN."); return -1; break; } + case ACT_ILLEGAL: { puts("Illegal action."); return -1; break; } case ACT_OVERFLOW: { puts("Move would cause internal overflow, select another."); + return -1; break; } // Game has ended @@ -216,6 +217,7 @@ handle_turn(char *line) { } } puts("Game over, enter `new' to play again."); + if (! new_win) return -1; break; } // Valid, append to game log @@ -227,6 +229,8 @@ handle_turn(char *line) { break; } } + + return 0; } static void @@ -238,6 +242,59 @@ new_game(uint8_t size) { gamelog[0] = 0; } +static int +load_ptn(const char* fn) { + FILE *fh = NULL; + + fh = fopen(fn, "r"); + if (fh == NULL) return EXIT_FAILURE; + + int space1, space2; + enum E_RESULT r; + + ssize_t read; + size_t alloc_size; + char *line = NULL; + while ((read = getline(&line, &alloc_size, fh)) != -1) { + if (read && line[0] <= '9' && line[0] >= '0') { + // Trim trailing \n + line[read-1] = 0; + // Find first separator + space1 = 0; + while (space1 < read && line[space1++] != ' '); + // If still on line + if (space1 < read) { + // Find next separator or end of line, either way mark the split + space2 = space1; + while (space2 < read && line[space2] != ' ') space2++; + line[space2] = 0; + // Try the first piece we found + r = handle_turn(line+space1); + if (r) { + printf("Error on: %s\n", line+space1); + break; + } + // If there's a second piece, try it + if (space2 + 1 < read) { + r = handle_turn(line+space2+1); + if (r) { + printf("Error on: %s", line+space2+1); + break; + } + } else { + break; + } + } + } + } + + if (line) free(line); + fclose(fh); + + + return EXIT_SUCCESS; +} + int main(int argc, char **argv) { (void)(argc); @@ -255,6 +312,12 @@ main(int argc, char **argv) { print_info(); } else if (!strncmp(line,"log",3)) { puts(gamelog); + } else if (!strncmp(line,"load",4)) { + if (strnlen(line,6) >= 6) { + load_ptn(line+5); + } else { + puts("Usage: load ."); + } } else if (!strncmp(line,"auto",4)) { if (!strncmp(line,"auto board",10)) { auto_board = ~auto_board; diff --git a/src/pptdb.c b/src/pptdb.c index 92155b5..7179ab0 100644 --- a/src/pptdb.c +++ b/src/pptdb.c @@ -17,11 +17,11 @@ write_input(void) { /* fprintf(training_fh,"%d,",current_colour == C_BLACK); */ // Two numbers for flats remaining - /* fprintf(training_fh,"%.6f,%.6f,", */ - /* (float)(white_count & 127)/max_flats, */ - /* (float)(black_count & 127)/max_flats); */ - // Two data points for each square - /* float t; uint16_t mask; */ + /* + * fprintf(training_fh,"%.6f,%.6f,", + * (float)(white_count & 127)/max_flats, + * (float)(black_count & 127)/max_flats); + */ float val; uint16_t mask = 1; @@ -48,21 +48,22 @@ write_input(void) { mask <<= 1; } + /* - float t; - for (int k = 0; k < board_size * board_size; k++) { - // stacks encoded as balanced ternary - const int h = COUNT_AT(k); - t = 0; - mask = 1<>=1; - } - fprintf(training_fh,"%.8f,",2*t); - } - */ + * float t; + * for (int k = 0; k < board_size * board_size; k++) { + * // stacks encoded as balanced ternary + * const int h = COUNT_AT(k); + * t = 0; + * mask = 1<>=1; + * } + * fprintf(training_fh,"%.8f,",2*t); + * } + */ } @@ -141,7 +142,8 @@ main(int argc, char **argv) { 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; + uint32_t road_wins=0, flat_wins=0, road_turns=0, flat_turns=0, + white_wins = 0, black_wins = 0; for (int k = 0; k < 16; k++) heights[k] = 0; @@ -171,10 +173,10 @@ main(int argc, char **argv) { } /* - for (int k = 0; k < size*size; k++) { - fprintf(training_fh,"\"BT %d\",",k); - } - */ + * for (int k = 0; k < size*size; k++) { + * fprintf(training_fh,"\"BT %d\",",k); + * } + */ fputs("\"White win\",\"Black win\"\n",training_fh); } else generate=0; @@ -206,6 +208,10 @@ main(int argc, char **argv) { road_wins++; road_turns += ply/2+1; } + if (win == WIN_FLAT_BLACK || win == WIN_ROAD_BLACK) + black_wins++; + else if (win == WIN_FLAT_WHITE || win == WIN_ROAD_WHITE) + white_wins++; } } games++; @@ -219,9 +225,14 @@ main(int argc, char **argv) { printf("Read %d games\n",games); if (generate==0) { - 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, + printf("Illegals: %d\nOverflows: %d\n\ +Black wins: %.3f%%\n\ +Road wins: %d\nFlat wins: %d\n\ +Average turns to road win: %.3f\n\ +Average turns to flat win: %f\n", + illegal, overflow, + (double)black_wins / (double)(black_wins+white_wins) * 100, + road_wins, flat_wins, (double)(road_turns)/(double)(road_wins), (double)(flat_turns)/(double)(flat_wins)); for (int k = 2; k < 16; k++) { -- cgit v1.2.3