Esempio n. 1
0
/**
 * Verifies a database file of game positions.
 */
int
main (int argc, char *argv[])
{
  GamePositionDb               *db;
  GamePositionDbSyntaxErrorLog *syntax_error_log;
  FILE                         *fp;
  GError                       *error;
  gchar                        *source;
  int                           number_of_errors;

  GOptionContext *context;
  GOptionGroup   *option_group;

  error = NULL;

  /* GLib command line options and argument parsing. */
  option_group = g_option_group_new("name", "description", "help_description", NULL, NULL);
  context = g_option_context_new ("- Verify a database of game positions");
  g_option_context_add_main_entries (context, entries, NULL);
  g_option_context_add_group (context, option_group);
  if (!g_option_context_parse (context, &argc, &argv, &error)) {
    g_print("Option parsing failed: %s\n", error->message);
    return -1;
  }

  /* Checks command line options for consistency. */
  if (input_file) {
    source = g_strdup(input_file);
  } else {
    g_print("Option -f, --file is mandatory.\n.");
    return -2;
  }

  /* Opens the source file for reading. */
  fp = fopen(source, "r");
  if (!fp) {
    g_print("Unable to open database resource for reading, file \"%s\" does not exist.\n.", source);
    return -3;
  }

  /* Loads the game position database. */
  db = gpdb_new(g_strdup(source));
  syntax_error_log = NULL;
  error = NULL;
  gpdb_load(fp, source, db, &syntax_error_log, &error);
  g_free(source);
  fclose(fp);

  /* Compute the number of errors logged. */
  number_of_errors = gpdb_syntax_error_log_length(syntax_error_log);

  /* Prints the database summary if the OPTION -p is turned on. */
  if (print_summary) {
    gchar *summary = gpdb_print_summary(db);
    g_print("%s", summary);
    g_free(summary);
    g_print("Number of errors: %d\n", number_of_errors);
  }

  /* Prints the error log if the OPTION -e is turned on. */
  if (log_errors) {
    gchar *syntax_error_log_to_string = gpdb_syntax_error_log_print(syntax_error_log);
    g_print("%s", syntax_error_log_to_string);
    g_free(syntax_error_log_to_string);
  }

  /* Prints the entry list if the OPTION -l is turned on. */
  if (log_entries) {
    gchar *gpdb_to_string = gpdb_print(db);
    g_print("%s", gpdb_to_string);
    g_free(gpdb_to_string);
  }

  /* Lookup for a given key. */
  if (lookup_entry) {
    GamePositionDbEntry *entry = gpdb_lookup(db, lookup_entry);
    if (entry) {
      gchar *tmp = gpdb_entry_print(entry);
      g_print("%s", tmp);
      g_free(tmp);
    }
  }

  /* Frees the resources. */
  g_free(error);
  gpdb_free(db, TRUE);
  if (syntax_error_log)
    gpdb_syntax_error_log_free(syntax_error_log);

  g_option_context_free(context);

  return 0;
}
Esempio n. 2
0
/**
 * @brief Main entry to the Reversi C endgame solver implementation.
 *
 * @todo Documentation has to be completly developed.
 */
