Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
}
Exemplo 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;

  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;
}