示例#1
0
int freecell_solver_user_solve_board(
    void * user_instance,
    const char * state_as_string
    )
{
    fcs_user_t * user;

    user = (fcs_user_t*)user_instance;

    user->state_string_copy = strdup(state_as_string);

    user->current_instance_idx = 0;

    return freecell_solver_user_resume_solution(user_instance);
}
示例#2
0
int main(int argc, char * argv[])
{
    int parser_ret;
    void * instance;
    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;

    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 *)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"
                    "Type \"fc-solve --help\" for more usage information.\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);
#endif

#if 0
    {
        int limit = 500;
        freecell_solver_user_limit_iterations(instance, limit);
        ret = freecell_solver_user_solve_board(instance, user_state);
        while (ret == FCS_STATE_SUSPEND_PROCESS)
        {
            limit += 500;
            freecell_solver_user_limit_iterations(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;
        }

        if (ret == FCS_STATE_WAS_SOLVED)
        {
            fprintf(output_fh, "-=-=-=-=-=-=-=-=-=-=-=-\n\n");
            {
                fcs_move_t move;
                FILE * move_dump;
                char * as_string;
                int move_num = 0;

                move_dump = output_fh;

                if (debug_context.display_states)
                {
                    as_string =
                        freecell_solver_user_current_state_as_string(
                            instance,
                            debug_context.parseable_output,
                            debug_context.canonized_order_output,
                            debug_context.display_10_as_t
                            );

                    fprintf(move_dump, "%s\n", as_string);

                    free(as_string);

                    fprintf(move_dump, "%s", "\n====================\n\n");
                }

                while (
                        freecell_solver_user_get_next_move(
                            instance,
                            &move
                            ) == 0
                        )
                {
                    if (debug_context.display_moves)
                    {
                        as_string =
                            freecell_solver_user_move_to_string_w_state(
                                instance,
                                move,
                                debug_context.standard_notation
                                );

                        if (debug_context.display_states && debug_context.standard_notation)
                        {
                            fprintf(move_dump, "Move: ");
                        }

                        fprintf(
                            move_dump,
                            (debug_context.standard_notation ?
                                "%s " :
                                "%s\n"
                            ),
                            as_string
                            );
                        move_num++;
                        if (debug_context.standard_notation)
                        {
                            if ((move_num % 10 == 0) || debug_context.display_states)
                            {
                                fprintf(move_dump, "\n");
                            }
                        }
                        if (debug_context.display_states)
                        {
                            fprintf(move_dump, "\n");
                        }
                        fflush(move_dump);
                        free(as_string);
                    }

                    if (debug_context.display_states)
                    {
                        as_string =
                            freecell_solver_user_current_state_as_string(
                                instance,
                                debug_context.parseable_output,
                                debug_context.canonized_order_output,
                                debug_context.display_10_as_t
                                );

                        fprintf(move_dump, "%s\n", as_string);

                        free(as_string);
                    }

                    if (debug_context.display_states || (!debug_context.standard_notation))
                    {
                        fprintf(move_dump, "%s", "\n====================\n\n");
                    }
                }

                if (debug_context.standard_notation && (!debug_context.display_states))
                {
                    fprintf(move_dump, "\n\n");
                }
            }

            fprintf(output_fh, "This game is solveable.\n");
        }
        else
        {
            fprintf (output_fh, "I could not solve this game.\n");
        }

        fprintf(
            output_fh,
            "Total number of states checked is %i.\n",
            freecell_solver_user_get_num_times(instance)
            );
#if 1
        fprintf(
            output_fh,
            "This scan generated %i states.\n",
            freecell_solver_user_get_num_states_in_collection(instance)
            );
#endif

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

    freecell_solver_user_free(instance);

    return 0;
}
int Free2Solver(Position * orig, int NoFcs, int limit, int cmd_line_argc, char * * cmd_line_argv,
    int (*signal_step)(int step_limit))
{
    char * state_string;
    void * instance;
    int verdict;
    int num_iters;
    int ret;
    int current_limit = 1000;
    char * err_str;
    int ret_arg, parser_ret;
    char * moves_string;


    state_string = fc_solve_fc_pro_position_to_string(orig, NoFcs);

    instance = freecell_solver_user_alloc();

    NumFCs = NoFcs ;

    parser_ret = freecell_solver_user_cmd_line_parse_args(
            instance,
            cmd_line_argc,
            cmd_line_argv,
            0,
            cmd_line_known_parameters,
            NULL,
            NULL,
            &err_str,
            &ret_arg
            );

    if (parser_ret == FCS_CMD_LINE_UNRECOGNIZED_OPTION)
    {
        freecell_solver_user_free(instance);        
        return 0;
    }
    
            
    freecell_solver_user_set_game(
        instance,

        NoFcs,
        8,
        1,
        FCS_SEQ_BUILT_BY_ALTERNATE_COLOR,
        0,
        FCS_ES_FILLED_BY_ANY_CARD
        );

    freecell_solver_user_limit_iterations(instance, current_limit);

    verdict = freecell_solver_user_solve_board(instance, state_string);

    free(state_string);

    while ((verdict == FCS_STATE_SUSPEND_PROCESS) && 
           (
                (limit > 0) ? 
                    (current_limit < limit) :
                    1
           )
          )
    {
        if (signal_step(current_limit) != 0)
        {
            break;
        }
        current_limit += 1000;
        freecell_solver_user_limit_iterations(instance, current_limit);
        verdict = freecell_solver_user_resume_solution(instance);
    }

    num_iters = freecell_solver_user_get_num_times(instance);

    if (verdict == FCS_STATE_WAS_SOLVED)
    {
        int num_moves;
        int a;
        fcs_extended_move_t move;
        char * str, * moves_string_proto;
        int len;
        moves_processed_t * moves_processed;

        ret = num_iters;
        
        moves_processed = moves_processed_gen(orig, NoFcs, instance);
        num_moves = moves_processed_get_moves_left(moves_processed);
        moves_string_proto = (char *)malloc(moves_processed->num_moves*4+1);
        
        /* a = num_moves-1; */
        str = moves_string_proto;

        while (! moves_processed_get_next_move(moves_processed, &move))
        {
            str = moves_processed_render_move(move, str);
        }
        moves_processed_free(moves_processed);
        len = str-moves_string_proto;
        moves_string = malloc(len+1);
        for(a=0;a<len;a++)
        {
            moves_string[a] = moves_string_proto[len-1-a];
        }
        moves_string[a] = '\0';
        free(moves_string_proto);
        
    }
    else if (verdict == FCS_STATE_IS_NOT_SOLVEABLE)
    {
        if (num_iters == 0)
            num_iters++ ;
        ret = -num_iters;
    }
    else if ((verdict == FCS_STATE_SUSPEND_PROCESS) || (verdict == FCS_STATE_BEGIN_SUSPEND_PROCESS))
    {
        ret = 0;
    }
    
    freecell_solver_user_free(instance);

    return ret;
}
示例#4
0
int main(int argc, char * argv[])
{
    int parser_ret;
    void * instance;
    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;

    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 *)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"
                    "Type \"fc-solve --help\" for more usage information.\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);
#endif

#if 0
    {
        int limit = 500;
        freecell_solver_user_limit_iterations(instance, limit);
        ret = freecell_solver_user_solve_board(instance, user_state);
        while (ret == FCS_STATE_SUSPEND_PROCESS)
        {
            limit += 500;
            freecell_solver_user_limit_iterations(instance, limit);
            ret = freecell_solver_user_resume_solution(instance);
        }
    }
#elif defined(FCS_TRACE_MEM)
    {
#define STEP 100000
        int limit = STEP;
        char stat_fn[1024], foo_str[1024];
        fcs_portable_time_t mytime;
        FILE * stat;
        long long int rss;
        unsigned long long unsigned_foo;

        snprintf(stat_fn, sizeof(stat_fn), "/proc/%ld/stat", (long)(getpid()));

        freecell_solver_user_limit_iterations(instance, limit);
        ret = freecell_solver_user_solve_board(instance, user_state);
        while (ret == FCS_STATE_SUSPEND_PROCESS)
        {
            FCS_GET_TIME(mytime);
            
            /* This was taken from:
             *
             * http://www.brokestream.com/procstat.html
             * */
            stat = fopen(stat_fn, "r");
#define readone(foo) (fscanf(stat, "%lld ", &rss))
#define readstr(foo) (fscanf(stat, "%1000s ", foo_str))
#define readchar(foo) (fscanf(stat, "%c ", foo_str))
#define readunsigned(foo) (fscanf(stat, "%llu ", &unsigned_foo))
            readone(&pid);
            readstr(tcomm);
            readchar(&state);
            readone(&ppid);
            readone(&pgid);
            readone(&sid);
            readone(&tty_nr);
            readone(&tty_pgrp);
            readone(&flags);
            readone(&min_flt);
            readone(&cmin_flt);
            readone(&maj_flt);
            readone(&cmaj_flt);
            readone(&utime);
            readone(&stimev);
            readone(&cutime);
            readone(&cstime);
            readone(&priority);
            readone(&nicev);
            readone(&num_threads);
            readone(&it_real_value);
            readunsigned(&start_time);
            readone(&vsize);
            readone(&rss);
#undef readone
#undef readunsigned
#undef readchar
#undef readstr

            fclose(stat);

            printf("Reached:\t%d\t%li.%.6li\t%lld\n",
                    limit,
                    FCS_TIME_GET_SEC(mytime),
                    FCS_TIME_GET_USEC(mytime),
                    rss
                  );

            fflush(stdout);
            limit += STEP;
            freecell_solver_user_limit_iterations(instance, limit);
            ret = freecell_solver_user_resume_solution(instance);
        }
    }
#undef STEP
#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;
        }

        if (ret == FCS_STATE_WAS_SOLVED)
        {
            fprintf(output_fh, "-=-=-=-=-=-=-=-=-=-=-=-\n\n");
            {
                fcs_move_t move;
                FILE * move_dump;
                char * as_string;
                int move_num = 0;

                move_dump = output_fh;

                if (debug_context.display_states)
                {
                    as_string =
                        freecell_solver_user_current_state_as_string(
                            instance,
                            debug_context.parseable_output,
                            debug_context.canonized_order_output,
                            debug_context.display_10_as_t
                            );

                    fprintf(move_dump, "%s\n", as_string);

                    free(as_string);

                    fprintf(move_dump, "%s", "\n====================\n\n");
                }

                while (
                        freecell_solver_user_get_next_move(
                            instance,
                            &move
                            ) == 0
                        )
                {
                    if (debug_context.display_moves)
                    {
                        as_string =
                            freecell_solver_user_move_to_string_w_state(
                                instance,
                                move,
                                debug_context.standard_notation
                                );

                        if (debug_context.display_states && debug_context.standard_notation)
                        {
                            fprintf(move_dump, "Move: ");
                        }

                        fprintf(
                            move_dump,
                            (debug_context.standard_notation ?
                                "%s " :
                                "%s\n"
                            ),
                            as_string
                            );
                        move_num++;
                        if (debug_context.standard_notation)
                        {
                            if ((move_num % 10 == 0) || debug_context.display_states)
                            {
                                fprintf(move_dump, "\n");
                            }
                        }
                        if (debug_context.display_states)
                        {
                            fprintf(move_dump, "\n");
                        }
                        fflush(move_dump);
                        free(as_string);
                    }

                    if (debug_context.display_states)
                    {
                        as_string =
                            freecell_solver_user_current_state_as_string(
                                instance,
                                debug_context.parseable_output,
                                debug_context.canonized_order_output,
                                debug_context.display_10_as_t
                                );

                        fprintf(move_dump, "%s\n", as_string);

                        free(as_string);
                    }

                    if (debug_context.display_states || (!debug_context.standard_notation))
                    {
                        fprintf(move_dump, "%s", "\n====================\n\n");
                    }
                }

                if (debug_context.standard_notation && (!debug_context.display_states))
                {
                    fprintf(move_dump, "\n\n");
                }
            }

            fprintf(output_fh, "This game is solveable.\n");
        }
        else
        {
            fprintf (output_fh, "I could not solve this game.\n");
        }

        fprintf(
            output_fh,
            "Total number of states checked is %i.\n",
            freecell_solver_user_get_num_times(instance)
            );
#if 1
        fprintf(
            output_fh,
            "This scan generated %i states.\n",
            freecell_solver_user_get_num_states_in_collection(instance)
            );
#endif

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

    freecell_solver_user_free(instance);

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