int
main (int argc,
      char *argv[])
{

  int opt;
  int oindex = -1;

  mop_init(&options, argc, argv);
  while ((opt = mop_parse_long(&options, olist, &oindex)) != -1) {
    switch (opt) {
    case 'h':
      h_flag = true;
      break;
    case 'f':
      f_flag = true;
      f_arg = options.optarg;
      break;
    case 'q':
      q_flag = true;
      q_arg = options.optarg;
      break;
    case 's':
      s_flag = true;
      s_arg = options.optarg;
      break;
    case 'n':
      n_flag = true;
      n_arg = options.optarg;
      break;
    case 'r':
      r_flag = true;
      r_arg = options.optarg;
      break;
    case 'P':
      P_flag = true;
      P_arg = options.optarg;
      break;
    case 'l':
      l_flag = true;
      l_arg = options.optarg;
      break;
    case 'd':
      d_flag = true;
      d_arg = options.optarg;
      break;
    case 'R':
      R_flag = true;
      break;
    case 'F':
      F_flag = true;
      break;
    case 'N':
      N_flag = true;
      break;
    case ':':
      fprintf(stderr, "Option parsing failed: %s\n", options.errmsg);
      return -1;
    case '?':
      fprintf(stderr, "Option parsing failed: %s\n", options.errmsg);
      return -2;
    default:
      fprintf(stderr, "Unexpectd error. Aborting ...\n");
      abort();
    }
  }

  /* Prints documentation and returns, when help option is active. */
  if (h_flag) {
    fprintf(stderr, "%s", documentation);
    return 0;
  }

  /*
   * Checks command line options for consistency.
   */

  if (!f_flag) {
    fprintf(stderr, "Option -f, --file is mandatory.\n");
    return -2;
  } else {
    input_file = f_arg;
  }

  if (!s_flag) {
    fprintf(stderr, "Option -s, --solver is mandatory.\n");
    return -4;
  } else {
    solver_index = egs_select_solver(s_arg);
    if (solver_index == -1) {
      fprintf(stderr, "Option -s, --solver is out of range.\n");
      return -5;
    }
  }
  const endgame_solver_t *const solver = &solvers[solver_index];

  if (!q_flag) {
    fprintf(stderr, "Option -q, --lookup-entry is mandatory.\n");
    return -6;
  } else {
    lookup_entry = q_arg;
  }

  if (n_flag) {
    if ((strcmp("rand", solver->id) != 0) && (strcmp("rab", solver->id) != 0)) { // solver is not rab or rand ...
      fprintf(stderr, "Option -n, --repeats can be used only with solvers \"rab\" or \"rand\".\n");
      return -7;
    }
    char *endptr;
    long long int n_arg_to_int = strtoll(n_arg, &endptr, 10);
    if (endptr - n_arg != strlen(n_arg)) {
      fprintf(stderr, "Argument for option -n, --repeats: %s is invalid.\n", n_arg);
      return -8;
    }
    if (n_arg_to_int < 1) {
      fprintf(stderr, "Argument for option -n, --repeats is %lld, it must be a positive integer.\n", n_arg_to_int);
      return -9;
    }
    repeats = n_arg_to_int;
  } else {
    repeats = 1;
  }

  if (r_flag) {
    if ((strcmp("rand", solver->id) != 0) && (strcmp("rab", solver->id) != 0)) { // solver is not rab or rand ...
      fprintf(stderr, "Option -r, --prng-seed can be used only with solvers \"rab\" or \"rand\".\n");
      return EXIT_FAILURE;
    }
    char *endptr;
    long int r_arg_to_int = strtol(r_arg, &endptr, 10);
    if (endptr - r_arg != strlen(r_arg)) {
      fprintf(stderr, "Argument for option -r, --prng-seed: %s is invalid.\n", r_arg);
      return EXIT_FAILURE;
    }
    if (r_arg_to_int < 1) {
      fprintf(stderr, "Argument for option -r, --prng-seed is %ld, it must be a positive integer.\n", r_arg_to_int);
      return EXIT_FAILURE;
    }
    prng_seed = r_arg_to_int;
    prng_seed_is_set = true;
  }

  if (P_flag) {
    if (strcmp("rand", solver->id) != 0) { // solver is not rab ...
      fprintf(stderr, "Option -P, --pattern can be used only with solver \"rand\".\n");
      return EXIT_FAILURE;
    }
    board_pattern_index = egs_select_pattern(P_arg);
    if (board_pattern_index == -1) {
      fprintf(stderr, "Option -P, --pattern is out of range.\n");
      return EXIT_FAILURE;
    }
  }

  if (l_flag) {
    log_file = l_arg;
    if (gtl_touch_log_file(l_arg))
      log_file = l_arg;
    else {
      fprintf(stderr, "Unable to open log files with prefix \"%s\".\n", l_arg);
      return -10;
    }
  }

  if (d_flag) {
    if (fut_touch_file(d_arg))
      pve_dump_file = d_arg;
    else {
      fprintf(stderr, "Unable to open dump file \"%s\".\n", d_arg);
      return -11;
    }
  }

  if (R_flag) {
    if (!(strcmp("es", solver->id) == 0)) {
      fprintf(stderr, "Option -R, --pv-rec can be used only with solver \"es\".\n");
      return -12;
    }
    pv_rec = true;
  }

  if (F_flag) {
    if (!(strcmp("es", solver->id) == 0)) {
      fprintf(stderr, "Option -F, --pv-full-rec can be used only with solver \"es\".\n");
      return -13;
    }
    if (pv_rec) {
      fprintf(stderr, "Option -F, --pv-full-rec and option -R, cannot be used together.\n");
      return -14;
    }
    pv_full_rec = true;
  }

  if (N_flag) {
    if (!(strcmp("es", solver->id) == 0) || !pv_full_rec) {
      fprintf(stderr, "Option -N, --pv-no-print can be used only with solver \"es\", and when option -F, --pv-full-rec is turned on.\n");
      return -15;
    }
    pv_no_print = true;
  }

  /* Verifies that the database input file is available for reading. */
  FILE *fp = fopen(input_file, "r");
  if (!fp) {
    fprintf(stderr, "Unable to open database resource for reading, file \"%s\" does not exist.\n", input_file);
    return -16;
  }
  fclose(fp);

  /*
   * Checks on command line options ends here.
   */



  gpdb_dictionary_t *db;
  gpdb_syntax_err_log_t *syntax_error_log;

  gpdb_entry_t *entry = NULL;

  endgame_solver_env_t env =
    { .log_file = NULL,
      .pve_dump_file = NULL,
      .repeats = 0,
      .pv_recording = false,
      .pv_full_recording = false,
      .pv_no_print = false,
      .board_pattern_index = board_pattern_index,
      .prng_seed_is_set = prng_seed_is_set,
      .prng_seed = prng_seed
    };

  /* Loads the game position database. */
  db = gpdb_dictionary_new(input_file);
  syntax_error_log = gpdb_syntax_err_log_new();
  gpdb_dictionary_load(db, syntax_error_log, input_file, true, false, true);

  /* Compute the number of errors logged. */
  const int number_of_errors = gpdb_syntax_err_log_length(syntax_error_log);
  gpdb_syntax_err_log_free(syntax_error_log);
  if (number_of_errors != 0) {
    fprintf(stderr, "The database resource, file \"%s\" contains errors, debug it using the gpdb_verify utility.\n", input_file);
    return -4;
  }

  /* Lookup for a given key. */
  if (lookup_entry) {
    entry = gpdb_dictionary_find_entry(db, lookup_entry);
    if (entry) {
      gpdb_entry_print(entry, stdout, true);
    } else {
      fprintf(stderr, "Entry %s not found in file %s.\n", lookup_entry, input_file);
      return -6;
    }
  } else {
    printf("No entry provided.\n");
    return -7;
  }

  /* Initializes the board module. */
  board_module_init();

  /* Sets env structure. */
  env.log_file = log_file;
  env.pve_dump_file = pve_dump_file;
  env.repeats = repeats;
  env.pv_recording = pv_rec || pv_full_rec;
  env.pv_full_recording = pv_full_rec;
  env.pv_no_print = pv_no_print;

  /* Solves the position. */
  GamePositionX *gpx = gpdb_entry_get_gpx(entry);
  ExactSolution *solution = NULL;
  fprintf(stdout, "Solving game position %s, from source %s, using solver %s (%s) ...\n", entry->id, input_file, solver->id, solver->description);
  solution = solver->fn(gpx, &env);

  /* Prints results. */
  printf("\n");
  exact_solution_to_stream(stdout, solution);
  printf("\n");

  /* Frees the resources. */
  gpdb_dictionary_free(db);
  exact_solution_free(solution);

  return 0;
}



/**
 * @cond
 */

/*
 * Internal functions.
 */

/**
 * @brief Ruturns the index in the solvers arry of the endgame solver identified by `id`.
 *
 * @details Compares the `id` parameter with the values in the solvers static array,
 *          if the `id` parameter matches with the solver id field then the solver
 *          position is returned. If no solver matches, a `-1` value is returned.
 *
 * @param [in] id the label of the solver
 * @return        the solver index
 */
static int
egs_select_solver (const char *const id)
{
  assert(id);
  for (size_t i = 0; i < solvers_count; i++) {
    endgame_solver_t egs = solvers[i];
    if (strcmp(id, egs.id) == 0) return i;
  }
  return -1;
}
Esempio n. 3
0
/**
 * @brief Main entry to the Reversi C endgame solver implementation.
 *
 * @todo Documentation has to be completly developed.
 */
int
main (int argc, char *argv[])
{
  GamePositionDb               *db;
  GamePositionDbSyntaxErrorLog *syntax_error_log;
  FILE                         *fp;
  GError                       *error;
  gchar                        *source;
  int                           number_of_errors;

  GOptionContext *context;
  GOptionGroup   *option_group;

  GamePositionDbEntry *entry;
  int                  solver_index;

  error = NULL;
  entry = NULL;
  solver_index = -1;

  /* GLib command line options and argument parsing. */
  option_group = g_option_group_new("name", "description", "help_description", NULL, NULL);
  context = g_option_context_new("- Solve an endgame position");
  g_option_context_add_main_entries(context, entries, NULL);
  g_option_context_add_group(context, option_group);
  g_option_context_set_description(context, program_documentation_string);
  if (!g_option_context_parse (context, &argc, &argv, &error)) {
    g_print("Option parsing failed: %s\n", error->message);
    return -1;
  }

  /* Checks command line options for consistency. */
  if (input_file) {
    source = g_strdup(input_file);
  } else {
    g_print("Option -f, --file is mandatory.\n.");
    return -2;
  }
  if (solver) {
    for (int index = 0; index < solvers_count; index++) {
      if (g_strcmp0(solver, solvers[index]) == 0)
        solver_index = index;
    }
    if (solver_index == -1) {
      g_print("Option -s, --solver is out of range.\n.");
      return -8;
    }
    if (solver_index == 2) { // solver == random
      if (repeats < 1) {
        g_print("Option -n, --repeats is out of range.\n.");
        return -9;
      }
    }
  } else {
    g_print("Option -s, --solver is mandatory.\n.");
    return -5;
  }

  /* Opens the source file for reading. */
  fp = fopen(source, "r");
  if (!fp) {
    g_print("Unable to open database resource for reading, file \"%s\" does not exist.\n", source);
    return -3;
  }

  /* Loads the game position database. */
  db = gpdb_new(g_strdup(source));
  syntax_error_log = NULL;
  error = NULL;
  gpdb_load(fp, source, db, &syntax_error_log, &error);
  fclose(fp);

  /* Compute the number of errors logged. */
  number_of_errors = gpdb_syntax_error_log_length(syntax_error_log);
  if (number_of_errors != 0) {
    g_print("The database resource, file \"%s\" contains errors, debug it using the gpdb_verify utility.\n", source);
    return -4;
  }

  /* Lookup for a given key. */
  if (lookup_entry) {
    entry = gpdb_lookup(db, lookup_entry);
    if (entry) {
      gchar *tmp = gpdb_entry_print(entry);
      g_print("%s", tmp);
      g_free(tmp);
    } else {
      g_print("Entry %s not found in file %s.\n", lookup_entry, source);
      return -6;
    }
  } else {
    g_print("No entry provided.\n");
    return -7;
  }

  /* Initialize the board module. */
  board_module_init();

  /* Solving the position. */
  GamePosition *gp = entry->game_position;
  ExactSolution *solution = NULL;
  g_print("Solving game position %s, from source %s, using solver %s ...\n", entry->id, source, solvers[solver_index]);
  switch (solver_index) {
  case 0:
    solution = game_position_solve(gp, log_file);
    break;
  case 1:
    solution = game_position_ifes_solve(gp, log_file);
    break;
  case 2:
    solution = game_position_random_sampler(gp, log_file, repeats);
    break;
  case 3:
    solution = game_position_minimax_solve(gp, log_file);
    break;
  case 4:
    solution = game_position_rab_solve(gp, log_file, repeats);
    break;
  case 5:
    solution = game_position_ab_solve(gp, log_file);
    break;
  default:
    g_print("This should never happen! solver_index = %d. Aborting ...\n", solver_index);
    return -9;
  }

  /* Printing results. */
  gchar *solution_to_string = exact_solution_to_string(solution);
  printf("\n%s\n", solution_to_string);
  g_free(solution_to_string);

  /* Frees the resources. */
  g_free(error);
  gpdb_free(db, TRUE);
  if (syntax_error_log)
    gpdb_syntax_error_log_free(syntax_error_log);
  g_option_context_free(context);
  g_free(source);
  exact_solution_free(solution);

  return 0;
}
Esempio n. 4
0
/**
 * @brief Main entry to the Reversi C endgame solver implementation.
 *
 * @todo Documentation has to be completly developed.
 */
