2
* tests.h - header file of the test functions for Freecell Solver.
4
* The test functions code is found in freecell.c
6
* Written by Shlomi Fish ( http://www.shlomifish.org/ ), 2000
8
* This file is in the public domain (it's uncopyrighted).
11
#ifndef FC_SOLVE__TESTS_H
12
#define FC_SOLVE__TESTS_H
28
#ifdef FCS_FREECELL_ONLY
29
#define calc_max_sequence_move(fc_num, fs_num) (((fc_num)+1)<<(fs_num))
32
* The number of cards that can be moved is
33
* (freecells_number + 1) * 2 ^ (free_stacks_number)
35
* See the Freecell FAQ and the source code of PySol
38
#define calc_max_sequence_move(fc_num, fs_num) \
39
((instance->unlimited_sequence_move) ? \
41
((instance->empty_stacks_fill == FCS_ES_FILLED_BY_ANY_CARD) ? \
42
(((fc_num)+1)<<(fs_num)) : \
50
* These are some macros to make it easier for the programmer.
52
#define ptr_state_key (ptr_state_key)
53
#define ptr_state_val (ptr_state_val)
54
#define state_key (*ptr_state_key)
55
#define state (state_key)
56
#define state_val (*ptr_state_val)
57
#define new_state (*ptr_new_state_key)
58
#define new_state_key (new_state)
59
#define new_state_val (*ptr_new_state_val)
61
#define sfs_check_state_begin() \
62
fcs_state_ia_alloc_into_var(ptr_new_state_val, hard_thread); \
63
ptr_new_state_key = ptr_new_state_val->key; \
64
fcs_duplicate_state(new_state_key, new_state_val, state_key, state_val); \
65
/* Some A* and BFS parameters that need to be initialized in \
66
* the derived state. \
68
ptr_new_state_val->parent_val = ptr_state_val; \
69
ptr_new_state_val->moves_to_parent = moves; \
70
/* Make sure depth is consistent with the game graph. \
71
* I.e: the depth of every newly discovered state is derived from \
72
* the state from which it was discovered. */ \
73
ptr_new_state_val->depth = ptr_new_state_val->depth + 1; \
74
/* Mark this state as a state that was not yet visited */ \
75
ptr_new_state_val->visited = 0; \
76
/* It's a newly created state which does not have children yet. */ \
77
ptr_new_state_val->num_active_children = 0; \
78
memset(ptr_new_state_val->scan_visited, '\0', \
79
sizeof(ptr_new_state_val->scan_visited) \
81
fcs_move_stack_reset(moves); \
83
#define sfs_check_state_end() \
84
/* The last move in a move stack should be FCS_MOVE_TYPE_CANONIZE \
85
* because it indicates that the order of the stacks and freecells \
86
* need to be recalculated \
88
fcs_move_set_type(temp_move,FCS_MOVE_TYPE_CANONIZE); \
89
fcs_move_stack_push(moves, temp_move); \
92
fcs_state_extra_info_t * existing_state_val; \
93
check = fc_solve_check_and_add_state( \
98
if ((check == FCS_STATE_BEGIN_SUSPEND_PROCESS) || \
99
(check == FCS_STATE_SUSPEND_PROCESS)) \
101
/* This state is not going to be used, so \
102
* let's clean it. */ \
103
fcs_state_ia_release(hard_thread); \
106
else if (check == FCS_STATE_ALREADY_EXISTS) \
108
fcs_state_ia_release(hard_thread); \
109
calculate_real_depth(existing_state_val); \
110
/* Re-parent the existing state to this one. \
112
* What it means is that if the depth of the state if it \
113
* can be reached from this one is lower than what it \
114
* already have, then re-assign its parent to this state. \
117
(existing_state_val->depth > ptr_state_val->depth+1)) \
119
/* Make a copy of "moves" because "moves" will be destroyed */\
120
existing_state_val->moves_to_parent = \
121
fc_solve_move_stack_compact_allocate( \
124
if (!(existing_state_val->visited & FCS_VISITED_DEAD_END)) \
126
if ((--existing_state_val->parent_val->num_active_children) == 0) \
129
existing_state_val->parent_val \
132
ptr_state_val->num_active_children++; \
134
existing_state_val->parent_val = ptr_state_val; \
135
existing_state_val->depth = ptr_state_val->depth + 1; \
137
fc_solve_derived_states_list_add_state( \
138
derived_states_list, \
144
fc_solve_derived_states_list_add_state( \
145
derived_states_list, \
153
This macro checks if the top card in the stack is a flipped card
154
, and if so flips it so its face is up.
156
#define fcs_flip_top_card(stack) \
159
cards_num = fcs_stack_len(new_state,stack); \
163
if (fcs_card_get_flipped( \
171
fcs_flip_stack_card(new_state,stack,cards_num-1); \
172
fcs_move_set_type(temp_move, FCS_MOVE_TYPE_FLIP_CARD); \
173
fcs_move_set_src_stack(temp_move, stack); \
175
fcs_move_stack_push(moves, temp_move); \
182
* dest is the destination stack
183
* source is the source stack
184
* start is the start height
185
* end is the end height
188
#define fcs_move_sequence(dest, source, start, end, a) \
190
for ( a = (start) ; a <= (end) ; a++) \
192
fcs_push_stack_card_into_stack(new_state, dest, source, a); \
195
for ( a = (start) ; a <= (end) ; a++) \
197
fcs_pop_stack_card(new_state, source, temp_card); \
200
fcs_move_set_type(temp_move, FCS_MOVE_TYPE_STACK_TO_STACK); \
201
fcs_move_set_src_stack(temp_move, source); \
202
fcs_move_set_dest_stack(temp_move, dest); \
203
fcs_move_set_num_cards_in_seq(temp_move, (end)-(start)+1); \
205
fcs_move_stack_push(moves, temp_move); \
208
#ifdef FCS_FREECELL_ONLY
209
#define tests_declare_accessors_freecell_only()
211
#define tests_declare_accessors_freecell_only() \
212
int sequences_are_built_by; \
213
int empty_stacks_fill;
217
* This test declares a few access variables that are used in all
220
#define tests_declare_accessors() \
221
fc_solve_hard_thread_t * hard_thread; \
222
fc_solve_instance_t * instance; \
223
fcs_state_t * ptr_state_key; \
224
fcs_state_t * ptr_new_state_key; \
225
fcs_state_extra_info_t * ptr_new_state_val; \
226
fcs_move_stack_t * moves; \
227
char * indirect_stacks_buffer; \
228
int calc_real_depth; \
230
tests_declare_accessors_freecell_only()
232
#ifdef FCS_FREECELL_ONLY
234
#define tests_define_accessors_freecell_only() {}
236
#define tests__is_filled_by_any_card() 1
238
#define tests__is_filled_by_kings_only() 0
240
#define tests__is_filled_by_none() 0
244
#define tests_define_accessors_freecell_only() \
246
sequences_are_built_by = instance->sequences_are_built_by; \
247
empty_stacks_fill = instance->empty_stacks_fill; \
250
#define tests__is_filled_by_any_card() \
251
(empty_stacks_fill == FCS_ES_FILLED_BY_ANY_CARD)
253
#define tests__is_filled_by_kings_only() \
254
(empty_stacks_fill == FCS_ES_FILLED_BY_KINGS_ONLY)
256
#define tests__is_filled_by_none() \
257
(empty_stacks_fill == FCS_ES_FILLED_BY_NONE)
262
* This macro defines these accessors to have some value.
264
#define tests_define_accessors() \
265
ptr_state_key = ptr_state_val->key; \
266
hard_thread = soft_thread->hard_thread; \
267
instance = hard_thread->instance; \
268
moves = hard_thread->reusable_move_stack; \
269
indirect_stacks_buffer = hard_thread->indirect_stacks_buffer; \
270
calc_real_depth = instance->calc_real_depth; \
271
scans_synergy = instance->scans_synergy; \
272
tests_define_accessors_freecell_only()
274
extern int fc_solve_sfs_simple_simon_move_sequence_to_founds(
275
fc_solve_soft_thread_t * soft_thread,
276
fcs_state_extra_info_t * ptr_state_val,
279
fcs_derived_states_list_t * derived_states_list,
282
extern int fc_solve_sfs_simple_simon_move_sequence_to_true_parent(
283
fc_solve_soft_thread_t * soft_thread,
284
fcs_state_extra_info_t * ptr_state_val,
287
fcs_derived_states_list_t * derived_states_list,
291
extern int fc_solve_sfs_simple_simon_move_whole_stack_sequence_to_false_parent(
292
fc_solve_soft_thread_t * soft_thread,
293
fcs_state_extra_info_t * ptr_state_val,
296
fcs_derived_states_list_t * derived_states_list,
300
extern int fc_solve_sfs_simple_simon_move_sequence_to_true_parent_with_some_cards_above(
301
fc_solve_soft_thread_t * soft_thread,
302
fcs_state_extra_info_t * ptr_state_val,
305
fcs_derived_states_list_t * derived_states_list,
309
extern int fc_solve_sfs_simple_simon_move_sequence_with_some_cards_above_to_true_parent(
310
fc_solve_soft_thread_t * soft_thread,
311
fcs_state_extra_info_t * ptr_state_val,
314
fcs_derived_states_list_t * derived_states_list,
318
extern int fc_solve_sfs_simple_simon_move_sequence_with_junk_seq_above_to_true_parent_with_some_cards_above(
319
fc_solve_soft_thread_t * soft_thread,
320
fcs_state_extra_info_t * ptr_state_val,
323
fcs_derived_states_list_t * derived_states_list,
327
extern int fc_solve_sfs_simple_simon_move_whole_stack_sequence_to_false_parent_with_some_cards_above(
328
fc_solve_soft_thread_t * soft_thread,
329
fcs_state_extra_info_t * ptr_state_val,
332
fcs_derived_states_list_t * derived_states_list,
336
extern int fc_solve_sfs_simple_simon_move_sequence_to_parent_on_the_same_stack(
337
fc_solve_soft_thread_t * soft_thread,
338
fcs_state_extra_info_t * ptr_state_val,
341
fcs_derived_states_list_t * derived_states_list,
349
#define my_copy_stack(idx) fcs_copy_stack(new_state_key, new_state_val, idx, indirect_stacks_buffer);
351
#endif /* FC_SOLVE__TESTS_H */