X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=output.c;h=bc19a4a84894e7e0801c363d5ada0f6c734ca7f2;hb=23bf530a0df2de1a5075a33a3eb790a286c304bd;hp=2878b00a3b195165c2ef6c38f51246d5f6e4a55a;hpb=4e0c88b473dffdefb830e6806c3692aab6b4fa0c;p=pgn-extract diff --git a/output.c b/output.c index 2878b00..bc19a4a 100644 --- a/output.c +++ b/output.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "bool.h" #include "defs.h" #include "typedef.h" @@ -34,6 +35,7 @@ #include "apply.h" #include "output.h" #include "mymalloc.h" +#include "eco.h" /* Functions for outputting games in the required format. */ @@ -62,6 +64,8 @@ static char promoted_piece_letter(Piece piece); static void print_algebraic_game(Game current_game,FILE *outputfile, unsigned move_number,Boolean white_to_move, Board *final_board); +static void output_sesse_bin_game(Game current_game,FILE *outputfile, + unsigned move_number,Boolean white_to_move); static void print_epd_game(Game current_game,FILE *outputfile, unsigned move_number,Boolean white_to_move, Board *final_board); @@ -149,6 +153,7 @@ which_output_format(const char *arg) { "elalg", ELALG }, { "uci", UCI }, { "cm", CM }, + { "sessebin", SESSE_BIN }, { "", SOURCE }, /* Add others before the terminating NULL. */ { (const char *) NULL, SAN } @@ -188,6 +193,7 @@ output_file_suffix(OutputFormat format) static const char PGN_suffix[] = ".pgn"; static const char EPD_suffix[] = ".epd"; static const char CM_suffix[] = ".cm"; + static const char BIN_suffix[] = ".bin"; switch(format){ case SOURCE: @@ -200,6 +206,8 @@ output_file_suffix(OutputFormat format) return EPD_suffix; case CM: return CM_suffix; + case SESSE_BIN: + return BIN_suffix; default: return PGN_suffix; } @@ -996,6 +1004,9 @@ output_game(Game current_game,FILE *outputfile) case CM: output_cm_game(outputfile,move_number,white_to_move,current_game); break; + case SESSE_BIN: + output_sesse_bin_game(current_game,outputfile,move_number,white_to_move); + break; default: fprintf(GlobalState.logfile, "Internal error: unknown output type %d in output_game().\n", @@ -1156,6 +1167,84 @@ print_algebraic_game(Game current_game,FILE *outputfile, putc('\n',outputfile); } +static void +output_sesse_bin_game(Game current_game,FILE *outputfile, + unsigned move_number,Boolean white_to_move) +{ + const char *result = NULL; + Move *move; + + // Find the result. Skip games with no result. + for (move = current_game.moves; move != NULL; move = move->next) { + if (move->terminating_result) { + result = move->terminating_result; + } + } + if (result == NULL || strcmp(result, "*") == 0) { + return; + } + + int result_int = -1; + if (strcmp(result, "1-0") == 0) { + result_int = 0; + } else if (strcmp(result, "1/2-1/2") == 0) { + result_int = 1; + } else if (strcmp(result, "0-1") == 0) { + result_int = 2; + } else { + fprintf(stderr, "Unknown result '%s'\n", result); + return; + } + + // Find Black and White Elos. Skip games with no Elo. + const char *white_elo_tag = current_game.tags[WHITE_ELO_TAG]; + const char *black_elo_tag = current_game.tags[BLACK_ELO_TAG]; + if (white_elo_tag == NULL || black_elo_tag == NULL) { + return; + } + + int white_elo = atoi(white_elo_tag); + int black_elo = atoi(black_elo_tag); + + // Parse date and time, if it exists. Set invalid dates to year 3000. + const char *date_tag = current_game.tags[DATE_TAG]; + const char *time_tag = current_game.tags[TIME_TAG]; + struct tm tm = {0}; + time_t timestamp; + int year, month, day; + if (date_tag && sscanf(date_tag, "%u.%u.%u", &year, &month, &day) == 3) { + int hour, minute, second; + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = day; + + if (time_tag && sscanf(time_tag, "%u:%u:%u", &hour, &minute, &second) == 3) { + tm.tm_hour = hour; + tm.tm_min = minute; + tm.tm_sec = second; + } + timestamp = mktime(&tm); + } else { + timestamp = 32503680000; + } + + for (move = current_game.moves; move != NULL; move = move->next) { + unsigned int opening = move->eco ? move->eco->cumulative_hash_value : 0; // Truncate to 32 bits. + + // key + putc(move->bpfen_len + strlen((char *)move->move), outputfile); + fwrite(move->bpfen, move->bpfen_len, 1, outputfile); + fwrite(move->move, strlen((char *)move->move), 1, outputfile); + + // value + putc(result_int, outputfile); + fwrite(&white_elo, sizeof(white_elo), 1, outputfile); + fwrite(&black_elo, sizeof(black_elo), 1, outputfile); + fwrite(&opening, sizeof(opening), 1, outputfile); + fwrite(×tamp, sizeof(timestamp), 1, outputfile); + } +} + static void print_epd_move_list(Game current_game,FILE *outputfile, unsigned move_number, Boolean white_to_move,