#include <string.h>
#include <stdlib.h>
#include <ctype.h>
+#include <time.h>
#include "bool.h"
#include "defs.h"
#include "typedef.h"
#include "apply.h"
#include "output.h"
#include "mymalloc.h"
+#include "eco.h"
/* Functions for outputting games in the required format. */
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);
{ "elalg", ELALG },
{ "uci", UCI },
{ "cm", CM },
+ { "sessebin", SESSE_BIN },
{ "", SOURCE },
/* Add others before the terminating NULL. */
{ (const char *) NULL, SAN }
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:
return EPD_suffix;
case CM:
return CM_suffix;
+ case SESSE_BIN:
+ return BIN_suffix;
default:
return PGN_suffix;
}
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",
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);
+ long start_position = current_game.start_position;
+
+ // 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, outputfile);
+ fwrite(move->bpfen, move->bpfen_len, 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);
+ fwrite(&start_position, sizeof(start_position), 1, outputfile);
+ putc(strlen((char *)move->move), outputfile);
+ fwrite(move->move, strlen((char *)move->move), 1, outputfile);
+ }
+}
+
static void
print_epd_move_list(Game current_game,FILE *outputfile,
unsigned move_number, Boolean white_to_move,