diff options
Diffstat (limited to 'kpat/freecell-solver/tests.h')
-rw-r--r-- | kpat/freecell-solver/tests.h | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/kpat/freecell-solver/tests.h b/kpat/freecell-solver/tests.h new file mode 100644 index 00000000..ce0b35b5 --- /dev/null +++ b/kpat/freecell-solver/tests.h @@ -0,0 +1,307 @@ +/* + * fcs.h - header file of the test functions for Freecell Solver. + * + * The test functions code is found in freecell.c + * + * Written by Shlomi Fish (shlomif@vipe.technion.ac.il), 2000 + * + * This file is in the public domain (it's uncopyrighted). + */ + +#ifndef FC_SOLVE__TESTS_H +#define FC_SOLVE__TESTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdlib.h> +#include <limits.h> +#include <string.h> + +#include "fcs_isa.h" +#include "fcs.h" + +#include "test_arr.h" + + +/* + * The number of cards that can be moved is + * (freecells_number + 1) * 2 ^ (free_stacks_number) + * + * See the Freecell FAQ and the source code of PySol + * + * */ +#define calc_max_sequence_move(fc_num, fs_num) \ + ((instance->empty_stacks_fill == FCS_ES_FILLED_BY_ANY_CARD) ? \ + ( \ + (instance->unlimited_sequence_move) ? \ + INT_MAX : \ + (((fc_num)+1)<<(fs_num)) \ + ) : \ + ((fc_num)+1) \ + ) + +#include "caas.h" + +/* + * These 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) + +#define sfs_check_state_begin() \ + fcs_state_ia_alloc_into_var(ptr_new_state_with_locations, hard_thread); \ + fcs_duplicate_state(new_state_with_locations, state_with_locations); \ + /* Some A* and BFS parameters that need to be initialized in \ + * the derived state. \ + * */ \ + ptr_new_state_with_locations->parent = ptr_state_with_locations; \ + ptr_new_state_with_locations->moves_to_parent = moves; \ + /* Make sure depth is consistent with the game graph. \ + * I.e: the depth of every newly discovered state is derived from \ + * the state from which it was discovered. */ \ + ptr_new_state_with_locations->depth = ptr_state_with_locations->depth + 1; \ + /* Mark this state as a state that was not yet visited */ \ + ptr_new_state_with_locations->visited = 0; \ + /* It's a newly created state which does not have children yet. */ \ + ptr_new_state_with_locations->num_active_children = 0; \ + memset(ptr_new_state_with_locations->scan_visited, '\0', \ + sizeof(ptr_new_state_with_locations->scan_visited) \ + ); \ + fcs_move_stack_reset(moves); \ + + + + +#define sfs_check_state_end() \ +/* The last move in a move stack should be FCS_MOVE_TYPE_CANONIZE \ + * because it indicates that the order of the stacks and freecells \ + * need to be recalculated \ + * */ \ +fcs_move_set_type(temp_move,FCS_MOVE_TYPE_CANONIZE); \ +fcs_move_stack_push(moves, temp_move); \ + \ +{ \ + fcs_state_with_locations_t * existing_state; \ + check = freecell_solver_check_and_add_state( \ + soft_thread, \ + ptr_new_state_with_locations, \ + &existing_state \ + ); \ + if ((check == FCS_STATE_BEGIN_SUSPEND_PROCESS) || \ + (check == FCS_STATE_SUSPEND_PROCESS)) \ + { \ + /* This state is not going to be used, so \ + * let's clean it. */ \ + fcs_state_ia_release(hard_thread); \ + return check; \ + } \ + else if (check == FCS_STATE_ALREADY_EXISTS) \ + { \ + fcs_state_ia_release(hard_thread); \ + calculate_real_depth(existing_state); \ + /* Re-parent the existing state to this one. \ + * \ + * What it means is that if the depth of the state if it \ + * can be reached from this one is lower than what it \ + * already have, then re-assign its parent to this state. \ + * */ \ + if (reparent && \ + (existing_state->depth > ptr_state_with_locations->depth+1)) \ + { \ + /* Make a copy of "moves" because "moves" will be destroyed */\ + existing_state->moves_to_parent = \ + freecell_solver_move_stack_compact_allocate( \ + hard_thread, moves \ + ); \ + if (!(existing_state->visited & FCS_VISITED_DEAD_END)) \ + { \ + if ((--existing_state->parent->num_active_children) == 0) \ + { \ + mark_as_dead_end( \ + existing_state->parent \ + ); \ + } \ + ptr_state_with_locations->num_active_children++; \ + } \ + existing_state->parent = ptr_state_with_locations; \ + existing_state->depth = ptr_state_with_locations->depth + 1; \ + } \ + fcs_derived_states_list_add_state( \ + derived_states_list, \ + existing_state \ + ); \ + } \ + else \ + { \ + fcs_derived_states_list_add_state( \ + derived_states_list, \ + ptr_new_state_with_locations \ + ); \ + } \ +} + + +/* + This macro checks if the top card in the stack is a flipped card + , and if so flips it so its face is up. + */ +#define fcs_flip_top_card(stack) \ +{ \ + int cards_num; \ + cards_num = fcs_stack_len(new_state,stack); \ + \ + if (cards_num > 0) \ + { \ + if (fcs_card_get_flipped( \ + fcs_stack_card( \ + new_state, \ + stack, \ + cards_num-1) \ + ) == 1 \ + ) \ + { \ + fcs_flip_stack_card(new_state,stack,cards_num-1); \ + fcs_move_set_type(temp_move, FCS_MOVE_TYPE_FLIP_CARD); \ + fcs_move_set_src_stack(temp_move, stack); \ + \ + fcs_move_stack_push(moves, temp_move); \ + } \ + } \ +} + + +/* + * dest is the destination stack + * source is the source stack + * start is the start height + * end is the end height + * a is the iterator + * */ +#define fcs_move_sequence(dest, source, start, end, a) \ +{ \ + for ( a = (start) ; a <= (end) ; a++) \ + { \ + fcs_push_stack_card_into_stack(new_state, dest, source, a); \ + } \ + \ + for ( a = (start) ; a <= (end) ; a++) \ + { \ + fcs_pop_stack_card(new_state, source, temp_card); \ + } \ + \ + fcs_move_set_type(temp_move, FCS_MOVE_TYPE_STACK_TO_STACK); \ + fcs_move_set_src_stack(temp_move, source); \ + fcs_move_set_dest_stack(temp_move, dest); \ + fcs_move_set_num_cards_in_seq(temp_move, (end)-(start)+1); \ + \ + fcs_move_stack_push(moves, temp_move); \ +} + +/* + * This test declares a few access variables that are used in all + * the tests. + * */ +#define tests_declare_accessors() \ + freecell_solver_hard_thread_t * hard_thread; \ + freecell_solver_instance_t * instance; \ + fcs_state_with_locations_t * ptr_new_state_with_locations; \ + fcs_move_stack_t * moves; \ + char * indirect_stacks_buffer; \ + int calc_real_depth; \ + int scans_synergy + +/* + * This macro defines these accessors to have some value. + * */ +#define tests_define_accessors() \ + hard_thread = soft_thread->hard_thread; \ + instance = hard_thread->instance; \ + moves = hard_thread->reusable_move_stack; \ + indirect_stacks_buffer = hard_thread->indirect_stacks_buffer; \ + calc_real_depth = instance->calc_real_depth; \ + scans_synergy = instance->scans_synergy; + + + +extern 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 + ); +extern 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 + ); + +extern 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 + ); + +extern 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 + ); + +extern 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 + ); + +extern 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 + ); + +extern 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 + ); + +extern 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 + ); + +#ifdef __cplusplus +} +#endif + +#define my_copy_stack(idx) fcs_copy_stack(new_state_with_locations, idx, indirect_stacks_buffer); + +#endif /* FC_SOLVE__TESTS_H */ |