/* * simpsim.c - a module that contains Simple Simon Moves. * * Written by Shlomi Fish (shlomif@vipe.technion.ac.il), 2001 * * This file is in the public domain (it's uncopyrighted). */ #include #include "fcs.h" #include "tests.h" #include "ms_ca.h" #ifdef DMALLOC #include "dmalloc.h" #endif #define fcs_is_ss_false_parent(parent, child) \ (fcs_card_card_num(parent) == fcs_card_card_num(child)+1) #define fcs_suit_is_ss_true_parent(parent_suit, child_suit) \ ((parent_suit) == (child_suit)) #define fcs_is_ss_true_parent(parent, child) \ ( \ fcs_is_ss_false_parent(parent,child) && \ (fcs_suit_is_ss_true_parent(fcs_card_suit(parent),fcs_card_suit(child))) \ ) /* * Those are some macros to make it easier for the programmer. * */ #define state_with_locations (*ptr_state_with_locations) #define state (ptr_state_with_locations->s) #define new_state_with_locations (*ptr_new_state_with_locations) #define new_state (ptr_new_state_with_locations->s) int freecell_solver_sfs_simple_simon_move_sequence_to_founds( freecell_solver_soft_thread_t * soft_thread, fcs_state_with_locations_t * ptr_state_with_locations, int num_freestacks, int num_freecells, fcs_derived_states_list_t * derived_states_list, int reparent ) { tests_declare_accessors(); fcs_move_t temp_move; int check; fcs_card_t temp_card; /* * stack - the stack index from which to move cards to the founds. * cards_num - the number of cards in "stack" * suit - the suit of the complete sequence * a - the height of the card * */ int stack, cards_num, suit, a; /* * card - the current card (at height a) * above_card - the card above it. * */ fcs_card_t card, above_card; int state_stacks_num; tests_define_accessors(); state_stacks_num = instance->stacks_num; for(stack=0;stack= 13) { card = fcs_stack_card(state,stack,cards_num-1); /* Check if the top 13 cards are a sequence */ for(a=2;a<=13;a++) { above_card = fcs_stack_card(state,stack,cards_num-a); if (fcs_is_ss_true_parent(above_card, card)) { /* Do nothing - the card is OK for a propert sequence*/ } else { break; } card = above_card; } if (a == 14) { /* We can move this sequence up there */ sfs_check_state_begin(); my_copy_stack(stack); suit = fcs_card_suit(card); for(a=0;a<13;a++) { fcs_pop_stack_card(new_state, stack, temp_card); fcs_increment_foundation(new_state, suit); } fcs_move_init(temp_move); fcs_move_set_type(temp_move, FCS_MOVE_TYPE_SEQ_TO_FOUNDATION); fcs_move_set_src_stack(temp_move, stack); fcs_move_set_foundation(temp_move,suit); fcs_move_stack_push(moves,temp_move); sfs_check_state_end(); } } } return FCS_STATE_IS_NOT_SOLVEABLE; } int freecell_solver_sfs_simple_simon_move_sequence_to_true_parent( freecell_solver_soft_thread_t * soft_thread, fcs_state_with_locations_t * ptr_state_with_locations, int num_freestacks, int num_freecells, fcs_derived_states_list_t * derived_states_list, int reparent ) { tests_declare_accessors(); fcs_move_t temp_move; int check; /* * stack - the source stack index on which the sequence currently resides. * cards_num - the number of cards in "stack". * suit - the suit of the current card * a - a temporary variable that designates a card height * */ int stack, cards_num, suit, a; /* * h - the current height in stack * */ int h; /* * card - the current card (at height h) * above_card - the card above it. * dest_card - the destination card on which to put the sequence * */ fcs_card_t card, temp_card, dest_card; /* * card_num - the card number (i.e: A, 2 ,3 ... K) of the card, or * its previous one. * num_true_seqs - the number of true sequences (i.e: sequences of a * unified suit) in the source sequence. * ds - the destination stack index. * dest_cards_num - the number of cards in "ds". * */ int card_num, num_true_seqs, ds, dest_cards_num ; int state_stacks_num; tests_define_accessors(); state_stacks_num = instance->stacks_num; for(stack=0;stack 0) { /* Loop on the cards in the stack and try to look for a true * parent on top one of the stacks */ card = fcs_stack_card(state,stack,cards_num-1); card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); num_true_seqs = 1; for(h=cards_num-2;h>=-1;h--) { for(ds=0;ds 0) { dest_card = fcs_stack_card(state, ds, dest_cards_num-1); if ((fcs_card_suit(dest_card) == suit) && (fcs_card_card_num(dest_card) == (card_num+1)) ) { /* This is a suitable parent - let's check if we * have enough empty stacks to make the move feasible */ if (calc_max_sequence_move(0, num_freestacks) >= num_true_seqs) { /* We can do it - so let's move */ sfs_check_state_begin(); my_copy_stack(stack); my_copy_stack(ds); fcs_move_sequence(ds, stack, h+1, cards_num-1, a); sfs_check_state_end(); } } } } /* Stop if we reached the bottom of the stack */ if (h == -1) { break; } card = fcs_stack_card(state,stack,h); /* If this is no longer a sequence - move to the next stack */ if (fcs_card_card_num(card) != card_num+1) { break; } if (! fcs_suit_is_ss_true_parent(suit, fcs_card_suit(card))) { num_true_seqs++; } card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); } } } return FCS_STATE_IS_NOT_SOLVEABLE; } int freecell_solver_sfs_simple_simon_move_whole_stack_sequence_to_false_parent( freecell_solver_soft_thread_t * soft_thread, fcs_state_with_locations_t * ptr_state_with_locations, int num_freestacks, int num_freecells, fcs_derived_states_list_t * derived_states_list, int reparent ) { tests_declare_accessors(); fcs_move_t temp_move; int check; /* * stack - the source stack index * cards_num - number of cards in "stack" * ds - the dest stack index * dest_cards_num - number of cards in "ds". * card - the current card * card_num - its card number * suit - its suit * dest_card - the card at the top of "ds". * h - the height of the current card on "stack" * num_true_seqs - the number of true sequences on the current * false sequence * */ int stack, cards_num, suit, a; fcs_card_t card, temp_card, dest_card; int card_num, num_true_seqs, h, ds, dest_cards_num ; int state_stacks_num; tests_define_accessors(); state_stacks_num = instance->stacks_num; for(stack=0;stack 0) { card = fcs_stack_card(state,stack,cards_num-1); card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); num_true_seqs = 1; /* Stop if we reached the bottom of the stack */ for(h=cards_num-2;h>-1;h--) { card = fcs_stack_card(state,stack,h); /* If this is no longer a sequence - move to the next stack */ if (fcs_card_card_num(card) != card_num+1) { break; } if (fcs_card_suit(card) != suit) { num_true_seqs++; } card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); } /* This means that the loop exited prematurely and the stack does * not contain a sequence. */ if (h != -1) { continue; } for(ds=0;ds 0) { dest_card = fcs_stack_card(state, ds, dest_cards_num-1); if ( (fcs_is_ss_false_parent(dest_card, card)) ) { /* This is a suitable parent - let's check if we * have enough empty stacks to make the move feasible */ if (calc_max_sequence_move(0, num_freestacks) >= num_true_seqs) { /* We can do it - so let's move */ sfs_check_state_begin(); my_copy_stack(stack); my_copy_stack(ds); fcs_move_sequence(ds, stack, h+1, cards_num-1, a); sfs_check_state_end(); } } } } } } return FCS_STATE_IS_NOT_SOLVEABLE; } int freecell_solver_sfs_simple_simon_move_sequence_to_true_parent_with_some_cards_above( freecell_solver_soft_thread_t * soft_thread, fcs_state_with_locations_t * ptr_state_with_locations, int num_freestacks, int num_freecells, fcs_derived_states_list_t * derived_states_list, int reparent ) { tests_declare_accessors(); fcs_move_t temp_move; int check; /* * stack - the source stack index * cards_num - the number of cards in "stack" * h - the height of the current card in "stack" * card - the card in height "h" * suit - its suit * card_num - its card number * ds - the destionation stack index * dest_cards_num - the number of cards in "ds" * dc - the index of the current card in "ds". * num_separate_false_seqs - this variable tells how many distinct false * sequences exist above the true parent * above_num_true_seqs[] - the number of true sequences in each false * sequence * seq_points[] - the separation points of the false sequences (i.e: where * they begin and end) * stacks_map[] - a boolean map that indicates if one can place a card * on this stack or is it already taken. * junk_move_to_stacks[] - the stacks to move each false sequence of the * junk to. * false_seq_index - an iterator to hold the index of the current false * sequence. * after_junk_num_freestacks - this variable holds the number of stacks * that remained unoccupied during and after the process of moving * the junk sequences to different stacks. * * */ int stack, cards_num, suit, a; fcs_card_t card, temp_card, dest_card; int card_num, above_num_true_seqs[MAX_NUM_CARDS_IN_A_STACK], h, ds, dest_cards_num ; int dc; int seq_points[MAX_NUM_CARDS_IN_A_STACK]; int num_separate_false_seqs; int false_seq_index; int num_true_seqs; int stacks_map[MAX_NUM_STACKS]; int after_junk_num_freestacks; int junk_move_to_stacks[MAX_NUM_STACKS]; int state_stacks_num; tests_define_accessors(); state_stacks_num = instance->stacks_num; for(stack=0;stack 0) { card = fcs_stack_card(state,stack,cards_num-1); card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); num_true_seqs = 1; for(h=cards_num-2;h>=-1;h--) { for(ds=0;ds 0) { for(dc=dest_cards_num-1;dc>=0;dc--) { dest_card = fcs_stack_card(state, ds, dc); if ((fcs_card_suit(dest_card) == suit) && (fcs_card_card_num(dest_card) == (card_num+1)) ) { /* This is a suitable parent - let's check if there's a sequence above it. */ /* * above_c - the height of the card that is to be checked. * above_card - the card at height above_c+1 * up_above_card - the card at height above_c * * */ int above_c; fcs_card_t above_card, up_above_card; num_separate_false_seqs = 0; above_card = fcs_stack_card(state, ds, dest_cards_num-1); above_num_true_seqs[num_separate_false_seqs] = 1; for(above_c = dest_cards_num-2 ; above_c > dc ; above_c-- ) { up_above_card = fcs_stack_card(state, ds, above_c); if (! fcs_is_ss_false_parent(up_above_card, above_card)) { seq_points[num_separate_false_seqs++] = above_c+1; above_num_true_seqs[num_separate_false_seqs] = 1; } above_num_true_seqs[num_separate_false_seqs] += ! (fcs_card_suit(up_above_card) == fcs_card_suit(above_card)); above_card = up_above_card; } if (dc < dest_cards_num - 1) { seq_points[num_separate_false_seqs++] = above_c+1; } for(a=0;a 0) && (stacks_map[clear_junk_dest_stack] == 0)) { fcs_card_t clear_junk_dest_card; clear_junk_dest_card = fcs_stack_card(state, clear_junk_dest_stack, clear_junk_stack_len-1); if (fcs_is_ss_false_parent(clear_junk_dest_card, fcs_stack_card(state, ds, seq_points[false_seq_index]))) { if (calc_max_sequence_move(0, after_junk_num_freestacks) >= above_num_true_seqs[false_seq_index]) { stacks_map[clear_junk_dest_stack] = 1; break; } } } } if (clear_junk_dest_stack == state_stacks_num) { clear_junk_dest_stack = -1; } if (clear_junk_dest_stack == -1) { /* Check if there is a vacant stack */ if (num_freestacks > 0) { if (calc_max_sequence_move(0, after_junk_num_freestacks-1) >= above_num_true_seqs[false_seq_index]) { /* Find an empty stack and designate it as the destination for the junk */ for( clear_junk_dest_stack = 0; clear_junk_dest_stack < state_stacks_num; clear_junk_dest_stack++ ) { if ((fcs_stack_len(state, clear_junk_dest_stack) == 0) && (stacks_map[clear_junk_dest_stack] == 0)) { stacks_map[clear_junk_dest_stack] = 1; break; } } } after_junk_num_freestacks--; } } if ((clear_junk_dest_stack == -1)) { break; } junk_move_to_stacks[false_seq_index] = clear_junk_dest_stack; } if (false_seq_index == num_separate_false_seqs) { if (calc_max_sequence_move(0, after_junk_num_freestacks) >= num_true_seqs) { /* * We can do it - so let's move everything. * Notice that we only put the child in a different stack * then the parent and let it move to the parent in the * next iteration of the program * */ sfs_check_state_begin(); my_copy_stack(ds); my_copy_stack(stack); /* Move the junk cards to their place */ for(false_seq_index=0; false_seq_indexstacks_num; for(stack=0;stack 0) { for( sc = cards_num-1 ; sc >= 0 ; sc-- ) { int above_c; fcs_card_t above_card, up_above_card; int end_of_src_seq; card = fcs_stack_card(state, stack, sc); suit = fcs_card_suit(card); card_num = fcs_card_card_num(card); num_true_seqs = 1; for (end_of_src_seq = sc+1; end_of_src_seq < cards_num ; end_of_src_seq++) { above_card = fcs_stack_card(state, stack, end_of_src_seq); if (!fcs_is_ss_false_parent(card, above_card)) { break; } if (fcs_card_suit(above_card) != fcs_card_suit(card)) { num_true_seqs++; } card = above_card; } if (end_of_src_seq == cards_num) { continue; } /* Split the cards above it into false sequences */ num_separate_false_seqs = 0; above_card = fcs_stack_card(state, stack, cards_num-1); above_num_true_seqs[num_separate_false_seqs] = 1; for(above_c = cards_num-2 ; above_c > end_of_src_seq-1 ; above_c-- ) { up_above_card = fcs_stack_card(state, stack, above_c); if (! fcs_is_ss_false_parent(up_above_card, above_card)) { seq_points[num_separate_false_seqs++] = above_c+1; above_num_true_seqs[num_separate_false_seqs] = 1; } above_num_true_seqs[num_separate_false_seqs] += ! (fcs_card_suit(up_above_card) == fcs_card_suit(above_card)); above_card = up_above_card; } if (end_of_src_seq-1 < cards_num-1) { seq_points[num_separate_false_seqs++] = above_c+1; } for(ds=0;ds 0) { dest_card = fcs_stack_card(state, ds, dest_cards_num-1); if ((fcs_card_suit(dest_card) == suit) && (fcs_card_card_num(dest_card) == (card_num+1)) ) { /* This is a suitable parent - let's check if we * have enough empty stacks to make the move feasible */ for(a=0;a 0) && (stacks_map[clear_junk_dest_stack] == 0)) { fcs_card_t clear_junk_dest_card; clear_junk_dest_card = fcs_stack_card(state, clear_junk_dest_stack, clear_junk_stack_len-1); if (fcs_is_ss_false_parent(clear_junk_dest_card, fcs_stack_card(state, stack, seq_points[false_seq_index]))) { if (calc_max_sequence_move(0, after_junk_num_freestacks) >= above_num_true_seqs[false_seq_index]) { stacks_map[clear_junk_dest_stack] = 1; break; } } } } if (clear_junk_dest_stack == state_stacks_num) { clear_junk_dest_stack = -1; } if (clear_junk_dest_stack == -1) { /* Check if there is a vacant stack */ if (num_freestacks > 0) { if (calc_max_sequence_move(0, after_junk_num_freestacks-1) >= above_num_true_seqs[false_seq_index]) { /* Find an empty stack and designate it as the destination for the junk */ for( clear_junk_dest_stack = 0; clear_junk_dest_stack < state_stacks_num; clear_junk_dest_stack++ ) { if ((fcs_stack_len(state, clear_junk_dest_stack) == 0) && (stacks_map[clear_junk_dest_stack] == 0)) { stacks_map[clear_junk_dest_stack] = 1; break; } } } after_junk_num_freestacks--; } } if ((clear_junk_dest_stack == -1)) { break; } junk_move_to_stacks[false_seq_index] = clear_junk_dest_stack; } if (false_seq_index == num_separate_false_seqs) { if (calc_max_sequence_move(0, after_junk_num_freestacks) > num_true_seqs) { sfs_check_state_begin(); my_copy_stack(stack); my_copy_stack(ds); /* Let's boogie - we can move everything */ /* Move the junk cards to their place */ for(false_seq_index=0; false_seq_indexstacks_num; for(stack=0;stack 0) { card = fcs_stack_card(state,stack,cards_num-1); card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); num_src_junk_true_seqs = 1; for(h=cards_num-2;h>=-1;h--) { if (h == -1) { break; } card = fcs_stack_card(state, stack, h); if (fcs_card_card_num(card) != card_num+1) { break; } if (fcs_card_suit(card) != suit) { num_src_junk_true_seqs++; } card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); } if (h != -1) { end_of_junk = h; num_true_seqs = 1; for(;h>=-1;h--) { if (h == -1) { break; } card = fcs_stack_card(state,stack,h); if (fcs_card_card_num(card) != card_num+1) { break; } if (fcs_card_suit(card) != suit) { num_true_seqs++; } card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); } card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); for(ds=0;ds 1) { /* Start at the card below the top one, so we will * make sure there's at least some junk above it * */ for(dc=dest_cards_num-2;dc>=0;dc--) { dest_card = fcs_stack_card(state, ds, dc); if ((fcs_card_suit(dest_card) == suit) && (fcs_card_card_num(dest_card) == (card_num+1)) ) { /* This is a suitable parent - let's check if there's a sequence above it. */ int above_c; fcs_card_t above_card, up_above_card; num_separate_false_seqs = 0; above_card = fcs_stack_card(state, ds, dest_cards_num-1); above_num_true_seqs[num_separate_false_seqs] = 1; for(above_c = dest_cards_num-2 ; above_c > dc ; above_c-- ) { up_above_card = fcs_stack_card(state, ds, above_c); if (! fcs_is_ss_false_parent(up_above_card, above_card)) { seq_points[num_separate_false_seqs++] = above_c+1; above_num_true_seqs[num_separate_false_seqs] = 1; } above_num_true_seqs[num_separate_false_seqs] += ! (fcs_card_suit(up_above_card) == fcs_card_suit(above_card)); above_card = up_above_card; } if (dc < dest_cards_num - 1) { seq_points[num_separate_false_seqs++] = above_c+1; } for(a=0;a 0) && (stacks_map[clear_junk_dest_stack] == 0)) { fcs_card_t clear_junk_dest_card; clear_junk_dest_card = fcs_stack_card(state, clear_junk_dest_stack, clear_junk_stack_len-1); if (fcs_is_ss_false_parent(clear_junk_dest_card, the_card)) { if (calc_max_sequence_move(0, after_junk_num_freestacks) >= the_num_true_seqs) { stacks_map[clear_junk_dest_stack] = 1; break; } } } } if (clear_junk_dest_stack == state_stacks_num) { clear_junk_dest_stack = -1; } if (clear_junk_dest_stack == -1) { /* Check if there is a vacant stack */ if (num_freestacks > 0) { if (calc_max_sequence_move(0, after_junk_num_freestacks-1) >= the_num_true_seqs) { /* Find an empty stack and designate it as the destination for the junk */ for( clear_junk_dest_stack = 0; clear_junk_dest_stack < state_stacks_num; clear_junk_dest_stack++ ) { if ((fcs_stack_len(state, clear_junk_dest_stack) == 0) && (stacks_map[clear_junk_dest_stack] == 0)) { stacks_map[clear_junk_dest_stack] = 1; break; } } } after_junk_num_freestacks--; } } if ((clear_junk_dest_stack == -1)) { break; } junk_move_to_stacks[false_seq_index] = clear_junk_dest_stack; } if (false_seq_index == num_separate_false_seqs+1) { if (calc_max_sequence_move(0, after_junk_num_freestacks) >= num_true_seqs) { /* We can do it - so let's move everything */ sfs_check_state_begin(); my_copy_stack(stack); my_copy_stack(ds); /* Move the junk cards to their place */ for(false_seq_index=0; false_seq_indexstacks_num; for(stack=0;stack 0) { card = fcs_stack_card(state,stack,cards_num-1); card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); num_true_seqs = 1; for(h=cards_num-2;h>=-1;h--) { if (h == -1) { break; } card = fcs_stack_card(state,stack,h); if (fcs_card_card_num(card) != card_num+1) { break; } if (fcs_card_suit(card) != suit) { num_true_seqs++; } card_num = fcs_card_card_num(card); suit = fcs_card_suit(card); } if (h == -1) { for(ds=0;ds 0) { for(dc=dest_cards_num-1;dc>=0;dc--) { dest_card = fcs_stack_card(state, ds, dc); if ( (fcs_card_card_num(dest_card) == (card_num+1)) ) { /* This is a suitable parent - let's check if there's a sequence above it. */ int above_c; fcs_card_t above_card, up_above_card; num_separate_false_seqs = 0; above_card = fcs_stack_card(state, ds, dest_cards_num-1); above_num_true_seqs[num_separate_false_seqs] = 1; for(above_c = dest_cards_num-2 ; above_c > dc ; above_c-- ) { up_above_card = fcs_stack_card(state, ds, above_c); if (! fcs_is_ss_false_parent(up_above_card, above_card)) { seq_points[num_separate_false_seqs++] = above_c+1; above_num_true_seqs[num_separate_false_seqs] = 1; } above_num_true_seqs[num_separate_false_seqs] += ! (fcs_card_suit(up_above_card) == fcs_card_suit(above_card)); above_card = up_above_card; } if (dc < dest_cards_num - 1) { seq_points[num_separate_false_seqs++] = above_c+1; } for(a=0;a 0) && (stacks_map[clear_junk_dest_stack] == 0)) { fcs_card_t clear_junk_dest_card; clear_junk_dest_card = fcs_stack_card(state, clear_junk_dest_stack, clear_junk_stack_len-1); if (fcs_is_ss_false_parent(clear_junk_dest_card, the_card)) { if (calc_max_sequence_move(0, after_junk_num_freestacks) >= the_num_true_seqs) { stacks_map[clear_junk_dest_stack] = 1; break; } } } } if (clear_junk_dest_stack == state_stacks_num) { clear_junk_dest_stack = -1; } if ((clear_junk_dest_stack == -1)) { break; } junk_move_to_stacks[false_seq_index] = clear_junk_dest_stack; } if (false_seq_index == num_separate_false_seqs) { /* This is a suitable parent - let's check if we * have enough empty stacks to make the move feasible */ if (calc_max_sequence_move(0, num_freestacks) >= num_true_seqs) { /* We can do it - so let's move */ sfs_check_state_begin(); my_copy_stack(stack); my_copy_stack(ds); /* Move the junk cards to their place */ for(false_seq_index=0; false_seq_indexstacks_num; for(stack=0 ; stack < state_stacks_num ; stack++) { cards_num = fcs_stack_len(state, stack); if (cards_num > 2) { /* Search for a parent card */ for(pc=0; pc < cards_num-1 ; pc++) { parent_card = fcs_stack_card(state, stack, pc); if ( fcs_is_ss_true_parent( parent_card, fcs_stack_card(state, stack, pc+1) ) ) { continue; } for(cc = pc + 2 ; cc < cards_num ; cc++) { child_card = fcs_stack_card(state, stack, cc); if (fcs_is_ss_true_parent( parent_card, child_card ) ) { /* We have a matching parent and child cards */ #if 0 printf("Stack %i, Parent %i, Child %i\n", stack, pc, cc); fflush(stdout); #endif /* * Now let's try to find stacks to place the cards above * the child card. * */ int above_num_true_seqs[MAX_NUM_CARDS_IN_A_STACK]; int seq_points[MAX_NUM_CARDS_IN_A_STACK]; int stacks_map[MAX_NUM_STACKS]; int junk_move_to_stacks[MAX_NUM_STACKS]; int num_separate_false_seqs; fcs_card_t above_card, up_above_card; int above_c; int end_of_child_seq; int child_num_true_seqs; end_of_child_seq = cc; child_num_true_seqs = 1; while ((end_of_child_seq+1 < cards_num) && fcs_is_ss_false_parent( fcs_stack_card(state, stack, end_of_child_seq), fcs_stack_card(state, stack, end_of_child_seq+1) ) ) { child_num_true_seqs += (!fcs_is_ss_true_parent( fcs_stack_card(state, stack, end_of_child_seq), fcs_stack_card(state, stack, end_of_child_seq+1) )); end_of_child_seq++; } num_separate_false_seqs = 0; above_card = fcs_stack_card(state, stack, cards_num-1); above_num_true_seqs[num_separate_false_seqs] = 1; for(above_c = cards_num-2; above_c > end_of_child_seq ; above_c-- ) { up_above_card = fcs_stack_card(state, stack, above_c); if (! fcs_is_ss_false_parent(up_above_card, above_card)) { seq_points[num_separate_false_seqs++] = above_c+1; above_num_true_seqs[num_separate_false_seqs] = 1; } above_num_true_seqs[num_separate_false_seqs] += ! (fcs_card_suit(up_above_card) == fcs_card_suit(above_card)); above_card = up_above_card; } if (end_of_child_seq < cards_num - 1) { seq_points[num_separate_false_seqs++] = above_c+1; } /* Add the child to the seq_points */ child_seq_index = num_separate_false_seqs; above_num_true_seqs[num_separate_false_seqs] = child_num_true_seqs; seq_points[num_separate_false_seqs++] = cc; /* Add the cards between the parent and the child to the seq_points */ above_card = fcs_stack_card(state, stack, cc-1); above_num_true_seqs[num_separate_false_seqs] = 1; for(above_c = cc-2; above_c > pc ; above_c-- ) { up_above_card = fcs_stack_card(state, stack, above_c); if (! fcs_is_ss_false_parent(up_above_card, above_card)) { seq_points[num_separate_false_seqs++] = above_c+1; above_num_true_seqs[num_separate_false_seqs] = 1; } above_num_true_seqs[num_separate_false_seqs] += ! (fcs_card_suit(up_above_card) == fcs_card_suit(above_card)); above_card = up_above_card; } if (pc < cc - 1) { seq_points[num_separate_false_seqs++] = above_c+1; } for(a = 0 ; a < state_stacks_num ; a++) { stacks_map[a] = 0; } stacks_map[stack] = 1; after_junk_num_freestacks = num_freestacks; for(false_seq_index=0;false_seq_index 0) && (stacks_map[clear_junk_dest_stack] == 0)) { fcs_card_t clear_junk_dest_card; clear_junk_dest_card = fcs_stack_card(state, clear_junk_dest_stack, clear_junk_stack_len-1); if (fcs_is_ss_false_parent(clear_junk_dest_card, fcs_stack_card(state, stack, seq_points[false_seq_index]))) { if (calc_max_sequence_move(0, after_junk_num_freestacks) >= above_num_true_seqs[false_seq_index]) { stacks_map[clear_junk_dest_stack] = 1; break; } } } } if (clear_junk_dest_stack == state_stacks_num) { clear_junk_dest_stack = -1; } if (clear_junk_dest_stack == -1) { /* Check if there is a vacant stack */ if (num_freestacks > 0) { if (calc_max_sequence_move(0, after_junk_num_freestacks-1) >= above_num_true_seqs[false_seq_index]) { /* Find an empty stack and designate it as the destination for the junk */ for( clear_junk_dest_stack = 0; clear_junk_dest_stack < state_stacks_num; clear_junk_dest_stack++ ) { if ((fcs_stack_len(state, clear_junk_dest_stack) == 0) && (stacks_map[clear_junk_dest_stack] == 0)) { stacks_map[clear_junk_dest_stack] = 1; break; } } } after_junk_num_freestacks--; } } if ((clear_junk_dest_stack == -1)) { break; } junk_move_to_stacks[false_seq_index] = clear_junk_dest_stack; } if (false_seq_index == num_separate_false_seqs) { /* Let's check if we can move the child after we are done moving all the junk cards */ if (calc_max_sequence_move(0, after_junk_num_freestacks) >= child_num_true_seqs) { /* We can do it - so let's move everything */ sfs_check_state_begin(); /* Move the junk cards to their place */ my_copy_stack(stack); for(false_seq_index=0; false_seq_index