You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/kpat/freecell-solver/test_arr.h

137 lines
5.6 KiB

/*
* test_arr.h - header file for some routines and macros involving tests and
* the like for Freecell Solver.
*
* Written by Shlomi Fish (shlomif@vipe.technion.ac.il), 2002
*
* This file is in the public domain (it's uncopyrighted).
* */
#ifndef FC_SOLVE__TEST_ARR_H
#define FC_SOLVE__TEST_ARR_H
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*freecell_solver_solve_for_state_test_t)(
freecell_solver_soft_thread_t *,
fcs_state_with_locations_t *,
int,
int,
fcs_derived_states_list_t *,
int
);
extern freecell_solver_solve_for_state_test_t freecell_solver_sfs_tests[FCS_TESTS_NUM];
/*
* This macro determines if child can be placed above parent.
*
* The variable sequences_are_built_by has to be initialized to
* the sequences_are_built_by member of the instance.
*
* */
#define fcs_is_parent_card(child, parent) \
((fcs_card_card_num(child)+1 == fcs_card_card_num(parent)) && \
((sequences_are_built_by == FCS_SEQ_BUILT_BY_RANK) ? \
1 : \
((sequences_are_built_by == FCS_SEQ_BUILT_BY_SUIT) ? \
(fcs_card_suit(child) == fcs_card_suit(parent)) : \
((fcs_card_suit(child) & 0x1) != (fcs_card_suit(parent)&0x1)) \
)) \
)
/*
* This macro traces the path of the state up to the original state,
* and thus calculates its real depth.
*
* It then assigns the newly updated depth throughout the path.
*
* */
#define calculate_real_depth(ptr_state_orig) \
{ \
if (calc_real_depth) \
{ \
int this_real_depth = 0; \
fcs_state_with_locations_t * ptr_state = (ptr_state_orig); \
/* Count the number of states until the original state. */ \
while(ptr_state != NULL) \
{ \
ptr_state = ptr_state->parent; \
this_real_depth++; \
} \
this_real_depth--; \
ptr_state = (ptr_state_orig); \
/* Assign the new depth throughout the path*/ \
while (ptr_state->depth != this_real_depth) \
{ \
ptr_state->depth = this_real_depth; \
this_real_depth--; \
ptr_state = ptr_state->parent; \
} \
} \
} \
/*
* This macro marks a state as a dead end, and afterwards propogates
* this information to its parent and ancestor states.
* */
#define mark_as_dead_end(ptr_state_input) \
{ \
if (scans_synergy) \
{ \
fcs_state_with_locations_t * ptr_state = (ptr_state_input); \
/* Mark as a dead end */ \
ptr_state->visited |= FCS_VISITED_DEAD_END; \
ptr_state = ptr_state->parent; \
if (ptr_state != NULL) \
{ \
/* Decrease the refcount of the state */ \
ptr_state->num_active_children--; \
while((ptr_state->num_active_children == 0) && (ptr_state->visited & FCS_VISITED_ALL_TESTS_DONE)) \
{ \
/* Mark as dead end */ \
ptr_state->visited |= FCS_VISITED_DEAD_END; \
/* Go to its parent state */ \
ptr_state = ptr_state->parent; \
if (ptr_state == NULL) \
{ \
break; \
} \
/* Decrease the refcount */ \
ptr_state->num_active_children--; \
} \
} \
} \
}
/*
* This macro checks if we need to terminate from running this soft
* thread and return to the soft thread manager with an
* FCS_STATE_SUSPEND_PROCESS
* */
#define check_if_limits_exceeded() \
( \
((instance->max_num_times >= 0) && \
(instance->num_times >= instance->max_num_times)) \
|| \
((hard_thread->ht_max_num_times >= 0) && \
(hard_thread->num_times >= hard_thread->ht_max_num_times)) \
|| \
((hard_thread->max_num_times >= 0) && \
(hard_thread->num_times >= hard_thread->max_num_times)) \
|| \
((instance->max_num_states_in_collection >= 0) && \
(instance->num_states_in_collection >= \
instance->max_num_states_in_collection) \
) \
)
#ifdef __cplusplus
}
#endif
#endif