814
815
int state_freecells_num;
815
816
int state_stacks_num;
816
817
int sequences_are_built_by;
818
char * positions_by_rank;
819
int positions_by_rank_size;
820
char * pos_idx_to_check;
818
823
fcs_move_t temp_move;
820
825
tests_define_accessors();
827
decks_num = instance->decks_num;
822
828
state_freecells_num = instance->freecells_num;
823
829
state_stacks_num = instance->stacks_num;
824
830
sequences_are_built_by = instance->sequences_are_built_by;
832
/* We need 2 chars per card - one for the stack and one
835
* We also need it times 13 for each of the ranks.
837
* We need (4*decks_num+1) slots to hold the cards plus a
838
* (-1,-1) (= end) padding.
840
positions_by_rank_size =
841
(sizeof(positions_by_rank[0]) * 2 * 13) *
842
((decks_num << 2) + 1)
845
positions_by_rank = malloc(positions_by_rank_size);
847
memset(positions_by_rank, -1, positions_by_rank_size);
850
char * positions_by_rank_slots[13];
852
/* Initialize the pointers to the first available slots */
855
positions_by_rank_slots[c] = &positions_by_rank[
856
(((decks_num << 2)+1) << 1) * c
860
/* Populate positions_by_rank by looping over the stacks and indices
861
* looking for the cards and filling them. */
863
for(ds=0;ds<state_stacks_num;ds++)
865
dest_cards_num = fcs_stack_len(state, ds);
866
for(dc=0;dc<dest_cards_num;dc++)
868
dest_card = fcs_stack_card(state, ds, dc);
870
if (dest_cards_num - 1 > dc)
872
dest_below_card = fcs_stack_card(state, ds, dc+1);
873
if (fcs_is_parent_card(dest_below_card, dest_card))
880
*(positions_by_rank_slots[fcs_card_card_num(dest_card)-1]++) = ds;
881
*(positions_by_rank_slots[fcs_card_card_num(dest_card)-1]++) = dc;
826
887
/* Now let's try to move a card from one stack to the other *
827
888
* Note that it does not involve moving cards lower than king *
828
889
* to empty stacks */
853
914
card = fcs_stack_card(state, stack, c);
855
916
/* Make sure the card is not flipped or else we can't move it */
856
if (fcs_card_get_flipped(card) == 0)
858
for(ds=0 ; ds<state_stacks_num; ds++)
862
dest_cards_num = fcs_stack_len(state, ds);
863
for(dc=0;dc<dest_cards_num;dc++)
865
dest_card = fcs_stack_card(state, ds, dc);
867
if (fcs_is_parent_card(card, dest_card))
869
/* Corresponding cards - see if it is feasible to move
870
the source to the destination. */
873
if (dest_cards_num - 1 > dc)
875
dest_below_card = fcs_stack_card(state, ds, dc+1);
876
if (fcs_is_parent_card(dest_below_card, dest_card))
882
if (! is_seq_in_dest)
884
num_cards_to_relocate = dest_cards_num - dc - 1 + cards_num - seq_end - 1;
886
freecells_to_fill = min(num_cards_to_relocate, num_freecells);
888
num_cards_to_relocate -= freecells_to_fill;
890
if (instance->empty_stacks_fill == FCS_ES_FILLED_BY_ANY_CARD)
892
freestacks_to_fill = min(num_cards_to_relocate, num_freestacks);
894
num_cards_to_relocate -= freestacks_to_fill;
898
freestacks_to_fill = 0;
901
if ((num_cards_to_relocate == 0) &&
902
(calc_max_sequence_move(num_freecells-freecells_to_fill, num_freestacks-freestacks_to_fill) >=
906
int from_which_stack;
908
sfs_check_state_begin()
911
/* Fill the freecells with the top cards */
913
my_copy_stack(stack);
916
for(a=0 ; a<freecells_to_fill ; a++)
918
/* Find a vacant freecell */
919
for(b=0;b<state_freecells_num;b++)
921
if (fcs_freecell_card_num(new_state, b) == 0)
927
if (fcs_stack_len(new_state, ds) == dc+1)
929
from_which_stack = stack;
933
from_which_stack = ds;
935
my_copy_stack(from_which_stack);
937
fcs_pop_stack_card(new_state, from_which_stack, temp_card);
939
fcs_put_card_in_freecell(new_state, b, temp_card);
941
fcs_move_set_type(temp_move,FCS_MOVE_TYPE_STACK_TO_FREECELL);
942
fcs_move_set_src_stack(temp_move,from_which_stack);
943
fcs_move_set_dest_freecell(temp_move,b);
944
fcs_move_stack_push(moves, temp_move);
946
fcs_flip_top_card(from_which_stack);
949
/* Fill the free stacks with the cards below them */
950
for(a=0; a < freestacks_to_fill ; a++)
952
/* Find a vacant stack */
953
for(b=0;b<state_stacks_num;b++)
955
if (fcs_stack_len(new_state, b) == 0)
961
if (fcs_stack_len(new_state, ds) == dc+1)
963
from_which_stack = stack;
967
from_which_stack = ds;
971
fcs_pop_stack_card(new_state, from_which_stack, temp_card);
972
fcs_push_card_into_stack(new_state, b, temp_card);
973
fcs_move_set_type(temp_move,FCS_MOVE_TYPE_STACK_TO_STACK);
974
fcs_move_set_src_stack(temp_move,from_which_stack);
975
fcs_move_set_dest_stack(temp_move,b);
976
fcs_move_set_num_cards_in_seq(temp_move,1);
977
fcs_move_stack_push(moves, temp_move);
979
fcs_flip_top_card(from_which_stack);
982
for(a=c ; a <= seq_end ; a++)
984
fcs_push_stack_card_into_stack(new_state, ds, stack, a);
987
for(a=0; a < seq_end-c+1 ;a++)
989
fcs_pop_stack_card(new_state, stack, temp_card);
991
fcs_move_set_type(temp_move,FCS_MOVE_TYPE_STACK_TO_STACK);
992
fcs_move_set_src_stack(temp_move,stack);
993
fcs_move_set_dest_stack(temp_move,ds);
994
fcs_move_set_num_cards_in_seq(temp_move,seq_end-c+1);
995
fcs_move_stack_push(moves, temp_move);
997
fcs_flip_top_card(stack);
999
sfs_check_state_end()
917
if (fcs_card_get_flipped(card))
922
/* Skip if it's a King - nothing to put it on. */
923
if (fcs_card_card_num(card) == 13)
928
for(pos_idx_to_check = &positions_by_rank[
929
(((decks_num << 2)+1) << 1) * (fcs_card_card_num(card))
932
((*pos_idx_to_check) >= 0)
936
ds = *(pos_idx_to_check)++;
937
dc = *(pos_idx_to_check)++;
943
dest_cards_num = fcs_stack_len(state, ds);
944
dest_card = fcs_stack_card(state, ds, dc);
946
if (! fcs_is_parent_card(card, dest_card))
951
num_cards_to_relocate = dest_cards_num - dc - 1 + cards_num - seq_end - 1;
953
freecells_to_fill = min(num_cards_to_relocate, num_freecells);
955
num_cards_to_relocate -= freecells_to_fill;
957
if (instance->empty_stacks_fill == FCS_ES_FILLED_BY_ANY_CARD)
959
freestacks_to_fill = min(num_cards_to_relocate, num_freestacks);
961
num_cards_to_relocate -= freestacks_to_fill;
965
freestacks_to_fill = 0;
968
if ((num_cards_to_relocate == 0) &&
969
(calc_max_sequence_move(num_freecells-freecells_to_fill, num_freestacks-freestacks_to_fill) >=
973
int from_which_stack;
975
sfs_check_state_begin()
978
/* Fill the freecells with the top cards */
980
my_copy_stack(stack);
983
for(a=0 ; a<freecells_to_fill ; a++)
985
/* Find a vacant freecell */
986
for(b=0;b<state_freecells_num;b++)
988
if (fcs_freecell_card_num(new_state, b) == 0)
994
if (fcs_stack_len(new_state, ds) == dc+1)
996
from_which_stack = stack;
1000
from_which_stack = ds;
1002
my_copy_stack(from_which_stack);
1004
fcs_pop_stack_card(new_state, from_which_stack, temp_card);
1006
fcs_put_card_in_freecell(new_state, b, temp_card);
1008
fcs_move_set_type(temp_move,FCS_MOVE_TYPE_STACK_TO_FREECELL);
1009
fcs_move_set_src_stack(temp_move,from_which_stack);
1010
fcs_move_set_dest_freecell(temp_move,b);
1011
fcs_move_stack_push(moves, temp_move);
1013
fcs_flip_top_card(from_which_stack);
1016
/* Fill the free stacks with the cards below them */
1017
for(a=0; a < freestacks_to_fill ; a++)
1019
/* Find a vacant stack */
1020
for(b=0;b<state_stacks_num;b++)
1022
if (fcs_stack_len(new_state, b) == 0)
1028
if (fcs_stack_len(new_state, ds) == dc+1)
1030
from_which_stack = stack;
1034
from_which_stack = ds;
1038
fcs_pop_stack_card(new_state, from_which_stack, temp_card);
1039
fcs_push_card_into_stack(new_state, b, temp_card);
1040
fcs_move_set_type(temp_move,FCS_MOVE_TYPE_STACK_TO_STACK);
1041
fcs_move_set_src_stack(temp_move,from_which_stack);
1042
fcs_move_set_dest_stack(temp_move,b);
1043
fcs_move_set_num_cards_in_seq(temp_move,1);
1044
fcs_move_stack_push(moves, temp_move);
1046
fcs_flip_top_card(from_which_stack);
1049
for(a=c ; a <= seq_end ; a++)
1051
fcs_push_stack_card_into_stack(new_state, ds, stack, a);
1054
for(a=0; a < seq_end-c+1 ;a++)
1056
fcs_pop_stack_card(new_state, stack, temp_card);
1058
fcs_move_set_type(temp_move,FCS_MOVE_TYPE_STACK_TO_STACK);
1059
fcs_move_set_src_stack(temp_move,stack);
1060
fcs_move_set_dest_stack(temp_move,ds);
1061
fcs_move_set_num_cards_in_seq(temp_move,seq_end-c+1);
1062
fcs_move_stack_push(moves, temp_move);
1064
fcs_flip_top_card(stack);
1066
sfs_check_state_end()
1072
free (positions_by_rank);
1010
1074
return FCS_STATE_IS_NOT_SOLVEABLE;
1015
int freecell_solver_sfs_move_sequences_to_free_stacks(
1016
freecell_solver_soft_thread_t * soft_thread,
1017
fcs_state_with_locations_t * ptr_state_with_locations,
1079
int fc_solve_sfs_move_sequences_to_free_stacks(
1080
fc_solve_soft_thread_t * soft_thread,
1081
fcs_state_t * ptr_state_key,
1082
fcs_state_extra_info_t * ptr_state_val,
1018
1083
int num_freestacks,
1019
1084
int num_freecells,
1020
1085
fcs_derived_states_list_t * derived_states_list,
2380
2458
#undef new_state
2383
freecell_solver_solve_for_state_test_t freecell_solver_sfs_tests[FCS_TESTS_NUM] =
2461
fc_solve_solve_for_state_test_t fc_solve_sfs_tests[FCS_TESTS_NUM] =
2385
freecell_solver_sfs_move_top_stack_cards_to_founds,
2386
freecell_solver_sfs_move_freecell_cards_to_founds,
2387
freecell_solver_sfs_move_freecell_cards_on_top_of_stacks,
2388
freecell_solver_sfs_move_non_top_stack_cards_to_founds,
2389
freecell_solver_sfs_move_stack_cards_to_different_stacks,
2390
freecell_solver_sfs_move_stack_cards_to_a_parent_on_the_same_stack,
2391
freecell_solver_sfs_move_sequences_to_free_stacks,
2392
freecell_solver_sfs_move_freecell_cards_to_empty_stack,
2393
freecell_solver_sfs_move_cards_to_a_different_parent,
2394
freecell_solver_sfs_empty_stack_into_freecells,
2395
freecell_solver_sfs_simple_simon_move_sequence_to_founds,
2396
freecell_solver_sfs_simple_simon_move_sequence_to_true_parent,
2397
freecell_solver_sfs_simple_simon_move_whole_stack_sequence_to_false_parent,
2398
freecell_solver_sfs_simple_simon_move_sequence_to_true_parent_with_some_cards_above,
2399
freecell_solver_sfs_simple_simon_move_sequence_with_some_cards_above_to_true_parent,
2400
freecell_solver_sfs_simple_simon_move_sequence_with_junk_seq_above_to_true_parent_with_some_cards_above,
2401
freecell_solver_sfs_simple_simon_move_whole_stack_sequence_to_false_parent_with_some_cards_above,
2402
freecell_solver_sfs_simple_simon_move_sequence_to_parent_on_the_same_stack,
2403
freecell_solver_sfs_atomic_move_card_to_empty_stack,
2404
freecell_solver_sfs_atomic_move_card_to_parent,
2405
freecell_solver_sfs_atomic_move_card_to_freecell,
2406
freecell_solver_sfs_atomic_move_freecell_card_to_parent,
2407
freecell_solver_sfs_atomic_move_freecell_card_to_empty_stack,
2463
fc_solve_sfs_move_top_stack_cards_to_founds,
2464
fc_solve_sfs_move_freecell_cards_to_founds,
2465
fc_solve_sfs_move_freecell_cards_on_top_of_stacks,
2466
fc_solve_sfs_move_non_top_stack_cards_to_founds,
2467
fc_solve_sfs_move_stack_cards_to_different_stacks,
2468
fc_solve_sfs_move_stack_cards_to_a_parent_on_the_same_stack,
2469
fc_solve_sfs_move_sequences_to_free_stacks,
2470
fc_solve_sfs_move_freecell_cards_to_empty_stack,
2471
fc_solve_sfs_move_cards_to_a_different_parent,
2472
fc_solve_sfs_empty_stack_into_freecells,
2473
fc_solve_sfs_simple_simon_move_sequence_to_founds,
2474
fc_solve_sfs_simple_simon_move_sequence_to_true_parent,
2475
fc_solve_sfs_simple_simon_move_whole_stack_sequence_to_false_parent,
2476
fc_solve_sfs_simple_simon_move_sequence_to_true_parent_with_some_cards_above,
2477
fc_solve_sfs_simple_simon_move_sequence_with_some_cards_above_to_true_parent,
2478
fc_solve_sfs_simple_simon_move_sequence_with_junk_seq_above_to_true_parent_with_some_cards_above,
2479
fc_solve_sfs_simple_simon_move_whole_stack_sequence_to_false_parent_with_some_cards_above,
2480
fc_solve_sfs_simple_simon_move_sequence_to_parent_on_the_same_stack,
2481
fc_solve_sfs_atomic_move_card_to_empty_stack,
2482
fc_solve_sfs_atomic_move_card_to_parent,
2483
fc_solve_sfs_atomic_move_card_to_freecell,
2484
fc_solve_sfs_atomic_move_freecell_card_to_parent,
2485
fc_solve_sfs_atomic_move_freecell_card_to_empty_stack,
2409
freecell_solver_sfs_move_top_stack_cards_to_founds,
2410
freecell_solver_sfs_yukon_move_card_to_parent,
2411
freecell_solver_sfs_yukon_move_kings_to_empty_stack,
2412
freecell_solver_sfs_yukon_do_nothing,
2413
freecell_solver_sfs_yukon_do_nothing,
2487
fc_solve_sfs_move_top_stack_cards_to_founds,
2488
fc_solve_sfs_yukon_move_card_to_parent,
2489
fc_solve_sfs_yukon_move_kings_to_empty_stack,
2490
fc_solve_sfs_yukon_do_nothing,
2491
fc_solve_sfs_yukon_do_nothing,
2415
freecell_solver_sfs_yukon_do_nothing,
2416
freecell_solver_sfs_yukon_do_nothing
2493
fc_solve_sfs_yukon_do_nothing,
2494
fc_solve_sfs_yukon_do_nothing
2417
2495
#ifdef FCS_WITH_TALONS
2419
freecell_solver_sfs_deal_gypsy_talon,
2420
freecell_solver_sfs_get_card_from_klondike_talon
2497
fc_solve_sfs_deal_gypsy_talon,
2498
fc_solve_sfs_get_card_from_klondike_talon