/* Insert a slice marking the end of the branch * @param si identifies the entry slice of a help branch * @param end_proto end of branch prototype slice * @param parity indicates after which help move of the branch to insert * @return true iff the end could be inserted */ static boolean help_branch_insert_end_of_branch(slice_index si, slice_index end_proto, unsigned int parity) { boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",end_proto); TraceFunctionParam("%u",parity); TraceFunctionParamListEnd(); { slice_index const pos = help_branch_locate_played(si,parity); if (pos==no_slice) result = false; else { help_branch_insert_slices(pos,&end_proto,1); result = true; } } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Instrument a help branch with a STIfThenElse slice * @param adapter identifies adapter slice into the help branch */ void help_branch_insert_check_zigzag(slice_index adapter) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { slice_index const ready = help_branch_locate_ready(adapter); slice_index const proxy1 = alloc_proxy_slice(); slice_index const proxy2 = alloc_proxy_slice(); slice_index const played = alloc_help_move_played_slice(); slice_index const condition = alloc_goal_check_reached_tester_slice(goal_applies_to_starter); slice_index const jump = alloc_if_then_else_slice(proxy1,proxy2,condition); slice_index const landing_proto = alloc_pipe(STCheckZigzagLanding); assert(ready!=no_slice); pipe_link(condition,alloc_true_slice()); help_branch_insert_slices(ready,&landing_proto,1); pipe_link(proxy2,SLICE_NEXT1(ready)); pipe_link(proxy1,played); pipe_link(ready,jump); { slice_index const landing = branch_find_slice(STCheckZigzagLanding, ready, stip_traversal_context_help); assert(landing!=no_slice); link_to_branch(played,landing); } } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static slice_index make_circe_take_make_rebirth_squares_finder(Side side) { slice_index result; slice_index const proxy_branch = alloc_proxy_slice(); slice_index const help = alloc_help_branch(slack_length+1,slack_length+1); slice_index const prototype = alloc_pipe(STTakeMakeCirceCollectRebirthSquares); slice_index const executing = alloc_pipe(STExecutingKingCapture); link_to_branch(proxy_branch,help); help_branch_insert_slices(help,&prototype,1); slice_insertion_insert(help,&executing,1); result = alloc_conditional_pipe(STTakeMakeCirceCollectRebirthSquaresFork,proxy_branch); solving_impose_starter(result,side); return result; }
static void insert_maxsolutions_help_filter(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); { slice_index const prototype = alloc_maxsolutions_guard_slice(); help_branch_insert_slices(si,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Produce slices representing set play. * @param adapter identifies the adapter slice at the beginning of the branch * @param state address of structure holding state */ void help_branch_make_setplay(slice_index adapter, spin_off_state_type *state) { stip_length_type const length = SLICE_U(adapter).branch.length; stip_length_type min_length = SLICE_U(adapter).branch.min_length; TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); assert(SLICE_TYPE(adapter)==STHelpAdapter); if (min_length==0) min_length = 2; if (length>1) { slice_index const next = SLICE_NEXT1(adapter); slice_index const prototypes[] = { alloc_help_adapter_slice(length-1,min_length-1), alloc_pipe(STEndOfRoot) }; enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] }; help_branch_insert_slices(next,prototypes,nr_prototypes); { slice_index const set_adapter = branch_find_slice(STHelpAdapter, next, stip_traversal_context_help); assert(set_adapter!=no_slice); help_branch_make_root_slices(set_adapter,state); state->spun_off[adapter] = state->spun_off[set_adapter]; pipe_remove(set_adapter); } } TraceValue("%u\n",state->spun_off[adapter]); TraceFunctionExit(__func__); TraceFunctionParamListEnd(); }
static void keepmating_filter_inserter_help(slice_index si, stip_structure_traversal *st) { insertion_state_type const * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); { slice_index const prototype = alloc_appropriate_filter(state); if (prototype!=no_slice) { SLICE_STARTER(prototype) = advers(SLICE_STARTER(si)); help_branch_insert_slices(si,&prototype,1); } } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Shorten a help branch by 1 half move * @param identifies entry slice of branch to be shortened */ void help_branch_shorten(slice_index adapter) { slice_index const next = SLICE_NEXT1(adapter); TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); assert(SLICE_TYPE(adapter)==STHelpAdapter); { /* find the new spot for adapter by inserting a copy */ slice_index const prototype = copy_slice(adapter); help_branch_insert_slices(next,&prototype,1); } { /* move adapter to its new spot */ slice_index const copy = branch_find_slice(STHelpAdapter, next, stip_traversal_context_help); assert(copy!=no_slice); pipe_link(SLICE_PREV(adapter),next); pipe_append(copy,adapter); pipe_remove(copy); } /* adjust the length and min_length members */ --SLICE_U(adapter).branch.length; if (SLICE_U(adapter).branch.min_length<=0) increase_min_length(adapter); --SLICE_U(adapter).branch.min_length; branch_shorten_slices(next,STHelpAdapter,stip_traversal_context_help); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Produce slices representing set play. * @param adapter identifies the adapter slice at the beginning of the branch * @param state address of structure holding state */ void series_branch_make_setplay(slice_index adapter, spin_off_state_type *state) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { slice_index const next = SLICE_NEXT1(adapter); slice_index const prototypes[] = { alloc_help_adapter_slice(0,0), alloc_pipe(STEndOfRoot) }; enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] }; help_branch_insert_slices(next,prototypes,nr_prototypes); { slice_index const set_adapter = branch_find_slice(STHelpAdapter, next, stip_traversal_context_help); assert(set_adapter!=no_slice); if (SLICE_TYPE(SLICE_NEXT1(set_adapter))==STDeadEnd) ; /* set play not applicable */ else help_branch_make_root_slices(set_adapter,state); TraceValue("%u\n",state->spun_off[set_adapter]); state->spun_off[adapter] = state->spun_off[set_adapter]; pipe_remove(set_adapter); } } TraceValue("%u\n",state->spun_off[adapter]); TraceFunctionExit(__func__); TraceFunctionParamListEnd(); }
/* Allocate a help branch. * @param length maximum number of half-moves of slice (+ slack) * @param min_length minimum number of half-moves of slice (+ slack) * @param proxy_to_next identifies slice leading towards goal * @return index of entry slice into allocated series branch */ slice_index alloc_help_branch(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); { slice_index const adapter = alloc_help_adapter_slice(length,min_length); slice_index const ready1 = alloc_branch(STReadyForHelpMove, length,min_length); slice_index const testpre1 = alloc_pipe(STTestingPrerequisites); slice_index const generating1 = alloc_pipe(STGeneratingMoves); slice_index const done_generating1 = alloc_pipe(STDoneGeneratingMoves); slice_index const done_removing_illegal1 = alloc_pipe(STDoneRemovingIllegalMoves); slice_index const done_removing_futile1 = alloc_pipe(STDoneRemovingFutileMoves); slice_index const done_priorising1 = alloc_pipe(STDonePriorisingMoves); slice_index const move1 = alloc_pipe(STMove); slice_index const played1 = alloc_help_move_played_slice(); slice_index const not_end_goal1 = alloc_pipe(STNotEndOfBranchGoal); slice_index const ready2 = alloc_branch(STReadyForHelpMove, length-1,min_length-1); slice_index const testpre2 = alloc_pipe(STTestingPrerequisites); slice_index const generating2 = alloc_pipe(STGeneratingMoves); slice_index const done_generating2 = alloc_pipe(STDoneGeneratingMoves); slice_index const done_removing_illegal2 = alloc_pipe(STDoneRemovingIllegalMoves); slice_index const done_removing_futile2 = alloc_pipe(STDoneRemovingFutileMoves); slice_index const done_priorising2 = alloc_pipe(STDonePriorisingMoves); slice_index const move2 = alloc_pipe(STMove); slice_index const played2 = alloc_help_move_played_slice(); slice_index const not_end_goal2 = alloc_pipe(STNotEndOfBranchGoal); slice_index const deadend = alloc_pipe(STDeadEnd); pipe_link(adapter,ready1); pipe_link(ready1,testpre1); pipe_link(testpre1,generating1); pipe_link(generating1,done_generating1); pipe_link(done_generating1,done_removing_illegal1); pipe_link(done_removing_illegal1,done_removing_futile1); pipe_link(done_removing_futile1,done_priorising1); pipe_link(done_priorising1,move1); pipe_link(move1,played1); pipe_link(played1,not_end_goal1); pipe_link(not_end_goal1,ready2); pipe_link(ready2,testpre2); pipe_link(testpre2,generating2); pipe_link(generating2,done_generating2); pipe_link(done_generating2,done_removing_illegal2); pipe_link(done_removing_illegal2,done_removing_futile2); pipe_link(done_removing_futile2,done_priorising2); pipe_link(done_priorising2,move2); pipe_link(move2,played2); pipe_link(played2,not_end_goal2); pipe_link(not_end_goal2,adapter); if (length%2==0) help_branch_insert_slices(adapter,&deadend,1); else help_branch_insert_slices(move1,&deadend,1); result = adapter; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }