118
static GCC_INLINE void free_states_handle_soft_dfs_soft_thread(
119
fc_solve_soft_thread_t * soft_thread
122
fcs_soft_dfs_stack_item_t * soft_dfs_info =
123
soft_thread->method_specific.soft_dfs.soft_dfs_info;
124
fcs_soft_dfs_stack_item_t * const end_soft_dfs_info =
125
soft_dfs_info + soft_thread->method_specific.soft_dfs.depth;
127
for(;soft_dfs_info < end_soft_dfs_info; soft_dfs_info++)
129
int * rand_index_ptr, * dest_rand_index_ptr, * end_rand_index_ptr;
130
fcs_derived_states_list_item_t * const states =
131
soft_dfs_info->derived_states_list.states;
133
* We start from current_state_index instead of current_state_index+1
134
* because that is the next state to be checked - it is referenced
135
* by current_state_index++ instead of ++current_state_index .
137
dest_rand_index_ptr = rand_index_ptr =
138
soft_dfs_info->derived_states_random_indexes
139
+ soft_dfs_info->current_state_index
142
soft_dfs_info->derived_states_random_indexes
143
+ soft_dfs_info->derived_states_list.num_states
146
for( ; rand_index_ptr < end_rand_index_ptr ; rand_index_ptr++ )
148
if (! FCS_IS_STATE_DEAD_END(states[*(rand_index_ptr)].state_ptr))
150
*(dest_rand_index_ptr++) = *(rand_index_ptr);
153
soft_dfs_info->derived_states_list.num_states =
154
dest_rand_index_ptr - soft_dfs_info->derived_states_random_indexes;
162
static void verify_state_sanity(
163
fcs_state_t * ptr_state
168
for (i=0; i < 8 ; i++)
170
int l = fcs_col_len(fcs_state_get_col(*(ptr_state), i));
171
assert ((l >= 0) && (l <= 7+12));
177
#ifdef DEBUG_VERIFY_SOFT_DFS_STACK
178
static void verify_soft_dfs_stack(
179
fc_solve_soft_thread_t * soft_thread
182
int depth = 0, i, num_states;
183
for (depth = 0 ; depth < soft_thread->method_specific.soft_dfs.depth ; depth++)
185
fcs_soft_dfs_stack_item_t * soft_dfs_info;
188
soft_dfs_info = &(soft_thread->method_specific.soft_dfs.soft_dfs_info[depth]);
189
rand_indexes = soft_dfs_info->derived_states_random_indexes;
191
num_states = soft_dfs_info->derived_states_list.num_states;
193
for ( i=soft_dfs_info->current_state_index ; i < num_states ; i++)
195
verify_state_sanity(soft_dfs_info->derived_states_list.states[rand_indexes[i]].state_ptr);
201
#define VERIFY_SOFT_DFS_STACK(soft_thread) verify_soft_dfs_stack(soft_thread)
203
#define VERIFY_SOFT_DFS_STACK(soft_thread)
112
208
static void free_states(fc_solve_instance_t * instance)
211
printf("%s\n", "FREE_STATES HIT");
213
#if (! ((FCS_STATE_STORAGE == FCS_STATE_STORAGE_INTERNAL_HASH) || (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GOOGLE_DENSE_HASH)))
217
HT_LOOP_DECLARE_VARS();
114
219
/* First of all, let's make sure the soft_threads will no longer
115
220
* traverse to the freed states that are currently dead end.
118
HT_LOOP_DECLARE_VARS();
215
290
((void *)instance)
221
fc_solve_soft_dfs_do_solve is the event loop of the
222
Random-DFS scan. DFS which is recursive in nature is handled here
223
without procedural recursion
224
by using some dedicated stacks for the traversal.
297
#define STATE_TO_PASS() (&(pass))
298
#define NEW_STATE_TO_PASS() (&(new_pass))
226
300
#ifdef FCS_RCS_STATES
302
#define INITIALIZE_STATE() pass.key = &(state_key)
227
303
#define the_state (state_key)
304
#define VERIFY_DERIVED_STATE() {}
305
#define FCS_ASSIGN_STATE_KEY() (state_key = (*(fc_solve_lookup_state_key_from_val(instance, PTR_STATE))))
306
#define PTR_STATE (pass.val)
307
#define DECLARE_STATE() fcs_state_t state_key; fcs_kv_state_t pass
308
#define DECLARE_NEW_STATE() fcs_kv_state_t new_pass
309
#define ptr_new_state (new_pass.val)
229
#define the_state (ptr_state->s)
313
#define INITIALIZE_STATE() {}
314
#define the_state (PTR_STATE->s)
315
#define VERIFY_DERIVED_STATE() verify_state_sanity(&(single_derived_state->s))
316
#define FCS_ASSIGN_STATE_KEY() { pass.key = &(the_state); pass.val = &(PTR_STATE->info); }
317
#define PTR_STATE (ptr_state_raw)
318
#define DECLARE_STATE() fcs_collectible_state_t * ptr_state_raw; fcs_kv_state_t pass
319
#define DECLARE_NEW_STATE() fcs_collectible_state_t * ptr_new_state; fcs_kv_state_t new_pass
322
#define ASSIGN_ptr_state(my_value) { if ((PTR_STATE = my_value)) { FCS_ASSIGN_STATE_KEY(); } }
233
325
#define TRACE0(message) \
235
327
if (getenv("FCS_TRACE")) \
237
printf("%s. Depth=%d ; the_soft_Depth=%d ; Iters=%d ; test_index=%d ; current_state_index=%d ; num_states=%d\n", \
329
printf("%s. Depth=%d ; the_soft_Depth=%ld ; Iters=%d ; test_index=%d ; current_state_index=%d ; num_states=%d\n", \
239
soft_thread->method_specific.soft_dfs.depth, (the_soft_dfs_info-soft_thread->method_specific.soft_dfs.soft_dfs_info), \
331
soft_thread->method_specific.soft_dfs.depth, \
332
(long int)(the_soft_dfs_info-soft_thread->method_specific.soft_dfs.soft_dfs_info), \
240
333
instance->num_times, the_soft_dfs_info->test_index, \
241
334
the_soft_dfs_info->current_state_index, \
242
335
(derived_states_list ? derived_states_list->num_states : -1) \
244
337
fflush(stdout); \
341
#define VERIFY_STATE_SANITY() verify_state_sanity(&the_state)
343
#define VERIFY_PTR_STATE_TRACE0(string) \
346
VERIFY_STATE_SANITY(); \
347
VERIFY_SOFT_DFS_STACK(soft_thread); \
351
#define VERIFY_PTR_STATE_AND_DERIVED_TRACE0(string) \
354
VERIFY_STATE_SANITY(); \
355
VERIFY_DERIVED_STATE(); \
356
VERIFY_SOFT_DFS_STACK(soft_thread); \
248
361
#define TRACE0(no_use) {}
362
#define VERIFY_PTR_STATE_TRACE0(no_use) {}
363
#define VERIFY_PTR_STATE_AND_DERIVED_TRACE0(no_use) {}
367
#ifndef FCS_WITHOUT_DEPTH_FIELD
252
* This macro traces the path of the state up to the original state,
253
* and thus calculates its real depth.
369
* The calculate_real_depth() inline function traces the path of the state up
370
* to the original state, and thus calculates its real depth.
255
372
* It then assigns the newly updated depth throughout the path.
259
#define calculate_real_depth(ptr_state_orig) \
261
if (calc_real_depth) \
263
int this_real_depth = 0; \
264
fcs_collectible_state_t * temp_state = ptr_state_orig; \
265
/* Count the number of states until the original state. */ \
266
while(temp_state != NULL) \
268
temp_state = FCS_S_PARENT(temp_state); \
272
temp_state = (ptr_state_orig); \
273
/* Assign the new depth throughout the path */ \
274
while (FCS_S_DEPTH(temp_state) != this_real_depth) \
276
FCS_S_DEPTH(temp_state) = this_real_depth; \
278
temp_state = FCS_S_PARENT(temp_state); \
376
static GCC_INLINE void calculate_real_depth(fcs_bool_t calc_real_depth, fcs_collectible_state_t * ptr_state_orig)
380
int this_real_depth = 0;
381
fcs_collectible_state_t * temp_state = ptr_state_orig;
382
/* Count the number of states until the original state. */
383
while(temp_state != NULL)
385
temp_state = FCS_S_PARENT(temp_state);
389
temp_state = (ptr_state_orig);
390
/* Assign the new depth throughout the path */
391
while (FCS_S_DEPTH(temp_state) != this_real_depth)
393
FCS_S_DEPTH(temp_state) = this_real_depth;
395
temp_state = FCS_S_PARENT(temp_state);
402
#define calculate_real_depth(calc_real_depth, ptr_state_orig) {}
284
* This macro marks a state as a dead end, and afterwards propogates
285
* this information to its parent and ancestor states.
406
* The mark_as_dead_end() inline function marks a state as a dead end, and
407
* afterwards propogates this information to its parent and ancestor states.
288
#define mark_as_dead_end(ptr_state_input) \
292
fcs_collectible_state_t * temp_state = (ptr_state_input); \
293
/* Mark as a dead end */ \
294
FCS_S_VISITED(temp_state)|= FCS_VISITED_DEAD_END; \
295
temp_state = FCS_S_PARENT(temp_state); \
296
if (temp_state != NULL) \
298
/* Decrease the refcount of the state */ \
299
(FCS_S_NUM_ACTIVE_CHILDREN(temp_state))--; \
300
while((FCS_S_NUM_ACTIVE_CHILDREN(temp_state) == 0) && (FCS_S_VISITED(temp_state) & FCS_VISITED_ALL_TESTS_DONE)) \
302
/* Mark as dead end */ \
303
FCS_S_VISITED(temp_state) |= FCS_VISITED_DEAD_END; \
304
/* Go to its parent state */ \
305
temp_state = FCS_S_PARENT(temp_state); \
306
if (temp_state == NULL) \
310
/* Decrease the refcount */ \
311
(FCS_S_NUM_ACTIVE_CHILDREN(temp_state))--; \
411
static GCC_INLINE void mark_as_dead_end(fcs_bool_t scans_synergy, fcs_collectible_state_t * ptr_state_input)
415
fcs_collectible_state_t * temp_state = (ptr_state_input);
416
/* Mark as a dead end */
417
FCS_S_VISITED(temp_state)|= FCS_VISITED_DEAD_END;
418
temp_state = FCS_S_PARENT(temp_state);
419
if (temp_state != NULL)
421
/* Decrease the refcount of the state */
422
(FCS_S_NUM_ACTIVE_CHILDREN(temp_state))--;
423
while((FCS_S_NUM_ACTIVE_CHILDREN(temp_state) == 0) && (FCS_S_VISITED(temp_state) & FCS_VISITED_ALL_TESTS_DONE))
425
/* Mark as dead end */
426
FCS_S_VISITED(temp_state) |= FCS_VISITED_DEAD_END;
427
/* Go to its parent state */
428
temp_state = FCS_S_PARENT(temp_state);
429
if (temp_state == NULL)
433
/* Decrease the refcount */
434
(FCS_S_NUM_ACTIVE_CHILDREN(temp_state))--;
317
442
#define BUMP_NUM_TIMES() \
319
instance->num_times++; \
320
hard_thread->num_times++; \
444
(*instance_num_times_ptr)++; \
445
(*hard_thread_num_times_ptr)++; \
323
448
#define SHOULD_STATE_BE_PRUNED(enable_pruning, ptr_state) \
570
#define ASSIGN_STATE_KEY() (state_key = (*(fc_solve_lookup_state_key_from_val(instance, ptr_state))))
752
static GCC_INLINE fcs_game_limit_t count_num_vacant_freecells(
753
fcs_game_limit_t freecells_num,
754
fcs_state_t * state_ptr
757
fcs_game_limit_t num_vacant_freecells = 0;
760
for(i=0;i<freecells_num;i++)
762
if (fcs_freecell_card_num(*state_ptr, i) == 0)
764
num_vacant_freecells++;
768
return num_vacant_freecells;
771
static GCC_INLINE fcs_game_limit_t count_num_vacant_stacks(
772
fcs_game_limit_t stacks_num,
773
fcs_state_t * state_ptr
776
fcs_game_limit_t num_vacant_stacks = 0;
779
for ( i=0 ; i < stacks_num ; i++ )
781
if (fcs_col_len(fcs_state_get_col(*state_ptr, i)) == 0)
787
return num_vacant_stacks;
792
* fc_solve_soft_dfs_do_solve() is the event loop of the
793
* Random-DFS scan. DFS which is recursive in nature is handled here
794
* without procedural recursion by using some dedicated stacks for
572
797
int fc_solve_soft_dfs_do_solve(
573
fc_solve_soft_thread_t * soft_thread
798
fc_solve_soft_thread_t * const soft_thread
576
fc_solve_hard_thread_t * hard_thread = soft_thread->hard_thread;
577
fc_solve_instance_t * instance = hard_thread->instance;
579
#ifdef FCS_RCS_STATES
580
fcs_state_t state_key;
582
fcs_collectible_state_t * ptr_state;
801
fc_solve_hard_thread_t * const hard_thread = soft_thread->hard_thread;
802
fc_solve_instance_t * const instance = hard_thread->instance;
583
806
fcs_soft_dfs_stack_item_t * the_soft_dfs_info;
584
807
#if ((!defined(HARD_CODED_NUM_FREECELLS)) || (!defined(HARD_CODED_NUM_STACKS)))
585
808
DECLARE_GAME_PARAMS();
600
823
fcs_bool_t local_to_randomize = FALSE;
602
825
fcs_bool_t enable_pruning;
826
int * instance_num_times_ptr, * hard_thread_num_times_ptr;
827
int hard_thread_max_num_times;
828
fcs_instance_debug_iter_output_func_t debug_iter_output_func;
829
fcs_instance_debug_iter_output_context_t debug_iter_output_context;
604
831
#if ((!defined(HARD_CODED_NUM_FREECELLS)) || (!defined(HARD_CODED_NUM_STACKS)))
605
832
SET_GAME_PARAMS();
835
#define DEPTH() (*depth_ptr)
836
depth_ptr = &(soft_thread->method_specific.soft_dfs.depth);
609
the_soft_dfs_info = &(soft_thread->method_specific.soft_dfs.soft_dfs_info[soft_thread->method_specific.soft_dfs.depth]);
838
the_soft_dfs_info = &(soft_thread->method_specific.soft_dfs.soft_dfs_info[DEPTH()]);
611
840
dfs_max_depth = soft_thread->method_specific.soft_dfs.dfs_max_depth;
612
841
enable_pruning = soft_thread->enable_pruning;
614
ptr_state = the_soft_dfs_info->state;
843
ASSIGN_ptr_state (the_soft_dfs_info->state);
615
844
derived_states_list = &(the_soft_dfs_info->derived_states_list);
617
#ifdef FCS_RCS_STATES
621
846
rand_gen = &(soft_thread->method_specific.soft_dfs.rand_gen);
623
#ifndef FCS_WITHOUT_DEPTH_FIELD
624
calculate_real_depth(
848
calculate_real_depth(calc_real_depth, PTR_STATE);
629
850
by_depth_units = soft_thread->method_specific.soft_dfs.tests_by_depth_array.by_depth_units;
742
977
fcs_game_limit_t num_vacant_stacks, num_vacant_freecells;
745
979
TRACE0("In iter_handler");
747
if (instance->debug_iter_output_func)
981
if (debug_iter_output_func)
750
984
printf("ST Name: %s\n", soft_thread->name);
752
instance->debug_iter_output_func(
753
(void*)instance->debug_iter_output_context,
755
soft_thread->method_specific.soft_dfs.depth,
986
debug_iter_output_func(
987
debug_iter_output_context,
988
*(instance_num_times_ptr),
757
#ifdef FCS_RCS_STATES
761
992
#ifdef FCS_WITHOUT_VISITED_ITER
764
((soft_thread->method_specific.soft_dfs.depth == 0) ?
766
FCS_S_VISITED_ITER(soft_thread->method_specific.soft_dfs.soft_dfs_info[soft_thread->method_specific.soft_dfs.depth-1].state)
997
FCS_S_VISITED_ITER(soft_thread->method_specific.soft_dfs.soft_dfs_info[DEPTH()-1].state)
772
/* Count the free-cells */
773
num_vacant_freecells = 0;
774
for(i=0;i<LOCAL_FREECELLS_NUM;i++)
776
if (fcs_freecell_card_num(the_state, i) == 0)
778
num_vacant_freecells++;
782
/* Count the number of unoccupied stacks */
784
num_vacant_stacks = 0;
785
for(i=0;i<LOCAL_STACKS_NUM;i++)
787
if (fcs_col_len(fcs_state_get_col(the_state, i)) == 0)
1003
num_vacant_freecells =
1004
count_num_vacant_freecells(LOCAL_FREECELLS_NUM, &the_state);
1007
count_num_vacant_stacks(LOCAL_STACKS_NUM, &the_state);
793
1009
/* Check if we have reached the empty state */
794
1010
if (unlikely((num_vacant_stacks == LOCAL_STACKS_NUM) &&
795
1011
(num_vacant_freecells == LOCAL_FREECELLS_NUM)))
797
instance->final_state = ptr_state;
1013
instance->final_state = PTR_STATE;
799
1015
BUMP_NUM_TIMES();
2036
2226
return *positions_by_rank_location;
2038
#ifdef FCS_RCS_STATES
2039
2228
#undef state_key
2229
#undef ptr_state_key
2043
2232
* These functions are used by the move functions in freecell.c and
2046
2235
int fc_solve_sfs_check_state_begin(
2047
fc_solve_hard_thread_t * hard_thread,
2048
#ifdef FCS_RCS_STATES
2049
fcs_state_t * out_new_state_key,
2051
fcs_collectible_state_t * * out_ptr_new_state,
2052
#ifdef FCS_RCS_STATES
2053
fcs_state_t * ptr_state_key,
2055
fcs_collectible_state_t * ptr_state,
2056
fcs_move_stack_t * moves
2236
fc_solve_hard_thread_t * const hard_thread,
2237
fcs_kv_state_t * const out_new_state_out,
2238
fcs_kv_state_t * const raw_ptr_state_raw,
2239
fcs_move_stack_t * const moves
2059
fcs_collectible_state_t * ptr_new_state;
2060
fc_solve_instance_t * instance;
2062
instance = hard_thread->instance;
2242
#define ptr_state (raw_ptr_state_raw->val)
2243
fcs_collectible_state_t * raw_ptr_new_state;
2244
fc_solve_instance_t * const instance = hard_thread->instance;
2064
2246
if ((hard_thread->allocated_from_list =
2065
2247
(instance->list_of_vacant_states != NULL)))
2067
ptr_new_state = instance->list_of_vacant_states;
2249
raw_ptr_new_state = instance->list_of_vacant_states;
2068
2250
instance->list_of_vacant_states = FCS_S_NEXT(instance->list_of_vacant_states);
2073
2255
fcs_state_ia_alloc_into_var(
2074
2256
&(hard_thread->allocator)
2078
fcs_duplicate_state(
2079
#ifdef FCS_RCS_STATES
2083
#ifdef FCS_RCS_STATES
2260
FCS_STATE_collectible_to_kv(out_new_state_out, raw_ptr_new_state);
2261
fcs_duplicate_kv_state(
2265
#ifdef FCS_RCS_STATES
2266
#define INFO_STATE_PTR(kv_ptr) ((kv_ptr)->val)
2268
/* TODO : That's very hacky - get rid of it. */
2269
#define INFO_STATE_PTR(kv_ptr) ((fcs_state_keyval_pair_t *)((kv_ptr)->key))
2088
2271
/* Some BeFS and BFS parameters that need to be initialized in
2089
2272
* the derived state.
2091
FCS_S_PARENT(ptr_new_state) = ptr_state;
2092
FCS_S_MOVES_TO_PARENT(ptr_new_state) = moves;
2274
FCS_S_PARENT(raw_ptr_new_state) = INFO_STATE_PTR(raw_ptr_state_raw);
2275
FCS_S_MOVES_TO_PARENT(raw_ptr_new_state) = moves;
2093
2276
/* Make sure depth is consistent with the game graph.
2094
2277
* I.e: the depth of every newly discovered state is derived from
2095
2278
* the state from which it was discovered. */
2096
2279
#ifndef FCS_WITHOUT_DEPTH_FIELD
2097
(FCS_S_DEPTH(ptr_new_state))++;
2280
(FCS_S_DEPTH(raw_ptr_new_state))++;
2099
2282
/* Mark this state as a state that was not yet visited */
2100
FCS_S_VISITED(ptr_new_state) = 0;
2283
FCS_S_VISITED(raw_ptr_new_state) = 0;
2101
2284
/* It's a newly created state which does not have children yet. */
2102
FCS_S_NUM_ACTIVE_CHILDREN(ptr_new_state) = 0;
2103
memset(&(FCS_S_SCAN_VISITED(ptr_new_state)), '\0',
2104
sizeof(FCS_S_SCAN_VISITED(ptr_new_state))
2285
FCS_S_NUM_ACTIVE_CHILDREN(raw_ptr_new_state) = 0;
2286
memset(&(FCS_S_SCAN_VISITED(raw_ptr_new_state)), '\0',
2287
sizeof(FCS_S_SCAN_VISITED(raw_ptr_new_state))
2106
2289
fcs_move_stack_reset(moves);
2108
*out_ptr_new_state = ptr_new_state;
2113
2295
extern void fc_solve_sfs_check_state_end(
2114
fc_solve_soft_thread_t * soft_thread,
2115
#ifdef FCS_RCS_STATES
2116
fcs_state_t * ptr_state_key,
2118
fcs_collectible_state_t * ptr_state,
2119
#ifdef FCS_RCS_STATES
2120
fcs_state_t * ptr_new_state_key,
2122
fcs_collectible_state_t * ptr_new_state,
2123
int state_context_value,
2124
fcs_move_stack_t * moves,
2125
fcs_derived_states_list_t * derived_states_list
2296
fc_solve_soft_thread_t * const soft_thread,
2297
fcs_kv_state_t * const raw_ptr_state_raw,
2298
fcs_kv_state_t * const raw_ptr_new_state_raw,
2299
const int state_context_value,
2300
fcs_move_stack_t * const moves,
2301
fcs_derived_states_list_t * const derived_states_list
2128
fcs_internal_move_t temp_move;
2129
fc_solve_hard_thread_t * hard_thread;
2130
fc_solve_instance_t * instance;
2131
fcs_runtime_flags_t calc_real_depth;
2132
fcs_runtime_flags_t scans_synergy;
2133
fcs_collectible_state_t * existing_state;
2135
#ifdef FCS_RCS_STATES
2136
fcs_state_t * existing_state_key;
2304
fc_solve_hard_thread_t * const hard_thread = soft_thread->hard_thread;
2305
fc_solve_instance_t * const instance = hard_thread->instance;
2306
#ifndef FCS_WITHOUT_DEPTH_FIELD
2307
const fcs_runtime_flags_t calc_real_depth
2308
= STRUCT_QUERY_FLAG(instance, FCS_RUNTIME_CALC_REAL_DEPTH);
2309
const fcs_runtime_flags_t scans_synergy
2310
= STRUCT_QUERY_FLAG(instance, FCS_RUNTIME_SCANS_SYNERGY);
2139
temp_move = fc_solve_empty_move;
2141
hard_thread = soft_thread->hard_thread;
2142
instance = hard_thread->instance;
2144
calc_real_depth = STRUCT_QUERY_FLAG(instance, FCS_RUNTIME_CALC_REAL_DEPTH);
2145
scans_synergy = STRUCT_QUERY_FLAG(instance, FCS_RUNTIME_SCANS_SYNERGY);
2312
fcs_kv_state_t existing_state;
2314
#define ptr_new_state_foo (raw_ptr_new_state_raw->val)
2315
#define ptr_state (raw_ptr_state_raw->val)
2147
2317
if (! fc_solve_check_and_add_state(
2149
#ifdef FCS_RCS_STATES
2153
#ifdef FCS_RCS_STATES
2154
&existing_state_key,
2319
raw_ptr_new_state_raw,
2156
2320
&existing_state
2323
#define existing_state_val (existing_state.val)
2159
2324
if (hard_thread->allocated_from_list)
2161
FCS_S_NEXT(ptr_new_state) = instance->list_of_vacant_states;
2162
instance->list_of_vacant_states = ptr_new_state;
2326
ptr_new_state_foo->parent = instance->list_of_vacant_states;
2327
instance->list_of_vacant_states = INFO_STATE_PTR(raw_ptr_new_state_raw);
2166
2331
fcs_compact_alloc_release(&(hard_thread->allocator));
2168
2334
#ifndef FCS_WITHOUT_DEPTH_FIELD
2169
calculate_real_depth(existing_state);
2335
calculate_real_depth (calc_real_depth, FCS_STATE_kv_to_collectible(&existing_state));
2170
2337
/* Re-parent the existing state to this one.
2172
2339
* What it means is that if the depth of the state if it
2174
2341
* already have, then re-assign its parent to this state.
2176
2343
if (STRUCT_QUERY_FLAG(instance, FCS_RUNTIME_TO_REPARENT_STATES_REAL) &&
2177
(FCS_S_DEPTH(existing_state) > FCS_S_DEPTH(ptr_state)+1))
2344
(existing_state_val->depth > ptr_state->depth+1))
2179
2346
/* Make a copy of "moves" because "moves" will be destroyed */
2180
FCS_S_MOVES_TO_PARENT(existing_state) =
2347
existing_state_val->moves_to_parent =
2181
2348
fc_solve_move_stack_compact_allocate(
2182
2349
hard_thread, moves
2184
if (!(FCS_S_VISITED(existing_state) & FCS_VISITED_DEAD_END))
2351
if (!(existing_state_val->visited & FCS_VISITED_DEAD_END))
2186
if ((--(FCS_S_NUM_ACTIVE_CHILDREN(FCS_S_PARENT(existing_state)))) == 0)
2353
if ((--(FCS_S_NUM_ACTIVE_CHILDREN(existing_state_val->parent))) == 0)
2189
FCS_S_PARENT(existing_state)
2355
mark_as_dead_end(scans_synergy, existing_state_val->parent);
2192
FCS_S_NUM_ACTIVE_CHILDREN(ptr_state)++;
2357
ptr_state->num_active_children++;
2194
FCS_S_PARENT(existing_state) = ptr_state;
2195
FCS_S_DEPTH(existing_state) = FCS_S_DEPTH(ptr_state) + 1;
2359
existing_state_val->parent = INFO_STATE_PTR(raw_ptr_state_raw);
2360
existing_state_val->depth = ptr_state->depth + 1;
2198
2365
fc_solve_derived_states_list_add_state(
2199
2366
derived_states_list,
2367
FCS_STATE_kv_to_collectible(&existing_state),
2201
2368
state_context_value
2206
2374
fc_solve_derived_states_list_add_state(
2207
2375
derived_states_list,
2376
INFO_STATE_PTR(raw_ptr_new_state_raw),
2209
2377
state_context_value