~ubuntu-branches/ubuntu/natty/freecell-solver/natty

« back to all changes in this revision

Viewing changes to intrface.c

  • Committer: Bazaar Package Importer
  • Author(s): RISKO Gergely
  • Date: 2009-03-15 23:42:21 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090315234221-sx95hxyfyfgi0pja
Tags: 2.16.0-1
* Imported Upstream version 2.16.0 (closes: #518440)
* cmake is the new buildsystem

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * intrface.c - instance interface functions for Freecell Solver
3
3
 *
4
 
 * Written by Shlomi Fish (shlomif@vipe.technion.ac.il), 2000-2001
 
4
 * Written by Shlomi Fish ( http://www.shlomifish.org/ ), 2000-2001
5
5
 *
6
6
 * This file is in the public domain (it's uncopyrighted).
7
7
 */
43
43
 
44
44
/*
45
45
    General use of this interface:
46
 
    1. freecell_solver_alloc_instance()
 
46
    1. fc_solve_alloc_instance()
47
47
    2. Set the parameters of the game
48
48
    3. If you wish to revert, go to step #11.
49
 
    4. freecell_solver_init_instance()
50
 
    5. Call freecell_solver_solve_instance() with the initial board.
 
49
    4. fc_solve_init_instance()
 
50
    5. Call fc_solve_solve_instance() with the initial board.
51
51
    6. If it returns FCS_STATE_SUSPEND_PROCESS and you wish to proceed,
52
52
       then increase the iteration limit and call
53
 
       freecell_solver_resume_instance().
 
53
       fc_solve_resume_instance().
54
54
    7. Repeat Step #6 zero or more times.
55
55
    8. If the last call to solve_instance() or resume_instance() returned
56
56
       FCS_STATE_SUSPEND_PROCESS then call
57
 
       freecell_solver_unresume_instance().
 
57
       fc_solve_unresume_instance().
58
58
    9. If the solving was successful you can use the move stacks or the
59
59
       intermediate stacks. (Just don't destory them in any way).
60
 
    10. Call freecell_solver_finish_instance().
61
 
    11. Call freecell_solver_free_instance().
 
60
    10. Call fc_solve_finish_instance().
 
61
    11. Call fc_solve_free_instance().
62
62
 
63
63
    The library functions inside lib.c (a.k.a fcs_user()) give an
64
64
    easier approach for embedding Freecell Solver into your library. The
67
67
*/
68
68
 
69
69
#if 0
70
 
static const double freecell_solver_a_star_default_weights[5] = {0.5,0,0.5,0,0};
 
70
static const double fc_solve_a_star_default_weights[5] = {0.5,0,0.5,0,0};
71
71
#else
72
 
static const double freecell_solver_a_star_default_weights[5] = {0.5,0,0.3,0,0.2};
 
72
static const double fc_solve_a_star_default_weights[5] = {0.5,0,0.3,0,0.2};
73
73
#endif
74
74
 
75
75
 
78
78
 
79
79
 
80
80
 
81
 
static void freecell_solver_initialize_bfs_queue(freecell_solver_soft_thread_t * soft_thread)
 
81
static void fc_solve_initialize_bfs_queue(fc_solve_soft_thread_t * soft_thread)
82
82
{
83
83
    /* Initialize the BFS queue. We have one dummy element at the beginning
84
84
       in order to make operations simpler. */
89
89
}
90
90
 
91
91
static void foreach_soft_thread(
92
 
    freecell_solver_instance_t * instance,
 
92
    fc_solve_instance_t * instance,
93
93
    void (*soft_thread_callback)(
94
 
        freecell_solver_soft_thread_t * soft_thread,
 
94
        fc_solve_soft_thread_t * soft_thread,
95
95
        void * context
96
96
        ),
97
97
    void * context
99
99
 
100
100
{
101
101
    int ht_idx, st_idx;
102
 
    freecell_solver_hard_thread_t * hard_thread;
 
102
    fc_solve_hard_thread_t * hard_thread;
103
103
    int num_soft_threads;
104
 
    freecell_solver_soft_thread_t * * ht_soft_threads;
 
104
    fc_solve_soft_thread_t * * ht_soft_threads;
105
105
    for(ht_idx = 0 ; ht_idx<instance->num_hard_threads; ht_idx++)
106
106
    {
107
107
        hard_thread = instance->hard_threads[ht_idx];
122
122
 
123
123
 
124
124
static void soft_thread_clean_soft_dfs(
125
 
    freecell_solver_soft_thread_t * soft_thread,
 
125
    fc_solve_soft_thread_t * soft_thread,
126
126
    void * context
127
127
    )
128
128
{
169
169
}
170
170
 
171
171
static void clean_soft_dfs(
172
 
        freecell_solver_instance_t * instance
 
172
        fc_solve_instance_t * instance
173
173
        )
174
174
{
175
175
    foreach_soft_thread(instance, soft_thread_clean_soft_dfs, NULL);
176
176
}
177
177
 
178
 
static freecell_solver_soft_thread_t * alloc_soft_thread(
179
 
        freecell_solver_hard_thread_t * hard_thread
 
178
static fc_solve_soft_thread_t * alloc_soft_thread(
 
179
        fc_solve_hard_thread_t * hard_thread
180
180
        )
181
181
{
182
 
    freecell_solver_soft_thread_t * soft_thread;
 
182
    fc_solve_soft_thread_t * soft_thread;
183
183
    int a;
184
184
 
185
185
    /* Make sure we are not exceeding the maximal number of soft threads
189
189
        return NULL;
190
190
    }
191
191
 
192
 
    soft_thread = malloc(sizeof(freecell_solver_soft_thread_t));
 
192
    soft_thread = malloc(sizeof(fc_solve_soft_thread_t));
193
193
 
194
194
    soft_thread->hard_thread = hard_thread;
195
195
 
210
210
 
211
211
    soft_thread->orig_method = FCS_METHOD_NONE;
212
212
 
213
 
    freecell_solver_initialize_bfs_queue(soft_thread);
 
213
    fc_solve_initialize_bfs_queue(soft_thread);
214
214
 
215
215
    /* Initialize the priotity queue of the A* scan */
216
216
    soft_thread->a_star_pqueue = malloc(sizeof(PQUEUE));
217
 
    freecell_solver_PQueueInitialise(
 
217
    fc_solve_PQueueInitialise(
218
218
        soft_thread->a_star_pqueue,
219
219
        1024
220
220
        );
222
222
    /* Set the default A* weigths */
223
223
    for(a=0;a<(sizeof(soft_thread->a_star_weights)/sizeof(soft_thread->a_star_weights[0]));a++)
224
224
    {
225
 
        soft_thread->a_star_weights[a] = freecell_solver_a_star_default_weights[a];
 
225
        soft_thread->a_star_weights[a] = fc_solve_a_star_default_weights[a];
226
226
    }
227
227
 
228
 
    soft_thread->rand_gen = freecell_solver_rand_alloc(soft_thread->rand_seed = 24);
 
228
    soft_thread->rand_gen = fc_solve_rand_alloc(soft_thread->rand_seed = 24);
229
229
 
230
230
    soft_thread->initialized = 0;
231
231
 
234
234
#if 0
235
235
    {
236
236
        char * no_use;
237
 
        freecell_solver_apply_tests_order(soft_thread, "[01][23456789]", &no_use);
 
237
        fc_solve_apply_tests_order(soft_thread, "[01][23456789]", &no_use);
238
238
    }
239
239
#else
240
240
    soft_thread->tests_order.num = soft_thread->hard_thread->instance->instance_tests_order.num;
254
254
    return soft_thread;
255
255
}
256
256
 
257
 
static freecell_solver_hard_thread_t * alloc_hard_thread(
258
 
        freecell_solver_instance_t * instance
 
257
static fc_solve_hard_thread_t * alloc_hard_thread(
 
258
        fc_solve_instance_t * instance
259
259
        )
260
260
{
261
 
    freecell_solver_hard_thread_t * hard_thread;
 
261
    fc_solve_hard_thread_t * hard_thread;
262
262
 
263
263
    /* Make sure we are not exceeding the maximal number of soft threads
264
264
     * for an instance. */
267
267
        return NULL;
268
268
    }
269
269
 
270
 
    hard_thread = malloc(sizeof(freecell_solver_hard_thread_t));
 
270
    hard_thread = malloc(sizeof(fc_solve_hard_thread_t));
271
271
 
272
272
    hard_thread->instance = instance;
273
273
 
293
293
 
294
294
#ifdef INDIRECT_STACK_STATES
295
295
    hard_thread->stacks_allocator = 
296
 
        freecell_solver_compact_allocator_new();
 
296
        fc_solve_compact_allocator_new();
297
297
#endif
298
298
    hard_thread->move_stacks_allocator =
299
 
        freecell_solver_compact_allocator_new();
 
299
        fc_solve_compact_allocator_new();
300
300
 
301
301
    fcs_move_stack_alloc_into_var(hard_thread->reusable_move_stack);
302
302
 
314
314
    default values in it. After the call to this function, the program can
315
315
    set parameters in it which are different from the default.
316
316
 
317
 
    Afterwards freecell_solver_init_instance() should be called in order
 
317
    Afterwards fc_solve_init_instance() should be called in order
318
318
    to really prepare it for solving.
319
319
  */
320
 
freecell_solver_instance_t * freecell_solver_alloc_instance(void)
 
320
fc_solve_instance_t * fc_solve_alloc_instance(void)
321
321
{
322
 
    freecell_solver_instance_t * instance;
 
322
    fc_solve_instance_t * instance;
323
323
 
324
 
    instance = malloc(sizeof(freecell_solver_instance_t));
 
324
    instance = malloc(sizeof(fc_solve_instance_t));
325
325
 
326
326
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INDIRECT)
327
327
    instance->num_indirect_prev_states = 0;
354
354
 
355
355
    instance->num_hard_threads = 0;
356
356
 
357
 
    freecell_solver_apply_preset_by_name(instance, "freecell");
 
357
    fc_solve_apply_preset_by_name(instance, "freecell");
358
358
 
359
359
    /****************************************/
360
360
 
395
395
 
396
396
 
397
397
 
398
 
static void free_bfs_queue(freecell_solver_soft_thread_t * soft_thread)
 
398
static void free_bfs_queue(fc_solve_soft_thread_t * soft_thread)
399
399
{
400
400
    /* Free the BFS linked list */
401
401
    fcs_states_linked_list_item_t * item, * next_item;
408
408
    }
409
409
}
410
410
 
411
 
static void free_instance_soft_thread_callback(freecell_solver_soft_thread_t * soft_thread, void * context)
 
411
static void free_instance_soft_thread_callback(fc_solve_soft_thread_t * soft_thread, void * context)
412
412
{
413
413
    free_bfs_queue(soft_thread);
414
 
    freecell_solver_rand_free(soft_thread->rand_gen);
 
414
    fc_solve_rand_free(soft_thread->rand_gen);
415
415
 
416
 
    freecell_solver_PQueueFree(soft_thread->a_star_pqueue);
 
416
    fc_solve_PQueueFree(soft_thread->a_star_pqueue);
417
417
    free(soft_thread->a_star_pqueue);
418
418
 
419
419
    free(soft_thread->tests_order.tests);
426
426
    free(soft_thread);
427
427
}
428
428
 
429
 
static void free_instance_hard_thread_callback(freecell_solver_hard_thread_t * hard_thread)
 
429
static void free_instance_hard_thread_callback(fc_solve_hard_thread_t * hard_thread)
430
430
{
431
431
    if (hard_thread->prelude_as_string)
432
432
    {
442
442
 
443
443
    if (hard_thread->move_stacks_allocator)
444
444
    {
445
 
        freecell_solver_compact_allocator_finish(hard_thread->move_stacks_allocator);
 
445
        fc_solve_compact_allocator_finish(hard_thread->move_stacks_allocator);
446
446
    }
447
447
#ifdef INDIRECT_STACK_STATES
448
448
    if (hard_thread->stacks_allocator)
449
449
    {
450
 
        freecell_solver_compact_allocator_finish(hard_thread->stacks_allocator);
 
450
        fc_solve_compact_allocator_finish(hard_thread->stacks_allocator);
451
451
    }
452
452
#endif
453
453
    free(hard_thread);    
458
458
    sequence of operations on instance, and it is meant for de-allocating
459
459
    whatever memory was allocated by alloc_instance().
460
460
  */
461
 
void freecell_solver_free_instance(freecell_solver_instance_t * instance)
 
461
void fc_solve_free_instance(fc_solve_instance_t * instance)
462
462
{
463
463
    int ht_idx;
464
464
 
486
486
 
487
487
 
488
488
static void normalize_a_star_weights(
489
 
    freecell_solver_soft_thread_t * soft_thread,
 
489
    fc_solve_soft_thread_t * soft_thread,
490
490
    void * context
491
491
    )
492
492
{
498
498
    {
499
499
        if (soft_thread->a_star_weights[a] < 0)
500
500
        {
501
 
            soft_thread->a_star_weights[a] = freecell_solver_a_star_default_weights[a];
 
501
            soft_thread->a_star_weights[a] = fc_solve_a_star_default_weights[a];
502
502
        }
503
503
        sum += soft_thread->a_star_weights[a];
504
504
    }
513
513
}
514
514
 
515
515
static void accumulate_tests_order(
516
 
    freecell_solver_soft_thread_t * soft_thread,
 
516
    fc_solve_soft_thread_t * soft_thread,
517
517
    void * context
518
518
    )
519
519
{
526
526
}
527
527
 
528
528
static void determine_scan_completeness(
529
 
    freecell_solver_soft_thread_t * soft_thread,
 
529
    fc_solve_soft_thread_t * soft_thread,
530
530
    void * context
531
531
    )
532
532
{
548
548
};
549
549
 
550
550
static int compile_prelude(
551
 
    freecell_solver_hard_thread_t * hard_thread
 
551
    fc_solve_hard_thread_t * hard_thread
552
552
    )
553
553
{
554
554
    char * p_quota, * p_scan, * p;
620
620
}
621
621
 
622
622
 
623
 
void freecell_solver_init_instance(freecell_solver_instance_t * instance)
 
623
void fc_solve_init_instance(fc_solve_instance_t * instance)
624
624
{
625
625
    int ht_idx;
626
 
    freecell_solver_hard_thread_t * hard_thread;
 
626
    fc_solve_hard_thread_t * hard_thread;
627
627
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INDIRECT)
628
628
    instance->num_prev_states_margin = 0;
629
629
 
642
642
        }
643
643
        hard_thread->num_times_left_for_soft_thread =
644
644
            hard_thread->soft_threads[0]->num_times_step;
645
 
        freecell_solver_state_ia_init(hard_thread);
 
645
        fc_solve_state_ia_init(hard_thread);
646
646
    }
647
647
 
648
648
    /* Normalize the A* Weights, so the sum of all of them would be 1. */
690
690
*/
691
691
#if defined(INDIRECT_STACK_STATES)
692
692
 
693
 
extern int freecell_solver_stack_compare_for_comparison(const void * v_s1, const void * v_s2);
 
693
extern int fc_solve_stack_compare_for_comparison(const void * v_s1, const void * v_s2);
694
694
 
695
695
#if ((FCS_STACK_STORAGE != FCS_STACK_STORAGE_GLIB_TREE) && (FCS_STACK_STORAGE != FCS_STACK_STORAGE_GLIB_HASH))
696
696
static int fcs_stack_compare_for_comparison_with_context(
703
703
 
704
704
    )
705
705
{
706
 
    return freecell_solver_stack_compare_for_comparison(v_s1, v_s2);
 
706
    return fc_solve_stack_compare_for_comparison(v_s1, v_s2);
707
707
}
708
708
#endif
709
709
 
713
713
 
714
714
#if (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_HASH)
715
715
/* A hash calculation function for use in glib's hash */
716
 
static guint freecell_solver_glib_hash_stack_hash_function (
 
716
static guint fc_solve_glib_hash_stack_hash_function (
717
717
    gconstpointer key
718
718
    )
719
719
{
736
736
 
737
737
 
738
738
 
739
 
static gint freecell_solver_glib_hash_stack_compare (
 
739
static gint fc_solve_glib_hash_stack_compare (
740
740
    gconstpointer a,
741
741
    gconstpointer b
742
742
)
760
760
 * This hash function is defined in caas.c
761
761
 *
762
762
 * */
763
 
extern guint freecell_solver_hash_function(gconstpointer key);
 
763
extern guint fc_solve_hash_function(gconstpointer key);
764
764
#endif
765
765
 
766
766
/*
768
768
 * to the initial state
769
769
 * */
770
770
static void trace_solution(
771
 
    freecell_solver_instance_t * instance
 
771
    fc_solve_instance_t * instance
772
772
    )
773
773
{
774
774
    /*
775
775
        Trace the solution.
776
776
    */
777
 
    fcs_state_with_locations_t * s1;
 
777
    fcs_state_extra_info_t * s1_val;
778
778
    fcs_move_stack_t * solution_moves;
779
779
    int move_idx;
780
780
    fcs_move_stack_t * stack;
789
789
    fcs_move_stack_alloc_into_var(solution_moves);
790
790
    instance->solution_moves = solution_moves;
791
791
 
792
 
    s1 = instance->final_state;
 
792
    s1_val = instance->final_state_val;
793
793
 
794
794
    /* Retrace the step from the current state to its parents */
795
 
    while (s1->parent != NULL)
 
795
    while (s1_val->parent_val != NULL)
796
796
    {
797
797
        /* Mark the state as part of the non-optimized solution */
798
 
        s1->visited |= FCS_VISITED_IN_SOLUTION_PATH;
 
798
        s1_val->visited |= FCS_VISITED_IN_SOLUTION_PATH;
799
799
        /* Duplicate the move stack */
800
800
        {
801
 
            stack = s1->moves_to_parent;
 
801
            stack = s1_val->moves_to_parent;
802
802
            moves = stack->moves;
803
803
            for(move_idx=stack->num_moves-1;move_idx>=0;move_idx--)
804
804
            {
808
808
        /* Duplicate the state to a freshly malloced memory */
809
809
 
810
810
        /* Move to the parent state */
811
 
        s1 = s1->parent;
 
811
        s1_val = s1_val->parent_val;
812
812
    }
813
813
    /* There's one more state than there are move stacks */
814
 
    s1->visited |= FCS_VISITED_IN_SOLUTION_PATH;
 
814
    s1_val->visited |= FCS_VISITED_IN_SOLUTION_PATH;
815
815
}
816
816
 
817
817
 
830
830
    This function optimizes the solution path using a BFS scan on the
831
831
    states in the solution path.
832
832
*/
833
 
static int freecell_solver_optimize_solution(
834
 
    freecell_solver_instance_t * instance
 
833
static int fc_solve_optimize_solution(
 
834
    fc_solve_instance_t * instance
835
835
    )
836
836
{
837
 
    freecell_solver_hard_thread_t * optimization_thread;
838
 
    freecell_solver_soft_thread_t * soft_thread;
 
837
    fc_solve_hard_thread_t * optimization_thread;
 
838
    fc_solve_soft_thread_t * soft_thread;
839
839
    
840
840
    optimization_thread = alloc_hard_thread(instance);
841
841
    instance->optimization_thread = optimization_thread;
859
859
 
860
860
    /* Initialize the optimization hard-thread and soft-thread */
861
861
    optimization_thread->num_times_left_for_soft_thread = 1000000;
862
 
    freecell_solver_state_ia_init(optimization_thread);
 
862
    fc_solve_state_ia_init(optimization_thread);
863
863
 
864
864
    /* Instruct the optimization hard thread to run indefinitely AFA it
865
865
     * is concerned */
867
867
    optimization_thread->ht_max_num_times = -1;
868
868
 
869
869
    return 
870
 
        freecell_solver_a_star_or_bfs_do_solve_or_resume(
 
870
        fc_solve_a_star_or_bfs_do_solve_or_resume(
871
871
            optimization_thread->soft_threads[0],
872
 
            instance->state_copy_ptr,
 
872
            instance->state_copy_ptr_key,
 
873
            instance->state_copy_ptr_val,
873
874
            0
874
875
            );
875
876
 
876
877
}
877
878
 
878
879
 
879
 
extern void freecell_solver_cache_talon(
880
 
    freecell_solver_instance_t * instance,
881
 
    fcs_state_with_locations_t * new_state
 
880
extern void fc_solve_cache_talon(
 
881
    fc_solve_instance_t * instance,
 
882
    fcs_state_t * new_state_key,
 
883
    fcs_state_extra_info_t * new_state_val
882
884
    );
883
885
 
884
886
/*
885
887
    This function starts the solution process _for the first time_. If one
886
888
    wishes to proceed after the iterations limit was reached, one should
887
 
    use freecell_solver_resume_instance.
 
889
    use fc_solve_resume_instance.
888
890
 
889
891
  */
890
 
int freecell_solver_solve_instance(
891
 
    freecell_solver_instance_t * instance,
892
 
    fcs_state_with_locations_t * init_state
 
892
int fc_solve_solve_instance(
 
893
    fc_solve_instance_t * instance,
 
894
    fcs_state_t * init_state_key,
 
895
    fcs_state_extra_info_t * init_state_val
893
896
    )
894
897
{
895
 
    fcs_state_with_locations_t * state_copy_ptr;
 
898
    fcs_state_t * state_copy_ptr_key;
 
899
    fcs_state_extra_info_t * state_copy_ptr_val;
896
900
 
897
901
    /* Allocate the first state and initialize it to init_state */
898
 
    fcs_state_ia_alloc_into_var(state_copy_ptr, instance->hard_threads[0]);
 
902
    fcs_state_ia_alloc_into_var(
 
903
            state_copy_ptr_key, state_copy_ptr_val,
 
904
            instance->hard_threads[0]
 
905
            );
899
906
 
900
 
    fcs_duplicate_state(*state_copy_ptr, *init_state);
 
907
    fcs_duplicate_state(*state_copy_ptr_key, *state_copy_ptr_val, 
 
908
            *init_state_key, *init_state_val
 
909
            );
901
910
 
902
911
    {
903
912
        int a;
904
913
        for(a=0;a<instance->stacks_num;a++)
905
914
        {
906
 
            fcs_copy_stack(*state_copy_ptr, a, instance->hard_threads[0]->indirect_stacks_buffer);
 
915
            fcs_copy_stack(*state_copy_ptr_key, *state_copy_ptr_val, a, instance->hard_threads[0]->indirect_stacks_buffer);
907
916
        }
908
917
    }
909
918
 
910
919
    /* Initialize the state to be a base state for the game tree */
911
 
    state_copy_ptr->depth = 0;
912
 
    state_copy_ptr->moves_to_parent = NULL;
913
 
    state_copy_ptr->visited = 0;
914
 
    state_copy_ptr->parent = NULL;
915
 
    memset(&(state_copy_ptr->scan_visited), '\0', sizeof(state_copy_ptr->scan_visited));
 
920
    state_copy_ptr_val->depth = 0;
 
921
    state_copy_ptr_val->moves_to_parent = NULL;
 
922
    state_copy_ptr_val->visited = 0;
 
923
    state_copy_ptr_val->parent_key = NULL;
 
924
    state_copy_ptr_val->parent_val = NULL;
 
925
    memset(&(state_copy_ptr_val->scan_visited), '\0', sizeof(state_copy_ptr_val->scan_visited));
916
926
 
917
 
    instance->state_copy_ptr = state_copy_ptr;
 
927
    instance->state_copy_ptr_key = state_copy_ptr_key;
 
928
    instance->state_copy_ptr_val = state_copy_ptr_val;
918
929
 
919
930
    /* Initialize the data structure that will manage the state collection */
920
931
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBREDBLACK_TREE)
921
 
    instance->tree = rbinit(freecell_solver_state_compare_with_context, NULL);
 
932
    instance->tree = rbinit(fc_solve_state_compare_with_context, NULL);
922
933
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBAVL_AVL_TREE)
923
 
    instance->tree = avl_create(freecell_solver_state_compare_with_context, NULL);
 
934
    instance->tree = avl_create(fc_solve_state_compare_with_context, NULL);
924
935
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBAVL_REDBLACK_TREE)
925
 
    instance->tree = rb_create(freecell_solver_state_compare_with_context, NULL);
 
936
    instance->tree = rb_create(fc_solve_state_compare_with_context, NULL);
926
937
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GLIB_TREE)
927
 
    instance->tree = g_tree_new(freecell_solver_state_compare);
 
938
    instance->tree = g_tree_new(fc_solve_state_compare);
928
939
#endif
929
940
 
930
941
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GLIB_HASH)
931
942
    instance->hash = g_hash_table_new(
932
 
        freecell_solver_hash_function,
933
 
        freecell_solver_state_compare_equal
 
943
        fc_solve_hash_function,
 
944
        fc_solve_state_compare_equal
934
945
        );
935
946
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INTERNAL_HASH)
936
 
    instance->hash = freecell_solver_hash_init(
 
947
    instance->hash = fc_solve_hash_init(
937
948
            2048,
938
 
            freecell_solver_state_compare_with_context,
 
949
            fc_solve_state_compare_with_context,
939
950
            NULL
940
951
       );
941
952
#endif
946
957
    /* Initialize the data structure that will manage the stack
947
958
       collection */
948
959
#if FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH
949
 
    instance->stacks_hash = freecell_solver_hash_init(
 
960
    instance->stacks_hash = fc_solve_hash_init(
950
961
            2048,
951
962
            fcs_stack_compare_for_comparison_with_context,
952
963
            NULL
970
981
    instance->stacks_tree = g_tree_new(fcs_stack_compare_for_comparison);
971
982
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_HASH)
972
983
    instance->stacks_hash = g_hash_table_new(
973
 
        freecell_solver_glib_hash_stack_hash_function,
974
 
        freecell_solver_glib_hash_stack_compare
 
984
        fc_solve_glib_hash_stack_hash_function,
 
985
        fc_solve_glib_hash_stack_compare
975
986
        );
976
987
#endif
977
988
#endif
982
993
    /* Initialize the Talon's Cache */
983
994
    if (instance->talon_type == FCS_TALON_KLONDIKE)
984
995
    {
985
 
        instance->talons_hash = freecell_solver_hash_init(
 
996
        instance->talons_hash = fc_solve_hash_init(
986
997
            512,
987
998
            fcs_talon_compare_with_context,
988
999
            NULL
989
1000
            );
990
1001
 
991
 
        freecell_solver_cache_talon(instance, instance->state_copy_ptr);
 
1002
        fc_solve_cache_talon(instance, instance->state_copy_ptr);
992
1003
    }
993
1004
#endif
994
1005
 
1006
1017
#endif
1007
1018
 
1008
1019
    {
1009
 
        fcs_state_with_locations_t * no_use;
 
1020
        fcs_state_t * no_use_key;
 
1021
        fcs_state_extra_info_t * no_use_val;
1010
1022
 
1011
 
        freecell_solver_check_and_add_state(
 
1023
        fc_solve_check_and_add_state(
1012
1024
            instance->hard_threads[0]->soft_threads[0],
1013
 
            state_copy_ptr,
1014
 
            &no_use
 
1025
            state_copy_ptr_key,
 
1026
            state_copy_ptr_val,
 
1027
            &no_use_key,
 
1028
            &no_use_val
1015
1029
            );
1016
1030
 
1017
1031
    }
1021
1035
        int ht_idx;
1022
1036
        for(ht_idx=0; ht_idx < instance->num_hard_threads ; ht_idx++)
1023
1037
        {
1024
 
            freecell_solver_hard_thread_t * hard_thread;
 
1038
            fc_solve_hard_thread_t * hard_thread;
1025
1039
            hard_thread = instance->hard_threads[ht_idx];
1026
1040
            
1027
1041
            if (hard_thread->prelude != NULL)
1038
1052
        }
1039
1053
    }
1040
1054
 
1041
 
    return freecell_solver_resume_instance(instance);
 
1055
    return fc_solve_resume_instance(instance);
1042
1056
}
1043
1057
 
1044
1058
 
1045
 
static int run_hard_thread(freecell_solver_hard_thread_t * hard_thread)
 
1059
static int run_hard_thread(fc_solve_hard_thread_t * hard_thread)
1046
1060
{
1047
 
    freecell_solver_soft_thread_t * soft_thread;
 
1061
    fc_solve_soft_thread_t * soft_thread;
1048
1062
    int num_times_started_at;
1049
1063
    int ret;
1050
 
    freecell_solver_instance_t * instance = hard_thread->instance;
 
1064
    fc_solve_instance_t * instance = hard_thread->instance;
1051
1065
    /* 
1052
1066
     * Again, making sure that not all of the soft_threads in this 
1053
1067
     * hard thread are finished.
1124
1138
                
1125
1139
            if (! soft_thread->initialized)
1126
1140
            {
1127
 
                ret = freecell_solver_hard_dfs_solve_for_state(
 
1141
                ret = fc_solve_hard_dfs_solve_for_state(
1128
1142
                    soft_thread,
1129
 
                    instance->state_copy_ptr,
 
1143
                    instance->state_copy_ptr_key,
 
1144
                    instance->state_copy_ptr_val,
1130
1145
                    0,
1131
1146
                    0);
1132
1147
 
1134
1149
            }
1135
1150
            else
1136
1151
            {
1137
 
                ret = freecell_solver_hard_dfs_resume_solution(soft_thread, 0);
 
1152
                ret = fc_solve_hard_dfs_resume_solution(soft_thread, 0);
1138
1153
            }
1139
1154
            break;
1140
1155
 
1143
1158
            if (! soft_thread->initialized)
1144
1159
            {
1145
1160
                ret = 
1146
 
                    freecell_solver_soft_dfs_or_random_dfs_do_solve_or_resume(
 
1161
                    fc_solve_soft_dfs_or_random_dfs_do_solve_or_resume(
1147
1162
                        soft_thread,
1148
 
                        instance->state_copy_ptr,
 
1163
                        instance->state_copy_ptr_key,
 
1164
                        instance->state_copy_ptr_val,
1149
1165
                        0,
1150
1166
                        0
1151
1167
                        );
1154
1170
            else
1155
1171
            {
1156
1172
                ret = 
1157
 
                    freecell_solver_soft_dfs_or_random_dfs_do_solve_or_resume(
 
1173
                    fc_solve_soft_dfs_or_random_dfs_do_solve_or_resume(
1158
1174
                        soft_thread,
1159
1175
                        NULL,
 
1176
                        NULL,
1160
1177
                        1,
1161
1178
                        0
1162
1179
                        );
1168
1185
            if (! soft_thread->initialized)
1169
1186
            {
1170
1187
                ret = 
1171
 
                    freecell_solver_soft_dfs_or_random_dfs_do_solve_or_resume(
 
1188
                    fc_solve_soft_dfs_or_random_dfs_do_solve_or_resume(
1172
1189
                        soft_thread,
1173
 
                        instance->state_copy_ptr,
 
1190
                        instance->state_copy_ptr_key,
 
1191
                        instance->state_copy_ptr_val,
1174
1192
                        0,
1175
1193
                        1
1176
1194
                        );
1180
1198
            else
1181
1199
            {
1182
1200
                ret = 
1183
 
                    freecell_solver_soft_dfs_or_random_dfs_do_solve_or_resume(
 
1201
                    fc_solve_soft_dfs_or_random_dfs_do_solve_or_resume(
1184
1202
                        soft_thread,
1185
1203
                        NULL,
 
1204
                        NULL,
1186
1205
                        1,
1187
1206
                        1
1188
1207
                        );
1196
1215
            {
1197
1216
                if (soft_thread->method == FCS_METHOD_A_STAR)
1198
1217
                {
1199
 
                    freecell_solver_a_star_initialize_rater(
 
1218
                    fc_solve_a_star_initialize_rater(
1200
1219
                        soft_thread,
1201
 
                        instance->state_copy_ptr
 
1220
                        instance->state_copy_ptr_key,
 
1221
                        instance->state_copy_ptr_val
1202
1222
                        );
1203
1223
                }
1204
1224
 
1205
 
                ret = freecell_solver_a_star_or_bfs_do_solve_or_resume(
 
1225
                ret = fc_solve_a_star_or_bfs_do_solve_or_resume(
1206
1226
                    soft_thread,
1207
 
                    instance->state_copy_ptr,
 
1227
                    instance->state_copy_ptr_key,
 
1228
                    instance->state_copy_ptr_val,
1208
1229
                    0
1209
1230
                );
1210
1231
 
1213
1234
            else
1214
1235
            {
1215
1236
                ret =
1216
 
                    freecell_solver_a_star_or_bfs_do_solve_or_resume(
 
1237
                    fc_solve_a_star_or_bfs_do_solve_or_resume(
1217
1238
                        soft_thread,
1218
 
                        soft_thread->first_state_to_check,
 
1239
                        soft_thread->first_state_to_check_key,
 
1240
                        soft_thread->first_state_to_check_val,
1219
1241
                        1
1220
1242
                        );
1221
1243
            }
1311
1333
 
1312
1334
 
1313
1335
/* Resume a solution process that was stopped in the middle */
1314
 
int freecell_solver_resume_instance(
1315
 
    freecell_solver_instance_t * instance
 
1336
int fc_solve_resume_instance(
 
1337
    fc_solve_instance_t * instance
1316
1338
    )
1317
1339
{
1318
1340
    int ret = FCS_STATE_SUSPEND_PROCESS;
1319
 
    freecell_solver_hard_thread_t * hard_thread;
 
1341
    fc_solve_hard_thread_t * hard_thread;
1320
1342
 
1321
1343
    /*
1322
1344
     * If the optimization thread is defined, it means we are in the 
1328
1350
    if (instance->optimization_thread)
1329
1351
    {
1330
1352
        ret =
1331
 
            freecell_solver_a_star_or_bfs_do_solve_or_resume(
 
1353
            fc_solve_a_star_or_bfs_do_solve_or_resume(
1332
1354
                instance->optimization_thread->soft_threads[0],
1333
 
                instance->optimization_thread->soft_threads[0]->first_state_to_check,
 
1355
                instance->optimization_thread->soft_threads[0]->first_state_to_check_key,
 
1356
                instance->optimization_thread->soft_threads[0]->first_state_to_check_val,
1334
1357
                1
1335
1358
                );
1336
1359
    }
1417
1440
             * it has already run - we retain the old ret. */
1418
1441
            if (! instance->optimization_thread)
1419
1442
            {
1420
 
                ret = freecell_solver_optimize_solution(instance);
 
1443
                ret = fc_solve_optimize_solution(instance);
1421
1444
            }
1422
1445
            if (ret == FCS_STATE_WAS_SOLVED)
1423
1446
            {
1437
1460
    This function does not substitute for later calling
1438
1461
    finish_instance() and free_instance().
1439
1462
  */
1440
 
void freecell_solver_unresume_instance(
1441
 
    freecell_solver_instance_t * instance
 
1463
void fc_solve_unresume_instance(
 
1464
    fc_solve_instance_t * instance
1442
1465
    )
1443
1466
{
1444
1467
    /*
1452
1475
 
1453
1476
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBAVL_AVL_TREE) || (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBAVL_REDBLACK_TREE)
1454
1477
 
1455
 
static void freecell_solver_tree_do_nothing(void * data, void * context)
 
1478
static void fc_solve_tree_do_nothing(void * data, void * context)
1456
1479
{
1457
1480
}
1458
1481
 
1465
1488
#ifdef INDIRECT_STACK_STATES
1466
1489
#if (FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH) || (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_AVL_TREE) || (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_REDBLACK_TREE)
1467
1490
#if 0
1468
 
static void freecell_solver_stack_free(void * key, void * context)
 
1491
static void fc_solve_stack_free(void * key, void * context)
1469
1492
{
1470
1493
    free(key);
1471
1494
}
1472
1495
#endif
1473
1496
 
1474
1497
#elif FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBREDBLACK_TREE
1475
 
static void freecell_solver_libredblack_walk_destroy_stack_action
 
1498
static void fc_solve_libredblack_walk_destroy_stack_action
1476
1499
(
1477
1500
    const void * nodep,
1478
1501
    const VISIT which,
1486
1509
    }
1487
1510
}
1488
1511
#elif FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_TREE
1489
 
static gint freecell_solver_glib_tree_walk_destroy_stack_action
 
1512
static gint fc_solve_glib_tree_walk_destroy_stack_action
1490
1513
(
1491
1514
    gpointer key,
1492
1515
    gpointer value,
1499
1522
}
1500
1523
 
1501
1524
#elif FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_HASH
1502
 
static void freecell_solver_glib_hash_foreach_destroy_stack_action
 
1525
static void fc_solve_glib_hash_foreach_destroy_stack_action
1503
1526
(
1504
1527
    gpointer key,
1505
1528
    gpointer value,
1517
1540
 
1518
1541
 
1519
1542
 
1520
 
void freecell_solver_destroy_move_stack_of_state(
1521
 
        fcs_state_with_locations_t * ptr_state_with_locations,
 
1543
void fc_solve_destroy_move_stack_of_state(
 
1544
        fcs_state_t * ptr_state_key,
 
1545
        fcs_state_extra_info_t * ptr_state_val,
1522
1546
        void * context
1523
1547
        )
1524
1548
{
1525
 
    if (ptr_state_with_locations->moves_to_parent != NULL)
 
1549
    if (ptr_state_val->moves_to_parent != NULL)
1526
1550
    {
1527
 
        fcs_move_stack_destroy(ptr_state_with_locations->moves_to_parent);
 
1551
        fcs_move_stack_destroy(ptr_state_val->moves_to_parent);
1528
1552
    }
1529
1553
}
1530
1554
 
1532
1556
    This function should be called after the user has retrieved the
1533
1557
    results generated by the scan as it will destroy them.
1534
1558
  */
1535
 
void freecell_solver_finish_instance(
1536
 
    freecell_solver_instance_t * instance
 
1559
void fc_solve_finish_instance(
 
1560
    fc_solve_instance_t * instance
1537
1561
    )
1538
1562
{
1539
1563
    int ht_idx;
1540
 
    freecell_solver_hard_thread_t * hard_thread;
 
1564
    fc_solve_hard_thread_t * hard_thread;
1541
1565
 
1542
1566
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INDIRECT)
1543
1567
    free(instance->indirect_prev_states);
1547
1571
    for(ht_idx=0;ht_idx<instance->num_hard_threads;ht_idx++)
1548
1572
    {
1549
1573
        hard_thread = instance->hard_threads[ht_idx];
1550
 
        freecell_solver_state_ia_finish(hard_thread);
 
1574
        fc_solve_state_ia_finish(hard_thread);
1551
1575
 
1552
1576
#ifdef INDIRECT_STACK_STATES
1553
 
        freecell_solver_compact_allocator_finish(hard_thread->stacks_allocator);
 
1577
        fc_solve_compact_allocator_finish(hard_thread->stacks_allocator);
1554
1578
        hard_thread->stacks_allocator = NULL;
1555
1579
#endif
1556
 
        freecell_solver_compact_allocator_finish(hard_thread->move_stacks_allocator);
 
1580
        fc_solve_compact_allocator_finish(hard_thread->move_stacks_allocator);
1557
1581
        hard_thread->move_stacks_allocator = NULL;
1558
1582
        
1559
1583
    }
1560
1584
 
1561
1585
    if (instance->optimization_thread)
1562
1586
    {
1563
 
        freecell_solver_state_ia_finish(instance->optimization_thread);
 
1587
        fc_solve_state_ia_finish(instance->optimization_thread);
1564
1588
    }
1565
1589
 
1566
1590
 
1568
1592
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBREDBLACK_TREE)
1569
1593
    rbdestroy(instance->tree);
1570
1594
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBAVL_AVL_TREE)
1571
 
    avl_destroy(instance->tree, freecell_solver_tree_do_nothing);
 
1595
    avl_destroy(instance->tree, fc_solve_tree_do_nothing);
1572
1596
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBAVL_REDBLACK_TREE)
1573
 
    rb_destroy(instance->tree, freecell_solver_tree_do_nothing);
 
1597
    rb_destroy(instance->tree, fc_solve_tree_do_nothing);
1574
1598
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GLIB_TREE)
1575
1599
    g_tree_destroy(instance->tree);
1576
1600
#endif
1578
1602
#if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GLIB_HASH)
1579
1603
    g_hash_table_destroy(instance->hash);
1580
1604
#elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INTERNAL_HASH)
1581
 
    freecell_solver_hash_free(instance->hash);
 
1605
    fc_solve_hash_free(instance->hash);
1582
1606
#endif
1583
1607
 
1584
1608
 
1588
1612
#ifdef INDIRECT_STACK_STATES
1589
1613
#if FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH
1590
1614
#if 0
1591
 
    freecell_solver_hash_free_with_callback(instance->stacks_hash, freecell_solver_stack_free);
 
1615
    fc_solve_hash_free_with_callback(instance->stacks_hash, fc_solve_stack_free);
1592
1616
#else
1593
 
    freecell_solver_hash_free(instance->stacks_hash);
 
1617
    fc_solve_hash_free(instance->stacks_hash);
1594
1618
#endif
1595
1619
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_AVL_TREE)
1596
1620
#if 0
1597
 
    avl_destroy(instance->stacks_tree, freecell_solver_stack_free);
 
1621
    avl_destroy(instance->stacks_tree, fc_solve_stack_free);
1598
1622
#else
1599
1623
    avl_destroy(instance->stacks_tree, NULL);
1600
1624
#endif
1601
1625
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_REDBLACK_TREE)
1602
1626
#if 0
1603
 
    rb_destroy(instance->stacks_tree, freecell_solver_stack_free);
 
1627
    rb_destroy(instance->stacks_tree, fc_solve_stack_free);
1604
1628
#else
1605
1629
    rb_destroy(instance->stacks_tree, NULL);
1606
1630
#endif
1607
1631
#elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBREDBLACK_TREE)
1608
1632
#if 0
1609
1633
    rbwalk(instance->stacks_tree,
1610
 
        freecell_solver_libredblack_walk_destroy_stack_action,
 
1634
        fc_solve_libredblack_walk_destroy_stack_action,
1611
1635
        NULL
1612
1636
        );
1613
1637
#endif
1616
1640
#if 0
1617
1641
    g_tree_traverse(
1618
1642
        instance->stacks_tree,
1619
 
        freecell_solver_glib_tree_walk_destroy_stack_action,
 
1643
        fc_solve_glib_tree_walk_destroy_stack_action,
1620
1644
        G_IN_ORDER,
1621
1645
        NULL
1622
1646
        );
1626
1650
#if 0
1627
1651
    g_hash_table_foreach(
1628
1652
        instance->stacks_hash,
1629
 
        freecell_solver_glib_hash_foreach_destroy_stack_action,
 
1653
        fc_solve_glib_hash_foreach_destroy_stack_action,
1630
1654
        NULL
1631
1655
        );
1632
1656
#endif
1642
1666
    clean_soft_dfs(instance);    
1643
1667
}
1644
1668
 
1645
 
freecell_solver_soft_thread_t * freecell_solver_instance_get_soft_thread(
1646
 
        freecell_solver_instance_t * instance,
 
1669
fc_solve_soft_thread_t * fc_solve_instance_get_soft_thread(
 
1670
        fc_solve_instance_t * instance,
1647
1671
        int ht_idx,
1648
1672
        int st_idx
1649
1673
        )
1654
1678
    }
1655
1679
    else
1656
1680
    {
1657
 
        freecell_solver_hard_thread_t * hard_thread;
 
1681
        fc_solve_hard_thread_t * hard_thread;
1658
1682
        hard_thread = instance->hard_threads[ht_idx];
1659
1683
        if (st_idx >= hard_thread->num_soft_threads)
1660
1684
        {
1667
1691
    }
1668
1692
}
1669
1693
 
1670
 
freecell_solver_soft_thread_t * freecell_solver_new_soft_thread(
1671
 
    freecell_solver_soft_thread_t * soft_thread
 
1694
fc_solve_soft_thread_t * fc_solve_new_soft_thread(
 
1695
    fc_solve_soft_thread_t * soft_thread
1672
1696
    )
1673
1697
{
1674
 
    freecell_solver_soft_thread_t * ret;
1675
 
    freecell_solver_hard_thread_t * hard_thread;
 
1698
    fc_solve_soft_thread_t * ret;
 
1699
    fc_solve_hard_thread_t * hard_thread;
1676
1700
 
1677
1701
    hard_thread = soft_thread->hard_thread;
1678
1702
    ret = alloc_soft_thread(hard_thread);
1690
1714
    return ret;
1691
1715
}
1692
1716
 
1693
 
freecell_solver_soft_thread_t * freecell_solver_new_hard_thread(
1694
 
    freecell_solver_instance_t * instance
 
1717
fc_solve_soft_thread_t * fc_solve_new_hard_thread(
 
1718
    fc_solve_instance_t * instance
1695
1719
    )
1696
1720
{
1697
 
    freecell_solver_hard_thread_t * ret;
 
1721
    fc_solve_hard_thread_t * ret;
1698
1722
 
1699
1723
    /* Exceeded the maximal number of Soft-Threads in an instance */
1700
1724
    ret = alloc_hard_thread(instance);
1717
1741
    return ret->soft_threads[0];
1718
1742
}
1719
1743
 
1720
 
void freecell_solver_recycle_instance(
1721
 
    freecell_solver_instance_t * instance
 
1744
void fc_solve_recycle_instance(
 
1745
    fc_solve_instance_t * instance
1722
1746
        )
1723
1747
{
1724
1748
    int ht_idx, st_idx;
1725
 
    freecell_solver_hard_thread_t * hard_thread;
1726
 
    freecell_solver_soft_thread_t * soft_thread;
 
1749
    fc_solve_hard_thread_t * hard_thread;
 
1750
    fc_solve_soft_thread_t * soft_thread;
1727
1751
    
1728
 
    freecell_solver_finish_instance(instance);
 
1752
    fc_solve_finish_instance(instance);
1729
1753
 
1730
1754
    instance->num_times = 0;
1731
1755
 
1739
1763
        hard_thread->max_num_times = -1;
1740
1764
        hard_thread->num_soft_threads_finished = 0;
1741
1765
        hard_thread->move_stacks_allocator =
1742
 
            freecell_solver_compact_allocator_new();
 
1766
            fc_solve_compact_allocator_new();
1743
1767
#ifdef INDIRECT_STACK_STATES
1744
1768
        hard_thread->stacks_allocator = 
1745
 
            freecell_solver_compact_allocator_new();
 
1769
            fc_solve_compact_allocator_new();
1746
1770
#endif
1747
1771
        for(st_idx = 0; st_idx < hard_thread->num_soft_threads ; st_idx++)
1748
1772
        {
1750
1774
            soft_thread->is_finished = 0;
1751
1775
            soft_thread->initialized = 0;
1752
1776
 
1753
 
            freecell_solver_rand_srand(soft_thread->rand_gen, soft_thread->rand_seed);
 
1777
            fc_solve_rand_srand(soft_thread->rand_gen, soft_thread->rand_seed);
1754
1778
            /* Reset the priority queue */
1755
1779
            soft_thread->a_star_pqueue->CurrentSize = 0;
1756
1780
        }