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);
        }
    }
}
Example #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;
}
Example #3
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[])
{
    pack_item_t user;
    /* char buffer[2048]; */
    int ret;
    int board_num;
    int start_board, end_board, stop_at;
    result_t * results;
    FILE * output_fh;
    int min_depth_for_scan2;
    int iters_limit = 100000;
    int max_var_depth_to_check = 100;

#ifndef WIN32
    struct timeval tv;
    struct timezone tz;
#else
    struct _timeb tb;
#endif
    int total_num_iters = 0;
    char * error_string;
    char * scan1_to = NULL, * scan2_to = NULL;

    char * output_filename = NULL;
    fcs_state_string_t state_string;

    int arg = 1, start_from_arg = -1, end_args = -1;

    if (argc < 4)
    {
        fprintf(stderr, "Not Enough Arguments!\n");
        print_help();
        exit(-1);
    }
    start_board = atoi(argv[arg++]);
    end_board = atoi(argv[arg++]);
    stop_at = atoi(argv[arg++]);

    for (;arg < argc; arg++)
    {
        if (!strcmp(argv[arg], "--args-start"))
        {
            arg++;

            start_from_arg = arg;
            while (arg < argc)
            {
                if (!strcmp(argv[arg], "--args-end"))
                {
                    break;
                }
                arg++;
            }
            end_args = arg;
        }
        else if (!strcmp(argv[arg], "--output-to"))
        {
            arg++;
            if (arg == argc)
            {
                fprintf(stderr, "--output-to came without an argument!\n");
                print_help();
                exit(-1);
            }
            output_filename = argv[arg];
        }
        else if (!strcmp(argv[arg], "--scan1-to"))
        {
            arg++;
            if (arg == argc)
            {
                fprintf(stderr, "--scan1-to came without an argument!\n");
                print_help();
                exit(-1);
            }
            scan1_to = argv[arg];
        }
        else if (!strcmp(argv[arg], "--scan2-to"))
        {
            arg++;
            if (arg == argc)
            {
                fprintf(stderr, "--scan1-to came without an argument!\n");
                print_help();
                exit(-1);
            }
            scan2_to = argv[arg];
        }
        else if (!strcmp(argv[arg], "--iters-limit"))
        {
            arg++;
            if (arg == argc)
            {
                fprintf(stderr, "--iters-limit came without an argument!\n");
                print_help();
                exit(-1);
            }
            iters_limit = atoi(argv[arg]);
        }
        else if (!strcmp(argv[arg], "--max-var-depth"))
        {
            arg++;
            if (arg == argc)
            {
                fprintf(stderr, "--max-var-depth came without an argument!\n");
                print_help();
                exit(-1);
            }
            max_var_depth_to_check = atoi(argv[arg]);
        }
        else
        {
            fprintf(stderr, "Unknown argument - '%s'!\n", argv[arg]);
            exit(-1);
        }
    }

    if (!scan1_to)
    {
        fprintf(stderr, "--scan1-to not specified!\n");
        exit(-1);
    }
    
    if (!scan2_to)
    {
        fprintf(stderr, "--scan2-to not specified!\n");
        exit(-1);
    }

    if (!output_filename)
    {
        fprintf(stderr, "output filename not specified");
        exit(-1);
    }

    /* for(board_num=1;board_num<100000;board_num++) */
#ifndef WIN32
    gettimeofday(&tv,&tz);
    printf("Started at %li.%.6li\n",
        tv.tv_sec,
        tv.tv_usec
        );
#else
    _ftime(&tb);
    printf("Started at %li.%.6i\n",
        tb.time,
        tb.millitm*1000
        );
#endif
    fflush(stdout);

    results = malloc(sizeof(results[0]) * (end_board - start_board + 1));

    output_fh = fopen(output_filename, "wt");

    for (min_depth_for_scan2 = 0; min_depth_for_scan2 < max_var_depth_to_check ; 
            min_depth_for_scan2++)
    {
        user.instance = freecell_solver_user_alloc();

        if (start_from_arg >= 0)
        {
            freecell_solver_user_cmd_line_parse_args(
                user.instance,
                end_args,
                (freecell_solver_str_t *)argv,
                start_from_arg,
                known_parameters,
                NULL,
                &user,
                &error_string,
                &arg
            );
        }
        
        if (freecell_solver_user_set_depth_tests_order(
            user.instance,
            0,
            scan1_to,
            &error_string
            ))
        {
            fprintf(stderr, "Error! Got '%s'!\n", error_string);
            free(error_string);
            exit(-1);
        }
        if (freecell_solver_user_set_depth_tests_order(
            user.instance,
            min_depth_for_scan2,
            scan2_to,
            &error_string
            ))
        {
            fprintf(stderr, "Error! Got '%s'!\n", error_string);
            free(error_string);
            exit(-1);
        }


        ret = 0;

        total_num_iters = 0;

        for(board_num=start_board;board_num<=end_board;board_num++)
        {
            get_board(board_num, state_string);

            freecell_solver_user_limit_iterations(
                user.instance,
                iters_limit
            );

#ifndef WIN32
                gettimeofday(
                    &(results[board_num - start_board].start_tv), 
                    &tz
                );
#else
                _ftime(&(results[board_num - start_board].start_tb));
#endif
            
            results[board_num-start_board].verdict = ret =
                freecell_solver_user_solve_board(
                    user.instance,
                    state_string
                    );

#ifndef WIN32
                gettimeofday(
                    &(results[board_num - start_board].end_tv), 
                    &tz
                );
#else
                _ftime(&(results[board_num - start_board].end_tb));
#endif

            total_num_iters += 
                (results[board_num - start_board].num_iters
                    = freecell_solver_user_get_num_times(user.instance)
                );

            freecell_solver_user_recycle(user.instance);
        }

        freecell_solver_user_free(user.instance);

        printf("Reached depth %d\n", min_depth_for_scan2);
        
        fprintf(output_fh, "Depth == %d\n\n", min_depth_for_scan2);
        for(board_num=start_board;board_num<=end_board;board_num++)
        {
            fprintf(output_fh, "board[%d].ret == %d\n", board_num, results[board_num-start_board].verdict);
            fprintf(output_fh, "board[%d].iters == %d\n", board_num, results[board_num-start_board].num_iters);
            fprintf(output_fh, "board[%d].start = %li.%.6li\n", board_num, results[board_num-start_board].start_tv.tv_sec, results[board_num-start_board].start_tv.tv_usec);
            fprintf(output_fh, "board[%d].end = %li.%.6li\n", board_num, results[board_num-start_board].end_tv.tv_sec, results[board_num-start_board].end_tv.tv_usec);
        }
        fflush(output_fh);
    }

    fclose(output_fh);

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