diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | c90c389a8a8d9d8661e9772ec4144c5cf2039f23 (patch) | |
tree | 6d8391395bce9eaea4ad78958617edb20c6a7573 /kpat/freecell-solver/main.c | |
download | tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.tar.gz tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegames@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kpat/freecell-solver/main.c')
-rw-r--r-- | kpat/freecell-solver/main.c | 859 |
1 files changed, 859 insertions, 0 deletions
diff --git a/kpat/freecell-solver/main.c b/kpat/freecell-solver/main.c new file mode 100644 index 00000000..d16468c4 --- /dev/null +++ b/kpat/freecell-solver/main.c @@ -0,0 +1,859 @@ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> + +#include "fcs_cl.h" + +struct freecell_solver_display_information_context_struct +{ + int debug_iter_state_output; + int freecells_num; + int stacks_num; + int decks_num; + int parseable_output; + int canonized_order_output; + int display_10_as_t; + int display_parent_iter_num; + int debug_iter_output_on; + int display_moves; + int display_states; + int standard_notation; +}; + +typedef struct freecell_solver_display_information_context_struct freecell_solver_display_information_context_t; + +static void init_debug_context( + freecell_solver_display_information_context_t * dc + ) +{ + dc->parseable_output = 0; + dc->canonized_order_output = 0; + dc->display_10_as_t = 0; + dc->display_parent_iter_num = 0; + dc->display_moves = 0; + dc->display_states = 1; + dc->standard_notation = 0; +} + + + +static void my_iter_handler( + void * user_instance, + int iter_num, + int depth, + void * ptr_state, + int parent_iter_num, + void * lp_context + ) +{ + freecell_solver_display_information_context_t * context; + context = (freecell_solver_display_information_context_t*)lp_context; + + fprintf(stdout, "Iteration: %i\n", iter_num); + fprintf(stdout, "Depth: %i\n", depth); + fprintf(stdout, "Stored-States: %i\n", + freecell_solver_user_get_num_states_in_collection(user_instance) + ); + if (context->display_parent_iter_num) + { + fprintf(stdout, "Parent Iteration: %i\n", parent_iter_num); + } + fprintf(stdout, "\n"); + + + if (context->debug_iter_state_output) + { + char * state_string = + freecell_solver_user_iter_state_as_string( + user_instance, + ptr_state, + context->parseable_output, + context->canonized_order_output, + context->display_10_as_t + ); + printf("%s\n---------------\n\n\n", state_string); + free((void*)state_string); + } + +#ifdef MYDEBUG + { + fcs_card_t card; + int ret; + char card_str[10]; + + ret = fcs_check_state_validity( + ptr_state_with_locations, + context->freecells_num, + context->stacks_num, + context->decks_num, + &card + ); + + if (ret != 0) + { + + fcs_card_perl2user(card, card_str, context->display_10_as_t); + if (ret == 3) + { + fprintf(stdout, "%s\n", + "There's an empty slot in one of the stacks." + ); + } + else + { + fprintf(stdout, "%s%s.\n", + ((ret == 2)? "There's an extra card: " : "There's a missing card: "), + card_str + ); + } + exit(-1); + } + } +#endif +} + +struct help_screen_struct +{ + char * key; + char * screen; +}; + +typedef struct help_screen_struct help_screen_t; + +help_screen_t help_screens[] = { +{ + "configs", +"These configurations are usually faster than the unmodified run:\n" +"\n" +" fc-solve -l cool-jives\n" +" fc-solve -l john-galt-line\n" +"\n" +"Or if you want an accurate verdict:\n" +"\n" +" fc-solve -l fools-gold\n" +"\n" +"If you want to try constructing your own configurations refer to the\n" +"USAGE file in the Freecell Solver distribution\n" +}, +{ + "options", +"fc-solve [options] board_file\n" +"\n" +"If board_file is - or unspecified reads standard input\n" +"\n" +"Available Options:\n" +"-h --help\n" +" display the default help screen\n" +"--help-summary\n" +" display the summary help screen\n" +"-i --iter-output\n" +" display the iteration number and depth in every state that is checked\n" +"-s --state-output\n" +" also output the state in every state that is checked\n" +"-p --parseable-output\n" +" Output the states in a format that is friendly to perl, grep and\n" +" friends.\n" +"-c --canonized-order-output\n" +" Output the stacks and freecells according to their canonic order.\n" +" (That means that stacks and freecells won't retain their place.)\n" +"-t --display-10-as-t\n" +" Display the card 10 as a capital T instead of \"10\".\n" +"-m --display-moves\n" +" Display the moves instead of the intermediate states.\n" +"-sam --display-states-and-moves \n" +" Display both intermediate states and moves.\n" +"-sn --standard-notation\n" +" Display the moves in standard (non-verbose) notation.\n" +" (Applicable only if -m was specified)\n" +"-snx --standard-notation-extended\n" +" Display the moves in extended standard notation while specifying the\n" +" number of cards moved if applicable\n" +"-pi --display-parent-iter \n" +" Display the index of the parent iteration of each state in the\n" +" run-time dump.\n" +"\n" +"--freecells-num [Freecells\' Number]\n" +" The number of freecells present in the board.\n" +"--stacks-num [Stacks\' Number]\n" +" The number of stacks present in the board.\n" +"--decks-num [Decks\' Number]\n" +" The number of decks in the board.\n" +"\n" +"--sequences-are-built-by {suit|alternate_color|rank}\n" +" Specifies the type of sequence\n" +"--sequence-move {limited|unlimited}\n" +" Specifies whether the sequence move is limited by the number of\n" +" freecells or vacant stacks or not.\n" +"--empty-stacks-filled-by {kings|none|all}\n" +" Specifies which cards can fill empty stacks.\n" +"\n" +"--game [game] --preset [game] -g [game]\n" +" Specifies the type of game. (Implies several of the game settings\n" +" options above.). Available presets:\n" +" bakers_dozen - Baker\'s Dozen\n" +" bakers_game - Baker\'s Game\n" +" beleaguered_castle - Beleaguered Castle\n" +" citadel - Citadel\n" +" cruel - Cruel\n" +" der_katz - Der Katzenschwanz\n" +" die_schlange - Die Schlange\n" +" eight_off - Eight Off\n" +" fan - Fan\n" +" forecell - Forecell\n" +" freecell - Freecell\n" +" good_measure - Good Measure\n" +" ko_bakers_game - Kings\' Only Baker\'s Game\n" +" relaxed_freecell - Relaxed Freecell\n" +" relaxed_seahaven - Relaxed Seahaven Towers\n" +" seahaven - Seahaven Towers\n" +" simple_simon - Simple Simon\n" +" streets_and_alleys - Streets and Alleys\n" +"\n" +"-md [depth] --max-depth [depth] \n" +" Specify a maximal search depth for the solution process.\n" +"-mi [iter_num] --max-iters [iter_num] \n" +" Specify a maximal number of iterations number.\n" +"-mss [states_num] --max-stored-states [states_num] \n" +" Specify the maximal number of states stored in memory.\n" +"\n" +"-to [tests_order] --tests-order [tests_order] \n" +" Specify a test order string. Each test is represented by one character.\n" +" Valid tests:\n" +" Freecell Tests:\n" +"\n" +" '0' - put top stack cards in the foundations.\n" +" '1' - put freecell cards in the foundations.\n" +" '2' - put freecell cards on top of stacks.\n" +" '3' - put non-top stack cards in the foundations.\n" +" '4' - move stack cards to different stacks.\n" +" '5' - move stack cards to a parent card on the same stack.\n" +" '6' - move sequences of cards onto free stacks.\n" +" '7' - put freecell cards on empty stacks.\n" +" '8' - move cards to a different parent.\n" +" '9' - empty an entire stack into the freecells.\n" +"\n" +" Atomic Freecell Tests:\n" +"\n" +" 'A' - move a stack card to an empty stack.\n" +" 'B' - move a stack card to a parent on a different stack.\n" +" 'C' - move a stack card to a freecell.\n" +" 'D' - move a freecel card to a parent.\n" +" 'E' - move a freecel card to an empty stack.\n" +"\n" +" Simple Simon Tests:\n" +"\n" +" 'a' - move a full sequence to the foundations.\n" +" 'b' - move a sequence to a true parent of his.\n" +" 'c' - move a whole stack sequence to a false parent (in order to\n" +" clear the stack)\n" +" 'd' - move a sequence to a true parent that has some cards above it.\n" +" 'e' - move a sequence with some cards above it to a true parent.\n" +" 'f' - move a sequence with a junk sequence above it to a true parent\n" +" that has some cards above it.\n" +" 'g' - move a whole stack sequence to a false parent which has some\n" +" cards above it.\n" +" 'h' - move a sequence to a parent on the same stack.\n" +"\n" +" Tests are grouped with parenthesis or square brackets. Each group\n" +" will be randomized as a whole by the random-dfs scan.\n" +"\n" +"\n" +"-me [solving_method] --method [solving_method]\n" +" Specify a solving method. Available methods are:\n" +" \"a-star\" - A*\n" +" \"bfs\" - Breadth-First Search\n" +" \"dfs\" - Depth-First Search (default)\n" +" \"random-dfs\" - A randomized DFS\n" +" \"soft-dfs\" - \"Soft\" DFS\n" +"\n" +"-asw [A* Weights] --a-star-weight [A* Weights]\n" +" Specify weights for the A* scan, assuming it is used. The parameter\n" +" should be a comma-separated list of numbers, each one is proportional\n" +" to the weight of its corresponding test.\n" +"\n" +" The numbers are, in order:\n" +" 1. The number of cards out.\n" +" 2. The maximal sequence move.\n" +" 3. The number of cards under sequences.\n" +" 4. The length of the sequences which are found over renegade cards.\n" +" 5. The depth of the board in the solution.\n" +"\n" +"-seed [seed_number]\n" +" Set the seed for the random number generator used by the\n" +" \"random-dfs\" scan.\n" +"\n" +"-nst --next-soft-thread\n" +" Move to the next Soft-Thread. I.e: input another scan to run in\n" +" parallel.\n" +"-step [step iterations] --soft-thread-step [step iterations]\n" +" Set the number of iterations in the step of the current soft-thread.\n" +"-nht --next-hard-thread\n" +" Move to the next Hard-Thread. This is a new group of scans to run\n" +" in their own system thread (assuming the executable was compiled with\n" +" support for them.)\n" +"--st-name\n" +" Set the name of the soft-thread.\n" +"\n" +"--prelude [prelude_string]\n" +" Set the prelude string of the hard thread. A prelude is a static\n" +" sequence of iterations quotas that are executed at the beginning of\n" +" the search. The format is a list of [Limit]@[Soft-Thread Name]\n" +" delimited by commas.\n" +"\n" +"-ni --next-instance\n" +" Move to the next distinct solver instance. This is a separate scan\n" +" which would run only if the previous ones returned an unsolvable\n" +" verdict.\n" +"\n" +"-opt --optimize-solution\n" +" Try and optimize the solution for a small number of moves.\n" +"-opt-to --optimization-tests-order\n" +" The test order of the optimization scan.\n" +"\n" +"\n" +"--reparent-states\n" +" Reparent states that have a larger depth than that of the state\n" +" from which they were reached a posteriori.\n" +"--calc-real-depth\n" +" If --reparent-states is enabled, then explictly calculate the real\n" +" depth of a state by tracing its path to the initial state\n" +"--scans-synergy {none|dead-end-marks}\n" +" Specifies the cooperation between the scans.\n" +"\n" +"\n" +"--reset\n" +" Reset the program to its initial, unconfigured state.\n" +"--read-from-file [{num_skip},]filename\n" +" Reads configuration parameter with the file while skipping num_skip\n" +" arguments from the beginning.\n" +"-l [configuration] --load-config [configuration]\n" +" Reads the configuration [configruration] and configures the solver\n" +" accordingly.\n" +"\n" +"\n" +"Signals:\n" +"SIGUSR1 - Prints the number of states that were checked so far to stderr.\n" +"SIGUSR2 SIGUSR1 - Turns iteration output on/off.\n" +"SIGUSR2 SIGUSR2 SIGUSR1 - Turns iteration's state output on/off.\n" +"\n" +"\n" +"Freecell Solver was written by Shlomi Fish.\n" +"Homepage: http://vipe.technion.ac.il/~shlomif/freecell-solver/\n" +"Send comments and suggestions to shlomif@vipe.technion.ac.il\n" +}, +{ + "real-help", +"The environment variable FREECELL_SOLVER_DEFAULT_HELP sets the default help\n" +"screen. The name of the help screen is the same name as its \"--help-\" flag\n" +"but without the preceding \"--help-\". Type:\n" +"\n" +" fc-solve --help-summary\n" +"\n" +"for the available help screens.\n" +"\n" +"Refer to your system's documentation for information on how to set environment\n" +"variables.\n" +}, +{ + "problems", +"To be discussed.\n" +}, +{ + "short-sol", +"The following configurations may produce shorter solutions:\n" +"\n" +" fc-solve -opt\n" +" fc-solve --method a-star -opt\n" +" fc-solve --reparent-states -opt\n" +" fc-solve --method a-star --reparent-states -opt\n" +"\n" +"If \"--method a-star\" is specified you can set the weights with\n" +"-asw {comma separated list of 5 numeric weights}, which may improve\n" +"the length of the solution. (refer to the USAGE file for more information)\n" +}, +{ + "summary", +"fc-solve [flags] [board_file|-]\n" +"\n" +"Reads board from standard input by default or if a \"-\" is specified.\n" +"\n" +"- If it takes too long to finish, type \"fc-solve --help-configs\"\n" +"- If it erroneously reports a board as unsolvable, try adding the\n" +" \"-to 01ABCDE\" flag\n" +"- If the solution is too long type \"fc-solve --help-short-sol\"\n" +"- To present the moves only try adding \"-m\" or \"-m -snx\"\n" +"- For a description of all options type \"fc-solve --help-options\"\n" +"- To deal with other problems type \"fc-solve --help-problems\"\n" +"- To turn --help into something more useful, type\n" +" \"fc-solve --help-real-help\"\n" +"\n" +"Contact Shlomi Fish, shlomif@vipe.technion.ac.il for more information.\n" +}, +{ + NULL, + NULL +} +} +; + +enum MY_FCS_CMD_LINE_RET_VALUES +{ + EXIT_AND_RETURN_0 = FCS_CMD_LINE_USER, + +}; + +static void print_help_string(char * key) +{ + int i; + for(i=0;help_screens[i].key != NULL ; i++) + { + if (!strcmp(key, help_screens[i].key)) + { + printf("%s", help_screens[i].screen); + } + } +} + +static int cmd_line_callback( + void * instance, + int argc, + char * argv[], + int arg, + int * num_to_skip, + int * ret, + void * context + ) +{ + freecell_solver_display_information_context_t * dc; + *num_to_skip = 0; + + dc = (freecell_solver_display_information_context_t * )context; + + if ((!strcmp(argv[arg], "-h")) || (!strcmp(argv[arg], "--help"))) + { + char * help_key; + + help_key = getenv("FREECELL_SOLVER_DEFAULT_HELP"); + if (help_key == NULL) + { + help_key = "summary"; + } + print_help_string(help_key); + *ret = EXIT_AND_RETURN_0; + return FCS_CMD_LINE_STOP; + } + else if (!strncmp(argv[arg], "--help-", 7)) + { + print_help_string(argv[arg]+7); + *ret = EXIT_AND_RETURN_0; + return FCS_CMD_LINE_STOP; + } + else if ((!strcmp(argv[arg], "-i")) || (!strcmp(argv[arg], "--iter-output"))) + { +#define set_iter_handler() \ + freecell_solver_user_set_iter_handler( \ + instance, \ + my_iter_handler, \ + dc \ + ); \ + dc->debug_iter_output_on = 1; + + set_iter_handler(); + } + else if ((!strcmp(argv[arg], "-s")) || (!strcmp(argv[arg], "--state-output"))) + { + set_iter_handler(); + dc->debug_iter_state_output = 1; +#undef set_iter_handler + } + else if ((!strcmp(argv[arg], "-p")) || (!strcmp(argv[arg], "--parseable-output"))) + { + dc->parseable_output = 1; + } + else if ((!strcmp(argv[arg], "-c")) || (!strcmp(argv[arg], "--canonized-order-output"))) + { + dc->canonized_order_output = 1; + } + else if ((!strcmp(argv[arg], "-t")) || (!strcmp(argv[arg], "--display-10-as-t"))) + { + dc->display_10_as_t = 1; + } + else if ((!strcmp(argv[arg], "-m")) || (!strcmp(argv[arg], "--display-moves"))) + { + dc->display_moves = 1; + dc->display_states = 0; + } + else if ((!strcmp(argv[arg], "-sn")) || (!strcmp(argv[arg], "--standard-notation"))) + { + dc->standard_notation = 1; + + } + else if ((!strcmp(argv[arg], "-snx")) || (!strcmp(argv[arg], "--standard-notation-extended"))) + { + dc->standard_notation = 2; + } + else if ((!strcmp(argv[arg], "-sam")) || (!strcmp(argv[arg], "--display-states-and-moves"))) + { + dc->display_moves = 1; + dc->display_states = 1; + } + else if ((!strcmp(argv[arg], "-pi")) || (!strcmp(argv[arg], "--display-parent-iter"))) + { + dc->display_parent_iter_num = 1; + } + else if ((!strcmp(argv[arg], "--reset"))) + { + init_debug_context(dc); + freecell_solver_user_set_iter_handler( + instance, + NULL, + NULL + ); + *num_to_skip = 0; + return FCS_CMD_LINE_OK; + } + else + { + printf("Unimplemented option - \"%s\"!", argv[arg]); + exit(-1); + } + *num_to_skip = 1; + return FCS_CMD_LINE_SKIP; +} + + +static int command_num = 0; +static int debug_iter_output_on = 0; + +static void select_signal_handler(int signal_num) +{ + command_num = (command_num+1)%3; +} + +static void * current_instance; +static freecell_solver_display_information_context_t * dc; + + +static void command_signal_handler(int signal_num) +{ + if (command_num == 0) + { + fprintf( + stderr, + "The number of iterations is %i\n", + freecell_solver_user_get_num_times(current_instance) + ); + } + else if (command_num == 1) + { + if (debug_iter_output_on) + { + freecell_solver_user_set_iter_handler( + current_instance, + NULL, + NULL + ); + debug_iter_output_on = 0; + } + else + { + freecell_solver_user_set_iter_handler( + current_instance, + my_iter_handler, + dc + ); + debug_iter_output_on = 1; + } + } + else if (command_num == 2) + { + dc->debug_iter_state_output = ! dc->debug_iter_state_output; + } + + command_num = 0; +} + + +static char * known_parameters[] = { + "-h", "--help", + "--help-configs", "--help-options", "--help-problems", + "--help-real-help", "--help-short-sol", "--help-summary", + "-i", "--iter-output", + "-s", "--state-output", + "-p", "--parseable-output", + "-c", "--canonized-order-output", + "-t", "--display-10-as-t", + "-m", "--display-moves", + "-sn", "--standard-notation", + "-snx", "--standard-notation-extended", + "-sam", "--display-states-and-moves", + "-pi", "--display-parent-iter", + "--reset", + NULL + }; + +#define USER_STATE_SIZE 1024 + +int main(int argc, char * argv[]) +{ + int parser_ret; + void * instance; + char * error_string; + int arg; + FILE * file; + char user_state[USER_STATE_SIZE]; + int ret; + + freecell_solver_display_information_context_t debug_context; + + init_debug_context(&debug_context); + + dc = &debug_context; + + instance = freecell_solver_user_alloc(); + + current_instance = instance; + + + parser_ret = + freecell_solver_user_cmd_line_parse_args( + instance, + argc, + argv, + 1, + 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); + } + else + { + if (ret == FCS_STATE_WAS_SOLVED) + { + printf("-=-=-=-=-=-=-=-=-=-=-=-\n\n"); + { + fcs_move_t move; + FILE * move_dump; + char * as_string; + int move_num = 0; + + move_dump = stdout; + + + 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"); + } + } + + printf("This game is solveable.\n"); + } + else + { + printf ("I could not solve this game.\n"); + } + + printf( + "Total number of states checked is %i.\n", + freecell_solver_user_get_num_times(instance) + ); +#if 1 + printf( + "This scan generated %i states.\n", + freecell_solver_user_get_num_states_in_collection(instance) + ); +#endif + } + + freecell_solver_user_free(instance); + + return 0; +} + |