X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=output.c;h=a403488375b878a2035259267c2df9dd1dbfd41e;hb=HEAD;hp=bc19a4a84894e7e0801c363d5ada0f6c734ca7f2;hpb=23bf530a0df2de1a5075a33a3eb790a286c304bd;p=pgn-extract diff --git a/output.c b/output.c index bc19a4a..a403488 100644 --- a/output.c +++ b/output.c @@ -36,6 +36,7 @@ #include "output.h" #include "mymalloc.h" #include "eco.h" +#include "farmhash-c.h" /* Functions for outputting games in the required format. */ @@ -65,7 +66,8 @@ 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); + unsigned move_number,Boolean white_to_move, + Board *final_board); static void print_epd_game(Game current_game,FILE *outputfile, unsigned move_number,Boolean white_to_move, Board *final_board); @@ -1005,7 +1007,8 @@ output_game(Game current_game,FILE *outputfile) 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); + output_sesse_bin_game(current_game,outputfile,move_number,white_to_move, + final_board); break; default: fprintf(GlobalState.logfile, @@ -1169,13 +1172,18 @@ print_algebraic_game(Game current_game,FILE *outputfile, static void output_sesse_bin_game(Game current_game,FILE *outputfile, - unsigned move_number,Boolean white_to_move) + unsigned move_number,Boolean white_to_move, + Board* final_board) { 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->class == NULL_MOVE) { + // Skip games with null moves. + return; + } if (move->terminating_result) { result = move->terminating_result; } @@ -1196,15 +1204,19 @@ output_sesse_bin_game(Game current_game,FILE *outputfile, return; } - // Find Black and White Elos. Skip games with no Elo. + // Find Black and White Elos. 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 = 0, black_elo = 0; + if (white_elo_tag) { + white_elo = atoi(white_elo_tag); } - - int white_elo = atoi(white_elo_tag); - int black_elo = atoi(black_elo_tag); + if (black_elo_tag) { + black_elo = atoi(black_elo_tag); + } + int file_num = current_game.file_number; + long start_position = current_game.start_position; + int computer_flag = GlobalState.computer_flag; // Parse date and time, if it exists. Set invalid dates to year 3000. const char *date_tag = current_game.tags[DATE_TAG]; @@ -1228,13 +1240,16 @@ output_sesse_bin_game(Game current_game,FILE *outputfile, timestamp = 32503680000; } + uint16_t prev_board_hash = 0; + unsigned int opening; + 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. + opening = move->eco ? move->eco->cumulative_hash_value : 0; // Truncate to 32 bits. // key - putc(move->bpfen_len + strlen((char *)move->move), outputfile); + putc(move->bpfen_len + sizeof(prev_board_hash), outputfile); fwrite(move->bpfen, move->bpfen_len, 1, outputfile); - fwrite(move->move, strlen((char *)move->move), 1, outputfile); + fwrite(&prev_board_hash, sizeof(prev_board_hash), 1, outputfile); // value putc(result_int, outputfile); @@ -1242,7 +1257,37 @@ output_sesse_bin_game(Game current_game,FILE *outputfile, fwrite(&black_elo, sizeof(black_elo), 1, outputfile); fwrite(&opening, sizeof(opening), 1, outputfile); fwrite(×tamp, sizeof(timestamp), 1, outputfile); + fwrite(&file_num, sizeof(file_num), 1, outputfile); + fwrite(&start_position, sizeof(start_position), 1, outputfile); + putc(computer_flag, outputfile); + putc(strlen((char *)move->move), outputfile); + fwrite(move->move, strlen((char *)move->move), 1, outputfile); + + prev_board_hash = farmhash_32(move->bpfen, move->bpfen_len); } + + // Final position. + char *bpfen; + int bpfen_len; + build_BPFEN_string(final_board, &bpfen, &bpfen_len); + + // key + putc(bpfen_len + sizeof(prev_board_hash), outputfile); + fwrite(bpfen, bpfen_len, 1, outputfile); + fwrite(&prev_board_hash, sizeof(prev_board_hash), 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); // Not perfect, but should be OK. + fwrite(×tamp, sizeof(timestamp), 1, outputfile); + fwrite(&file_num, sizeof(file_num), 1, outputfile); + fwrite(&start_position, sizeof(start_position), 1, outputfile); + putc(computer_flag, outputfile); + putc(0, outputfile); // No move. + + free(bpfen); } static void