summaryrefslogtreecommitdiffstats
path: root/kpat/freecell-solver/simpsim.c
diff options
context:
space:
mode:
Diffstat (limited to 'kpat/freecell-solver/simpsim.c')
-rw-r--r--kpat/freecell-solver/simpsim.c1716
1 files changed, 1716 insertions, 0 deletions
diff --git a/kpat/freecell-solver/simpsim.c b/kpat/freecell-solver/simpsim.c
new file mode 100644
index 00000000..f603ba39
--- /dev/null
+++ b/kpat/freecell-solver/simpsim.c
@@ -0,0 +1,1716 @@
+/*
+ * 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 <stdio.h>
+
+#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<state_stacks_num;stack++)
+ {
+ cards_num = fcs_stack_len(state, stack);
+ if (cards_num >= 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<state_stacks_num;stack++)
+ {
+ cards_num = fcs_stack_len(state, stack);
+ if (cards_num > 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<state_stacks_num;ds++)
+ {
+ if (ds == stack)
+ {
+ continue;
+ }
+
+ dest_cards_num = fcs_stack_len(state,ds);
+ if (dest_cards_num > 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<state_stacks_num;stack++)
+ {
+ cards_num = fcs_stack_len(state, stack);
+ if (cards_num > 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<state_stacks_num;ds++)
+ {
+ dest_cards_num = fcs_stack_len(state,ds);
+ if (dest_cards_num > 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<state_stacks_num;stack++)
+ {
+ cards_num = fcs_stack_len(state, stack);
+ if (cards_num > 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<state_stacks_num;ds++)
+ {
+ if (ds == stack)
+ {
+ continue;
+ }
+
+ dest_cards_num = fcs_stack_len(state,ds);
+ if (dest_cards_num > 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<state_stacks_num;a++)
+ {
+ stacks_map[a] = 0;
+ }
+ stacks_map[stack] = 1;
+ stacks_map[ds] = 1;
+
+ after_junk_num_freestacks = num_freestacks;
+
+ for(false_seq_index=0;false_seq_index<num_separate_false_seqs;false_seq_index++)
+ {
+ /* Find a suitable place to put it */
+
+ /*
+ * clear_junk_dest_stack is the stack to move this particular junk sequence to.
+ * */
+ int clear_junk_dest_stack = -1;
+
+
+ /* Let's try to find a suitable parent on top one of the stacks */
+ for(clear_junk_dest_stack=0;
+ clear_junk_dest_stack < state_stacks_num;
+ clear_junk_dest_stack++
+ )
+ {
+ int clear_junk_stack_len;
+ clear_junk_stack_len = fcs_stack_len(state, clear_junk_dest_stack);
+
+ if ((clear_junk_stack_len > 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_index<num_separate_false_seqs;
+ false_seq_index++
+ )
+ {
+ /*
+ * start and end are the start and end heights of the sequence that is to be moved.
+ * */
+ int start = seq_points[false_seq_index];
+ int end = ((false_seq_index == 0) ? (dest_cards_num-1) : (seq_points[false_seq_index-1]-1));
+
+ my_copy_stack(junk_move_to_stacks[false_seq_index]);
+
+ fcs_move_sequence(junk_move_to_stacks[false_seq_index], ds, start, end, a);
+
+ }
+
+ /* Move the source seq on top of the dest seq */
+ 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;
+ }
+ /* If this is no longer a sequence - move to the next stack */
+ if (fcs_stack_card_num(state,stack, h) != card_num+1)
+ {
+ break;
+ }
+ card = fcs_stack_card(state,stack,h);
+ 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_sequence_with_some_cards_above_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 stack, cards_num, suit, a;
+ fcs_card_t card, temp_card, dest_card;
+ int card_num, num_true_seqs, ds, dest_cards_num ;
+ int check;
+ int sc, num_separate_false_seqs, 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 after_junk_num_freestacks;
+ int false_seq_index;
+ int junk_move_to_stacks[MAX_NUM_CARDS_IN_A_STACK];
+
+ int state_stacks_num;
+ tests_define_accessors();
+
+ state_stacks_num = instance->stacks_num;
+
+ for(stack=0;stack<state_stacks_num;stack++)
+ {
+ cards_num = fcs_stack_len(state, stack);
+ if (cards_num > 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<state_stacks_num;ds++)
+ {
+ if (ds == stack)
+ {
+ continue;
+ }
+
+ dest_cards_num = fcs_stack_len(state,ds);
+ if (dest_cards_num > 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<state_stacks_num;a++)
+ {
+ stacks_map[a] = 0;
+ }
+ stacks_map[stack] = 1;
+ stacks_map[ds] = 1;
+
+ after_junk_num_freestacks = num_freestacks;
+
+ for(false_seq_index=0;false_seq_index<num_separate_false_seqs;false_seq_index++)
+ {
+ /* Find a suitable place to put it */
+ int clear_junk_dest_stack = -1;
+
+
+ /* Let's try to find a suitable parent on top one of the stacks */
+ for(clear_junk_dest_stack=0;
+ clear_junk_dest_stack < state_stacks_num;
+ clear_junk_dest_stack++
+ )
+ {
+ int clear_junk_stack_len;
+ clear_junk_stack_len = fcs_stack_len(state, clear_junk_dest_stack);
+
+ if ((clear_junk_stack_len > 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_index<num_separate_false_seqs;
+ false_seq_index++
+ )
+ {
+ int start;
+ int end;
+
+ int src_stack;
+
+ {
+ start = seq_points[false_seq_index];
+ end = ((false_seq_index == 0) ? (cards_num-1) : (seq_points[false_seq_index-1]-1));
+ src_stack = stack;
+ }
+
+ my_copy_stack(junk_move_to_stacks[false_seq_index]);
+
+ fcs_move_sequence(junk_move_to_stacks[false_seq_index], src_stack, start, end, a);
+ }
+
+ fcs_move_sequence(ds, stack, sc, end_of_src_seq-1, a);
+
+ sfs_check_state_end();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return FCS_STATE_IS_NOT_SOLVEABLE;
+}
+
+int freecell_solver_sfs_simple_simon_move_sequence_with_junk_seq_above_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 current card in "stack"
+ * suit - its suit
+ * card_num - its card number
+ * ds - the index of the destination stack
+ * dest_cards_num - the number of cards in "ds".
+ * dc - the height of the current card in "ds".
+ * num_separate_false_seqs - the number of false sequences
+ * seq_points[] - the places in which the false sequences of the junk begin
+ * and end
+ * false_seq_index - an iterator that marks the index of the current
+ * false sequence
+ * stacks_map[] - a map of booleans that indicates if one can place a card
+ * on this stack or is already taken.
+ * above_num_true_seqs[] - the number of true sequences in each false
+ * sequence
+ * num_src_junk_true_seqs - the number of true seqs in the false seq above
+ * the source card.
+ * end_of_junk - the height marking the end of the source junk.
+ * num_true_seqs - the number of true sequences in the false seq which we
+ * wish to move.
+ * */
+ 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 stacks_map[MAX_NUM_STACKS];
+ int after_junk_num_freestacks;
+ int junk_move_to_stacks[MAX_NUM_STACKS];
+ int num_src_junk_true_seqs;
+ int end_of_junk;
+ int num_true_seqs;
+
+ int state_stacks_num;
+ tests_define_accessors();
+
+ state_stacks_num = instance->stacks_num;
+
+ for(stack=0;stack<state_stacks_num;stack++)
+ {
+ cards_num = fcs_stack_len(state, stack);
+ if (cards_num > 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<state_stacks_num;ds++)
+ {
+ if (ds == stack)
+ {
+ continue;
+ }
+
+ dest_cards_num = fcs_stack_len(state,ds);
+ /* At least a card with another card above it */
+ if (dest_cards_num > 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<state_stacks_num;a++)
+ {
+ stacks_map[a] = 0;
+ }
+ stacks_map[stack] = 1;
+ stacks_map[ds] = 1;
+
+ after_junk_num_freestacks = num_freestacks;
+
+ for(false_seq_index=0;false_seq_index<num_separate_false_seqs+1;false_seq_index++)
+ {
+ /* Find a suitable place to put it */
+ int clear_junk_dest_stack = -1;
+
+ fcs_card_t the_card =
+ (
+ (false_seq_index == num_separate_false_seqs) ?
+ (fcs_stack_card(state, stack, end_of_junk+1)) :
+ (fcs_stack_card(state, ds, seq_points[false_seq_index]))
+ );
+
+ int the_num_true_seqs =
+ (
+ (false_seq_index == num_separate_false_seqs) ?
+ num_src_junk_true_seqs :
+ above_num_true_seqs[false_seq_index]
+ );
+
+ /* Let's try to find a suitable parent on top one of the stacks */
+ for(clear_junk_dest_stack=0;
+ clear_junk_dest_stack < state_stacks_num;
+ clear_junk_dest_stack++
+ )
+ {
+ int clear_junk_stack_len;
+ clear_junk_stack_len = fcs_stack_len(state, clear_junk_dest_stack);
+
+ if ((clear_junk_stack_len > 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_index<num_separate_false_seqs+1;
+ false_seq_index++
+ )
+ {
+ int start;
+ int end;
+
+ int src_stack;
+
+ if (false_seq_index == num_separate_false_seqs)
+ {
+ start = end_of_junk+1;
+ end = cards_num-1;
+ src_stack = stack;
+ }
+ else
+ {
+ start = seq_points[false_seq_index];
+ end = ((false_seq_index == 0) ? (dest_cards_num-1) : (seq_points[false_seq_index-1]-1));
+ src_stack = ds;
+ }
+
+ my_copy_stack(src_stack);
+
+ my_copy_stack(junk_move_to_stacks[false_seq_index]);
+
+ fcs_move_sequence(junk_move_to_stacks[false_seq_index], src_stack, start, end, a);
+ }
+
+ /* Move the source seq on top of the dest seq */
+ fcs_move_sequence(ds, stack, h, end_of_junk, a);
+
+ sfs_check_state_end();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return FCS_STATE_IS_NOT_SOLVEABLE;
+}
+
+int freecell_solver_sfs_simple_simon_move_whole_stack_sequence_to_false_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 current card
+ * suit - its suit
+ * card_num - its card number
+ * ds - the destination stack index.
+ * dest_cards_num - the number of cards in it.
+ * dc - the height of the card in "ds".
+ * num_separate_false_seqs - this variable tells how many distinct false
+ * sequences exist above the false 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 - a variable that holds the number of stacks
+ * that are left unoccupied as part of the junk disposal process.
+ *
+ * */
+ 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 dc, num_separate_false_seqs, 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 after_junk_num_freestacks;
+ int false_seq_index;
+ 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<state_stacks_num;stack++)
+ {
+ cards_num = fcs_stack_len(state, stack);
+ if (cards_num > 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<state_stacks_num;ds++)
+ {
+ dest_cards_num = fcs_stack_len(state,ds);
+ if (dest_cards_num > 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<state_stacks_num;a++)
+ {
+ stacks_map[a] = 0;
+ }
+ stacks_map[stack] = 1;
+ stacks_map[ds] = 1;
+
+ after_junk_num_freestacks = num_freestacks;
+
+ for(false_seq_index=0;false_seq_index<num_separate_false_seqs;false_seq_index++)
+ {
+ /* Find a suitable place to put it */
+ int clear_junk_dest_stack = -1;
+
+ fcs_card_t the_card =
+ (fcs_stack_card(state, ds, seq_points[false_seq_index]))
+ ;
+
+
+ int the_num_true_seqs =
+ above_num_true_seqs[false_seq_index];
+
+
+ /* Let's try to find a suitable parent on top one of the stacks */
+ for(clear_junk_dest_stack=0;
+ clear_junk_dest_stack < state_stacks_num;
+ clear_junk_dest_stack++
+ )
+ {
+ int clear_junk_stack_len;
+ clear_junk_stack_len = fcs_stack_len(state, clear_junk_dest_stack);
+
+ if ((clear_junk_stack_len > 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_index<num_separate_false_seqs;
+ false_seq_index++
+ )
+ {
+ int start;
+ int end;
+
+ int src_stack;
+
+ {
+ start = seq_points[false_seq_index];
+ end = ((false_seq_index == 0) ? (dest_cards_num-1) : (seq_points[false_seq_index-1]-1));
+ src_stack = ds;
+ }
+
+ my_copy_stack(src_stack);
+ my_copy_stack(junk_move_to_stacks[false_seq_index]);
+
+ fcs_move_sequence( junk_move_to_stacks[false_seq_index], src_stack, start, end, a);
+ }
+
+ 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_parent_on_the_same_stack(
+ 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;
+
+ int stack, cards_num, pc, cc;
+ fcs_card_t parent_card, child_card;
+ int a;
+ int after_junk_num_freestacks;
+ int false_seq_index;
+ int child_seq_index;
+
+ fcs_card_t temp_card;
+
+ int state_stacks_num;
+ tests_define_accessors();
+
+ state_stacks_num = instance->stacks_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<num_separate_false_seqs;false_seq_index++)
+ {
+ /* Find a suitable place to put it */
+ int clear_junk_dest_stack = -1;
+
+
+ /* Let's try to find a suitable parent on top one of the stacks */
+ for(clear_junk_dest_stack=0;
+ clear_junk_dest_stack < state_stacks_num;
+ clear_junk_dest_stack++
+ )
+ {
+ int clear_junk_stack_len;
+ clear_junk_stack_len = fcs_stack_len(state, clear_junk_dest_stack);
+
+ if ((clear_junk_stack_len > 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<num_separate_false_seqs;
+ false_seq_index++
+ )
+ {
+ int start = seq_points[false_seq_index];
+ int end = ((false_seq_index == 0) ? (cards_num-1) : (seq_points[false_seq_index-1]-1));
+
+ my_copy_stack(junk_move_to_stacks[false_seq_index]);
+
+ fcs_move_sequence ( junk_move_to_stacks[false_seq_index], stack, start, end, a);
+ }
+
+ {
+ int end = fcs_stack_len(new_state, junk_move_to_stacks[child_seq_index])-1;
+ int start = end-(end_of_child_seq-cc);
+
+ my_copy_stack(junk_move_to_stacks[child_seq_index]);
+
+
+ fcs_move_sequence( stack, junk_move_to_stacks[child_seq_index], start, end, a);
+ }
+
+ sfs_check_state_end();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return FCS_STATE_IS_NOT_SOLVEABLE;
+}
+
+#undef state_with_locations
+#undef state
+#undef new_state_with_locations
+#undef new_state
+