Example #1
0
static void my_iter_handler(void *const user_instance,
    const fcs_int_limit_t iter_num, const int depth, void *const ptr_state,
    const fcs_int_limit_t parent_iter_num, void *const context)
{
    const fc_solve_display_information_context_t *const display_context =
        (const fc_solve_display_information_context_t *const)context;
    my_iter_handler_base(
        iter_num, depth, user_instance, display_context, parent_iter_num);
    if (display_context->debug_iter_state_output)
    {
        char state_string[1000];
        freecell_solver_user_iter_state_stringify(user_instance, state_string,
            ptr_state FC_SOLVE__PASS_PARSABLE(TRUE),
            FALSE FC_SOLVE__PASS_T(TRUE));
        printf("%s\n---------------\n\n\n", state_string);
        /* Now pass it to a secondary user_instance prune it. */
        {
            void *const pruner = freecell_solver_user_alloc();

            freecell_solver_user_set_num_freecells(pruner, 2);
#ifdef FCS_WITH_ERROR_STRS
            char *error_string;
#endif
            freecell_solver_user_set_tests_order(
                pruner, "01ABCDE" FCS__PASS_ERR_STR(&error_string));
#ifdef FCS_WITH_ERROR_STRS
            free(error_string);
#endif
            freecell_solver_user_limit_iterations_long(pruner, 128 * 1024);

            const int ret =
                freecell_solver_user_solve_board(pruner, state_string);
            switch (ret)
            {
            case FCS_STATE_SUSPEND_PROCESS:
                printf("\n\nVerdict: INDETERMINATE\n\n");
                break;

            case FCS_STATE_WAS_SOLVED:
                printf("\n\nVerdict: SOLVED\n\nYay! We found a solution from "
                       "this one.");
                exit(0);
                break;

            case FCS_STATE_IS_NOT_SOLVEABLE:
                printf("\n\nVerdict: PRUNED\n\n");
                break;

            default:
                printf("\n\nVerdict: unknown ret code: %d\n\n", ret);
                exit(-1);
                break;
            }
            freecell_solver_user_free(pruner);
        }
    }
}
int main(int argc, char * argv[])
{
    int parser_ret;
    int arg;
    FILE * file;
    char user_state[USER_STATE_SIZE];
    int ret;

    fc_solve_display_information_context_t debug_context;

    init_debug_context(&debug_context);

    dc = &debug_context;

    void * const instance = freecell_solver_user_alloc();

    current_instance = instance;


    {
        char * error_string;
        parser_ret =
            freecell_solver_user_cmd_line_parse_args(
                instance,
                argc,
                (freecell_solver_str_t *)(void *)argv,
                1,
                (freecell_solver_str_t *)known_parameters,
                cmd_line_callback,
                &debug_context,
                &error_string,
                &arg
                );

        if (parser_ret == EXIT_AND_RETURN_0)
        {
            freecell_solver_user_free(instance);
            return 0;
        }
        else if (parser_ret == FCS_CMD_LINE_PARAM_WITH_NO_ARG)
        {
            fprintf(stderr, "The command line parameter \"%s\" requires an argument"
                    " and was not supplied with one.\n", argv[arg]);
            return (-1);
        }
        else if (parser_ret == FCS_CMD_LINE_ERROR_IN_ARG)
        {
            if (error_string != NULL)
            {
                fprintf(stderr, "%s", error_string);
                free(error_string);
            }
            freecell_solver_user_free(instance);
            return -1;
        }
    }

    if ((arg == argc) || (!strcmp(argv[arg], "-")))
    {
        file = stdin;
        if (!getenv("FREECELL_SOLVER_QUIET"))
        {
            fprintf(stderr, "%s",
                    "Reading the board from the standard input.\n"
                    "Please refer to the documentation for more usage information:\n"
                    "    http://fc-solve.shlomifish.org/docs/\n"
                    "To cancel this message set the FREECELL_SOLVER_QUIET environment variable.\n"
                   );
        }
    }
    else if (argv[arg][0] == '-')
    {
        fprintf(stderr,
                "Unknown option \"%s\". "
                "Type \"%s --help\" for usage information.\n",
                argv[arg],
                argv[0]
                );
        freecell_solver_user_free(instance);

        return -1;
    }
    else
    {
        file = fopen(argv[arg], "r");
        if (file == NULL)
        {
            fprintf(stderr,
                "Could not open file \"%s\" for input. Exiting.\n",
                argv[arg]
                );
            freecell_solver_user_free(instance);

            return -1;
        }
    }
    memset(user_state, '\0', sizeof(user_state));
    fread(user_state, sizeof(user_state[0]), USER_STATE_SIZE-1, file);
    fclose(file);

    /* Win32 Does not have those signals */
#ifndef WIN32
    signal(SIGUSR1, command_signal_handler);
    signal(SIGUSR2, select_signal_handler);
    signal(SIGABRT, abort_signal_handler);
#endif

#if 0
    {
        fcs_int_limit_t limit = 500;
        freecell_solver_user_limit_iterations_long(instance, limit);
        ret = freecell_solver_user_solve_board(instance, user_state);
        while (ret == FCS_STATE_SUSPEND_PROCESS)
        {
            limit += 500;
            freecell_solver_user_limit_iterations_long(instance, limit);
            ret = freecell_solver_user_resume_solution(instance);
        }
    }
#else
    ret = freecell_solver_user_solve_board(instance, user_state);
#endif

    if (ret == FCS_STATE_INVALID_STATE)
    {
        char * error_string;

        error_string =
            freecell_solver_user_get_invalid_state_error_string(
                instance,
                debug_context.display_10_as_t
                );
        printf("%s\n", error_string);
        free(error_string);
        error_string = NULL;
    }
    else if (ret == FCS_STATE_FLARES_PLAN_ERROR)
    {
        const char * error_string;

        error_string = freecell_solver_user_get_last_error_string(instance);

        printf("Flares Plan: %s\n", error_string);
    }
    else
    {
        FILE * output_fh;

        if (debug_context.output_filename)
        {
            output_fh = fopen(debug_context.output_filename, "wt");
            if (! output_fh)
            {
                fprintf(stderr,
                        "Could not open output file '%s' for writing!",
                        debug_context.output_filename
                       );
                return -1;
            }
        }
        else
        {
            output_fh = stdout;
        }

        fc_solve_output_result_to_file(
            output_fh, instance, ret, &debug_context
        );

        if (debug_context.output_filename)
        {
            fclose(output_fh);
            output_fh = NULL;
        }
    }

    freecell_solver_user_free(instance);

    return 0;
}
static void abort_signal_handler(int signal_num GCC_UNUSED)
{
    freecell_solver_user_limit_iterations_long(current_instance, 0);
}