~ubuntu-branches/ubuntu/saucy/freecell-solver/saucy

« back to all changes in this revision

Viewing changes to main.c

  • Committer: Package Import Robot
  • Author(s): Gergely Risko
  • Date: 2012-06-22 10:08:05 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120622100805-evoda1ccdr8vt5xr
Tags: 3.12.0-1
New upstream version. (closes: #675262)

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 * executable.
27
27
 *
28
28
 * It is documented in the documents "README", "USAGE", etc. in the
29
 
 * Freecell Solver distribution from http://fc-solve.berlios.de/ .
 
29
 * Freecell Solver distribution from http://fc-solve.shlomifish.org/ .
30
30
 */
31
31
#include <string.h>
32
32
#include <stdio.h>
37
37
#include "unused.h"
38
38
#include "bool.h"
39
39
 
40
 
enum STANDARD_NOTATION_TYPE
41
 
{
42
 
    STANDARD_NOTATION_NO,
43
 
    STANDARD_NOTATION_REGULAR,
44
 
    STANDARD_NOTATION_EXTENDED
45
 
};
46
 
 
47
 
 
48
 
struct fc_solve_display_information_context_struct
49
 
{
50
 
    fcs_bool_t debug_iter_state_output;
51
 
    int freecells_num;
52
 
    int stacks_num;
53
 
    int decks_num;
54
 
    fcs_bool_t parseable_output;
55
 
    fcs_bool_t canonized_order_output;
56
 
    fcs_bool_t display_10_as_t;
57
 
    fcs_bool_t display_parent_iter_num;
58
 
    fcs_bool_t debug_iter_output_on;
59
 
    fcs_bool_t display_moves;
60
 
    fcs_bool_t display_states;
61
 
    int standard_notation;
62
 
    const char * output_filename;
63
 
};
64
 
 
65
 
typedef struct fc_solve_display_information_context_struct fc_solve_display_information_context_t;
66
 
 
67
 
static void init_debug_context(
68
 
    fc_solve_display_information_context_t * dc
69
 
    )
70
 
{
71
 
    dc->debug_iter_state_output = FALSE;
72
 
    dc->parseable_output = FALSE;
73
 
    dc->canonized_order_output = FALSE;
74
 
    dc->display_10_as_t = FALSE;
75
 
    dc->display_parent_iter_num = FALSE;
76
 
    dc->display_moves = FALSE;
77
 
    dc->display_states = TRUE;
78
 
    dc->standard_notation = STANDARD_NOTATION_NO;
79
 
    dc->output_filename = NULL;
80
 
}
 
40
#ifdef FCS_TRACE_MEM
 
41
#include "portable_time.h"
 
42
#include <unistd.h>
 
43
#include <sys/types.h>
 
44
#endif
 
45
 
 
46
#include "output_to_file.h"
81
47
 
82
48
static void my_iter_handler(
83
49
    void * user_instance,
354
320
"\n"
355
321
"\n"
356
322
"Freecell Solver was written by Shlomi Fish.\n"
357
 
"Homepage: http://fc-solve.berlios.de/\n"
 
323
"Homepage: http://fc-solve.shlomifish.org/\n"
358
324
"Send comments and suggestions to http://www.shlomifish.org/me/contact-me/\n"
359
325
},
360
326
{
429
395
    }
430
396
}
431
397
 
 
398
#define IS_ARG(s) (!strcmp(arg_str, (s)))
 
399
 
432
400
static int cmd_line_callback(
433
401
    void * instance,
434
402
    int argc,
439
407
    void * context
440
408
    )
441
409
{
 
410
    /* TODO: extract a macro IS_ARG("string") for IS_ARG("string")
 
411
     * */
442
412
    fc_solve_display_information_context_t * dc;
 
413
    const char * arg_str;
 
414
 
443
415
    *num_to_skip = 0;
444
416
 
445
417
    dc = (fc_solve_display_information_context_t * )context;
 
418
    arg_str = argv[arg];
446
419
 
447
 
    if (!strcmp(argv[arg], "--version"))
 
420
    if (IS_ARG("--version"))
448
421
    {
449
422
        printf(
450
423
            "fc-solve\nlibfreecell-solver version %s\n",
453
426
        *ret = EXIT_AND_RETURN_0;
454
427
        return FCS_CMD_LINE_STOP;
455
428
    }
456
 
    else if ((!strcmp(argv[arg], "-h")) || (!strcmp(argv[arg], "--help")))
 
429
    else if (IS_ARG("-h") || IS_ARG("--help"))
457
430
    {
458
 
        char * help_key;
 
431
        const char * help_key;
459
432
 
460
433
        help_key = getenv("FREECELL_SOLVER_DEFAULT_HELP");
461
434
        if (help_key == NULL)
466
439
        *ret = EXIT_AND_RETURN_0;
467
440
        return FCS_CMD_LINE_STOP;
468
441
    }
469
 
    else if (!strncmp(argv[arg], "--help-", 7))
 
442
    else if (!strncmp(arg_str, "--help-", 7))
470
443
    {
471
 
        print_help_string(argv[arg]+7);
 
444
        print_help_string(arg_str+7);
472
445
        *ret = EXIT_AND_RETURN_0;
473
446
        return FCS_CMD_LINE_STOP;
474
447
    }
475
 
    else if ((!strcmp(argv[arg], "-i")) || (!strcmp(argv[arg], "--iter-output")))
 
448
    else if (IS_ARG("-i") || IS_ARG("--iter-output"))
476
449
    {
477
450
#define set_iter_handler() \
478
451
        freecell_solver_user_set_iter_handler(   \
484
457
 
485
458
        set_iter_handler();
486
459
    }
487
 
    else if ((!strcmp(argv[arg], "-s")) || (!strcmp(argv[arg], "--state-output")))
 
460
    else if (IS_ARG("-s") || IS_ARG("--state-output"))
488
461
    {
489
462
        set_iter_handler();
490
463
        dc->debug_iter_state_output = TRUE;
491
464
#undef set_iter_handler
492
465
    }
493
 
    else if ((!strcmp(argv[arg], "-p")) || (!strcmp(argv[arg], "--parseable-output")))
 
466
    else if (IS_ARG("-p") || IS_ARG("--parseable-output"))
494
467
    {
495
468
        dc->parseable_output = TRUE;
496
469
    }
497
 
    else if ((!strcmp(argv[arg], "-c")) || (!strcmp(argv[arg], "--canonized-order-output")))
 
470
    else if (IS_ARG("-c") || IS_ARG("--canonized-order-output"))
498
471
    {
499
472
        dc->canonized_order_output = TRUE;
500
473
    }
501
 
    else if ((!strcmp(argv[arg], "-o")) || (!strcmp(argv[arg], "--output")))
 
474
    else if (IS_ARG("-o") || IS_ARG("--output"))
502
475
    {
503
476
        arg++;
504
477
        if (arg == argc)
509
482
        dc->output_filename = (const char *)argv[arg];
510
483
        return FCS_CMD_LINE_SKIP;
511
484
    }
512
 
    else if ((!strcmp(argv[arg], "-t")) || (!strcmp(argv[arg], "--display-10-as-t")))
 
485
    else if (IS_ARG("-t") || IS_ARG("--display-10-as-t"))
513
486
    {
514
487
        dc->display_10_as_t = TRUE;
515
488
    }
516
 
    else if ((!strcmp(argv[arg], "-m")) || (!strcmp(argv[arg], "--display-moves")))
 
489
    else if (IS_ARG("-m") || IS_ARG("--display-moves"))
517
490
    {
518
491
        dc->display_moves = TRUE;
519
492
        dc->display_states = FALSE;
520
493
    }
521
 
    else if ((!strcmp(argv[arg], "-sn")) || (!strcmp(argv[arg], "--standard-notation")))
 
494
    else if (IS_ARG("-sn") || IS_ARG("--standard-notation"))
522
495
    {
523
496
        dc->standard_notation = STANDARD_NOTATION_REGULAR;
524
497
 
525
498
    }
526
 
    else if ((!strcmp(argv[arg], "-snx")) || (!strcmp(argv[arg], "--standard-notation-extended")))
 
499
    else if (IS_ARG("-snx") || IS_ARG("--standard-notation-extended"))
527
500
    {
528
501
        dc->standard_notation = STANDARD_NOTATION_EXTENDED;
529
502
    }
530
 
    else if ((!strcmp(argv[arg], "-sam")) || (!strcmp(argv[arg], "--display-states-and-moves")))
 
503
    else if (IS_ARG("-sam") || IS_ARG("--display-states-and-moves"))
531
504
    {
532
505
        dc->display_moves = TRUE;
533
506
        dc->display_states = TRUE;
534
507
    }
535
 
    else if ((!strcmp(argv[arg], "-pi")) || (!strcmp(argv[arg], "--display-parent-iter")))
 
508
    else if (IS_ARG("-pi") || IS_ARG("--display-parent-iter"))
536
509
    {
537
510
        dc->display_parent_iter_num = TRUE;
538
511
    }
539
 
    else if ((!strcmp(argv[arg], "--reset")))
 
512
    else if (IS_ARG("-sel") || IS_ARG("--show-exceeded-limits"))
 
513
    {
 
514
        dc->show_exceeded_limits = TRUE;
 
515
    }
 
516
    else if (IS_ARG("--reset"))
540
517
    {
541
518
        init_debug_context(dc);
542
519
        freecell_solver_user_set_iter_handler(
549
526
    }
550
527
    else
551
528
    {
552
 
        printf("Unimplemented option - \"%s\"!", argv[arg]);
 
529
        printf("Unimplemented option - \"%s\"!", arg_str);
553
530
        exit(-1);
554
531
    }
555
532
    *num_to_skip = 1;
556
533
    return FCS_CMD_LINE_SKIP;
557
534
}
558
535
 
 
536
#undef IS_ARG
559
537
 
560
538
static int command_num = 0;
561
539
static int debug_iter_output_on = FALSE;
623
601
    "-snx", "--standard-notation-extended",
624
602
    "-sam", "--display-states-and-moves",
625
603
    "-pi", "--display-parent-iter",
 
604
    "-sel", "--show-exceeded-limits",
626
605
    "-o", "--output",
627
606
    "--reset",
628
607
    "--version",
657
636
            freecell_solver_user_cmd_line_parse_args(
658
637
                instance,
659
638
                argc,
660
 
                (freecell_solver_str_t *)argv,
 
639
                (freecell_solver_str_t *)(void *)argv,
661
640
                1,
662
641
                (freecell_solver_str_t *)known_parameters,
663
642
                cmd_line_callback,
671
650
            freecell_solver_user_free(instance);
672
651
            return 0;
673
652
        }
674
 
        else if (
675
 
            (parser_ret == FCS_CMD_LINE_PARAM_WITH_NO_ARG)
676
 
                )
 
653
        else if (parser_ret == FCS_CMD_LINE_PARAM_WITH_NO_ARG)
677
654
        {
678
655
            fprintf(stderr, "The command line parameter \"%s\" requires an argument"
679
656
                    " and was not supplied with one.\n", argv[arg]);
680
657
            return (-1);
681
658
        }
682
 
        else if (
683
 
            (parser_ret == FCS_CMD_LINE_ERROR_IN_ARG)
684
 
            )
 
659
        else if (parser_ret == FCS_CMD_LINE_ERROR_IN_ARG)
685
660
        {
686
661
            if (error_string != NULL)
687
662
            {
753
728
            ret = freecell_solver_user_resume_solution(instance);
754
729
        }
755
730
    }
 
731
#elif defined(FCS_TRACE_MEM)
 
732
    {
 
733
#define STEP 100000
 
734
        int limit = STEP;
 
735
        char stat_fn[1024], foo_str[1024];
 
736
        fcs_portable_time_t mytime;
 
737
        FILE * stat;
 
738
        long long int rss;
 
739
        unsigned long long unsigned_foo;
 
740
 
 
741
        snprintf(stat_fn, sizeof(stat_fn), "/proc/%ld/stat", (long)(getpid()));
 
742
 
 
743
        freecell_solver_user_limit_iterations(instance, limit);
 
744
        ret = freecell_solver_user_solve_board(instance, user_state);
 
745
        while (ret == FCS_STATE_SUSPEND_PROCESS)
 
746
        {
 
747
            FCS_GET_TIME(mytime);
 
748
 
 
749
            /* This was taken from:
 
750
             *
 
751
             * http://www.brokestream.com/procstat.html
 
752
             * */
 
753
            stat = fopen(stat_fn, "r");
 
754
#define readone(foo) (fscanf(stat, "%lld ", &rss))
 
755
#define readstr(foo) (fscanf(stat, "%1000s ", foo_str))
 
756
#define readchar(foo) (fscanf(stat, "%c ", foo_str))
 
757
#define readunsigned(foo) (fscanf(stat, "%llu ", &unsigned_foo))
 
758
            readone(&pid);
 
759
            readstr(tcomm);
 
760
            readchar(&state);
 
761
            readone(&ppid);
 
762
            readone(&pgid);
 
763
            readone(&sid);
 
764
            readone(&tty_nr);
 
765
            readone(&tty_pgrp);
 
766
            readone(&flags);
 
767
            readone(&min_flt);
 
768
            readone(&cmin_flt);
 
769
            readone(&maj_flt);
 
770
            readone(&cmaj_flt);
 
771
            readone(&utime);
 
772
            readone(&stimev);
 
773
            readone(&cutime);
 
774
            readone(&cstime);
 
775
            readone(&priority);
 
776
            readone(&nicev);
 
777
            readone(&num_threads);
 
778
            readone(&it_real_value);
 
779
            readunsigned(&start_time);
 
780
            readone(&vsize);
 
781
            readone(&rss);
 
782
#undef readone
 
783
#undef readunsigned
 
784
#undef readchar
 
785
#undef readstr
 
786
 
 
787
            fclose(stat);
 
788
 
 
789
            printf("Reached:\t%d\t%li.%.6li\t%lld\n",
 
790
                    limit,
 
791
                    FCS_TIME_GET_SEC(mytime),
 
792
                    FCS_TIME_GET_USEC(mytime),
 
793
                    rss
 
794
                  );
 
795
 
 
796
            fflush(stdout);
 
797
            limit += STEP;
 
798
            freecell_solver_user_limit_iterations(instance, limit);
 
799
            ret = freecell_solver_user_resume_solution(instance);
 
800
        }
 
801
    }
 
802
#undef STEP
756
803
#else
757
804
    ret = freecell_solver_user_solve_board(instance, user_state);
758
805
#endif
799
846
            output_fh = stdout;
800
847
        }
801
848
 
802
 
        if (ret == FCS_STATE_WAS_SOLVED)
803
 
        {
804
 
            fprintf(output_fh, "-=-=-=-=-=-=-=-=-=-=-=-\n\n");
805
 
            {
806
 
                fcs_move_t move;
807
 
                FILE * move_dump;
808
 
                char * as_string;
809
 
                int move_num = 0;
810
 
 
811
 
                move_dump = output_fh;
812
 
 
813
 
                if (debug_context.display_states)
814
 
                {
815
 
                    as_string =
816
 
                        freecell_solver_user_current_state_as_string(
817
 
                            instance,
818
 
                            debug_context.parseable_output,
819
 
                            debug_context.canonized_order_output,
820
 
                            debug_context.display_10_as_t
821
 
                            );
822
 
 
823
 
                    fprintf(move_dump, "%s\n", as_string);
824
 
 
825
 
                    free(as_string);
826
 
 
827
 
                    fprintf(move_dump, "%s", "\n====================\n\n");
828
 
                }
829
 
 
830
 
                while (
831
 
                        freecell_solver_user_get_next_move(
832
 
                            instance,
833
 
                            &move
834
 
                            ) == 0
835
 
                        )
836
 
                {
837
 
                    if (debug_context.display_moves)
838
 
                    {
839
 
                        as_string =
840
 
                            freecell_solver_user_move_to_string_w_state(
841
 
                                instance,
842
 
                                move,
843
 
                                debug_context.standard_notation
844
 
                                );
845
 
 
846
 
                        if (debug_context.display_states && debug_context.standard_notation)
847
 
                        {
848
 
                            fprintf(move_dump, "Move: ");
849
 
                        }
850
 
 
851
 
                        fprintf(
852
 
                            move_dump,
853
 
                            (debug_context.standard_notation ?
854
 
                                "%s " :
855
 
                                "%s\n"
856
 
                            ),
857
 
                            as_string
858
 
                            );
859
 
                        move_num++;
860
 
                        if (debug_context.standard_notation)
861
 
                        {
862
 
                            if ((move_num % 10 == 0) || debug_context.display_states)
863
 
                            {
864
 
                                fprintf(move_dump, "\n");
865
 
                            }
866
 
                        }
867
 
                        if (debug_context.display_states)
868
 
                        {
869
 
                            fprintf(move_dump, "\n");
870
 
                        }
871
 
                        fflush(move_dump);
872
 
                        free(as_string);
873
 
                    }
874
 
 
875
 
                    if (debug_context.display_states)
876
 
                    {
877
 
                        as_string =
878
 
                            freecell_solver_user_current_state_as_string(
879
 
                                instance,
880
 
                                debug_context.parseable_output,
881
 
                                debug_context.canonized_order_output,
882
 
                                debug_context.display_10_as_t
883
 
                                );
884
 
 
885
 
                        fprintf(move_dump, "%s\n", as_string);
886
 
 
887
 
                        free(as_string);
888
 
                    }
889
 
 
890
 
                    if (debug_context.display_states || (!debug_context.standard_notation))
891
 
                    {
892
 
                        fprintf(move_dump, "%s", "\n====================\n\n");
893
 
                    }
894
 
                }
895
 
 
896
 
                if (debug_context.standard_notation && (!debug_context.display_states))
897
 
                {
898
 
                    fprintf(move_dump, "\n\n");
899
 
                }
900
 
            }
901
 
 
902
 
            fprintf(output_fh, "This game is solveable.\n");
903
 
        }
904
 
        else
905
 
        {
906
 
            fprintf (output_fh, "I could not solve this game.\n");
907
 
        }
908
 
 
909
 
        fprintf(
910
 
            output_fh,
911
 
            "Total number of states checked is %i.\n",
912
 
            freecell_solver_user_get_num_times(instance)
913
 
            );
914
 
#if 1
915
 
        fprintf(
916
 
            output_fh,
917
 
            "This scan generated %i states.\n",
918
 
            freecell_solver_user_get_num_states_in_collection(instance)
919
 
            );
920
 
#endif
 
849
        fc_solve_output_result_to_file(
 
850
            output_fh, instance, ret, &debug_context
 
851
        );
921
852
 
922
853
        if (debug_context.output_filename)
923
854
        {