int
main (int argc, char *argv[])
{
  GamePositionDb *db;
  GamePositionDbSyntaxErrorLog *syntax_error_log;
  FILE *fp;

  GamePositionDbEntry *entry = NULL;
  int solver_index = -1;

  endgame_solver_env_t env =
    { .log_file = NULL,
      .pve_dump_file = NULL,
      .repeats = 0,
      .pv_recording = false,
      .pv_full_recording = false,
      .pv_no_print = false
    };

  /* GLib command line options and argument parsing. */
  GError *error = NULL;
  GOptionGroup *option_group = g_option_group_new("name", "description", "help_description", NULL, NULL);
  GOptionContext *context = g_option_context_new("- Solve an endgame position");
  g_option_context_add_main_entries(context, entries, NULL);
  g_option_context_add_group(context, option_group);
  g_option_context_set_description(context, program_documentation_string);
  if (!g_option_context_parse (context, &argc, &argv, &error)) {
    g_print("Option parsing failed: %s\n", error->message);
    return -1;
  }

  /* Checks command line options for consistency, and selects the solver. */
  if (!input_file) {
    g_print("Option -f, --file is mandatory.\n");
    return -2;
  }
  if (solver_id) {
    solver_index = egs_select_solver(solver_id);
    if (solver_index == -1) {
      g_print("Option -s, --solver is out of range.\n");
      return -8;
    }
    if (strcmp(solvers[solver_index].id, "rand") == 0) {
      if (repeats < 1) {
        g_print("Option -n, --repeats is out of range.\n");
        return -9;
      }
    }
  } else {
    g_print("Option -s, --solver is mandatory.\n");
    return -5;
  }
  const endgame_solver_t *const solver = &solvers[solver_index];
  if (pv_rec && !(!strcmp(solver->id, "es") || !strcmp(solver->id, "es2"))) {
    g_print("Option --pv-rec can be used only with solver \"es\" or \"es2\".\n");
    return -10;
  }
  if (pv_full_rec && !(!strcmp(solver->id, "es") || !strcmp(solver->id, "es2"))) {
    g_print("Option --pv-full-rec can be used only with solver \"es\" or \"es2\".\n");
    return -10;
  }
  if (pv_no_print && (strcmp(solver->id, "es") || !pv_full_rec)) {
    g_print("Option --pv-no-print can be used only with solver \"es\", and when option --pv-full-rec is turned on.\n");
    return -11;
  }

  /* Opens the source file for reading. */
  fp = fopen(input_file, "r");
  if (!fp) {
    g_print("Unable to open database resource for reading, file \"%s\" does not exist.\n", input_file);
    return -3;
  }

  /* Loads the game position database. */
  db = gpdb_new(g_strdup(input_file));
  syntax_error_log = NULL;
  error = NULL;
  gpdb_load(fp, input_file, db, &syntax_error_log, &error);
  fclose(fp);

  /* Compute the number of errors logged. */
  const int number_of_errors = gpdb_syntax_error_log_length(syntax_error_log);
  if (number_of_errors != 0) {
    g_print("The database resource, file \"%s\" contains errors, debug it using the gpdb_verify utility.\n", input_file);
    return -4;
  }

  /* Lookup for a given key. */
  if (lookup_entry) {
    entry = gpdb_lookup(db, lookup_entry);
    if (entry) {
      gchar *tmp = gpdb_entry_print(entry);
      g_print("%s", tmp);
      g_free(tmp);
    } else {
      g_print("Entry %s not found in file %s.\n", lookup_entry, input_file);
      return -6;
    }
  } else {
    g_print("No entry provided.\n");
    return -7;
  }

  /* Initializes the board module. */
  board_module_init();

  /* Sets env structure. */
  env.log_file = log_file;
  env.pve_dump_file = pve_dump_file;
  env.repeats = repeats;
  env.pv_recording = pv_rec || pv_full_rec;
  env.pv_full_recording = pv_full_rec;
  env.pv_no_print = pv_no_print;

  /* Solves the position. */
  //GamePosition *gp = entry->game_position;
  GamePositionX *gpx = game_position_x_gp_to_gpx(entry->game_position);
  ExactSolution *solution = NULL;
  g_print("Solving game position %s, from source %s, using solver %s (%s) ...\n", entry->id, input_file, solver->id, solver->description);
  solution = solver->fn(gpx, &env);

  /* Prints results. */
  gchar *solution_to_string = exact_solution_to_string(solution);
  printf("\n%s\n", solution_to_string);
  g_free(solution_to_string);

  /* Frees the resources. */
  g_free(error);
  gpdb_free(db, TRUE);
  if (syntax_error_log)
    gpdb_syntax_error_log_free(syntax_error_log);
  g_option_context_free(context);
  exact_solution_free(solution);
  free(gpx);

  return 0;
}



/**
 * @cond
 */

/*
 * Internal functions.
 */

/**
 * @brief Ruturns the index in the solvers arry of the endgame solver identified by `id`.
 *
 * @details Compares the `id` parameter with the values in the solvers static array,
 *          if the `id` parameter matches with the solver id field then the solver
 *          position is returned. If no solver matches, a `-1` value is returned.
 *
 * @param [in] id the label of the solver
 * @return        the solver index
 */
static int
egs_select_solver (const char *const id)
{
  g_assert(id);
  for (size_t i = 0; i < solvers_count; i++) {
    endgame_solver_t egs = solvers[i];
    if (strcmp(id, egs.id) == 0) return i;
  }
  return -1;
}