static void
game_position_solve_test (GamePositionDbFixture *fixture,
                          gconstpointer          test_data)
{
  GamePositionDb *db = fixture->db;

  /*
   * FFO position #05:
   *
   * a b c d e f g h 
   * 1  . O O O O O . . 
   * 2  . . O @ @ O . @ 
   * 3  @ @ O @ O @ @ . 
   * 4  @ @ O @ O @ @ O 
   * 5  @ @ O O @ O O O 
   * 6  @ @ @ @ O O . O 
   * 7  @ . @ O O O . . 
   * 8  . @ @ @ @ @ . . 
   * Player to move: BLACK
   *
   * Move values: G8:+32. G2:+12. B2:-20. G6:-26. G1:-32. G7:-34.
   *
   * Principal Variation, PV: g8 g7 h8 g2 b2 a2 a1 g6 h7 b7 a8 -- h3
   * Final score is +32
   */
  GamePosition *ffo_05 = get_gp_from_db(db, "ffo-05");
  g_assert(TRUE  == game_position_has_any_legal_move(ffo_05));

  ExactSolution *solution = game_position_solve(ffo_05);
  g_assert(+32 == solution->outcome);
  g_assert(G8 == solution->principal_variation[0]);
}
Exemple #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[])
{
  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;
}