static void insert_maxthreatlength_guard(slice_index si, stip_structure_traversal *st) { stip_length_type const length = SLICE_U(si).branch.length; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); if (length>=2*max_len_threat+slack_length) { boolean * const inserted = st->param; slice_index const threat_start = branch_find_slice(STMaxThreatLengthStart, si, st->context); slice_index const proxy = alloc_proxy_slice(); slice_index const dummy = alloc_pipe(STDummyMove); slice_index const played = alloc_defense_played_slice(); slice_index const prototype = alloc_maxthreatlength_guard(proxy); assert(threat_start!=no_slice); pipe_link(proxy,dummy); pipe_link(dummy,played); link_to_branch(played,threat_start); defense_branch_insert_slices(si,&prototype,1); *inserted = true; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void substitute_deadend_goal(slice_index si, stip_moves_traversal *st) { optimisation_state * const state = st->param; slice_index const save_optimisable_deadend = state->optimisable_deadend; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_moves_children(si,st); TraceValue("%u",state->optimisable_deadend); TraceValue("%u",state->end_of_branch_goal); TraceValue("%u\n",st->context); if (state->optimisable_deadend!=no_slice && state->end_of_branch_goal!=no_slice && st->context!=stip_traversal_context_attack) { slice_index const prototype = alloc_pipe(STDeadEndGoal); defense_branch_insert_slices(si,&prototype,1); pipe_remove(state->optimisable_deadend); } state->optimisable_deadend = save_optimisable_deadend; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_continuation_solvers_attack(slice_index si, stip_structure_traversal *st) { boolean const * const attack_played = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); if (*attack_played && st->context==stip_traversal_context_defense) { slice_index const prototypes[] = { alloc_pipe(STSolvingContinuation), alloc_continuation_solver_slice() }; enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] }; defense_branch_insert_slices(si,prototypes,nr_prototypes); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void keepmating_filter_inserter_battle(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); if (st->context!=stip_traversal_context_help) { insertion_state_type const * const state = st->param; slice_index const prototype = alloc_appropriate_filter(state); if (prototype!=no_slice) { SLICE_STARTER(prototype) = SLICE_STARTER(si); if (st->context==stip_traversal_context_attack) attack_branch_insert_slices(si,&prototype,1); else defense_branch_insert_slices(si,&prototype,1); } } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_play_suppressors(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (st->context==stip_traversal_context_defense) { slice_index const prototype = alloc_play_suppressor_slice(); defense_branch_insert_slices(si,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Instrument a battle branch with a STIfThenElse slice providing a * shortcut for the defense moe * @param adapter identifies adapter slice into the battle branch */ void battle_branch_insert_defense_check_zigzag(slice_index adapter) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { slice_index const ready = branch_find_slice(STReadyForDefense, adapter, stip_traversal_context_intro); slice_index const deadend = branch_find_slice(STDeadEnd, ready, stip_traversal_context_defense); slice_index const proxy1 = alloc_proxy_slice(); slice_index const proxy2 = alloc_proxy_slice(); slice_index const dummy = alloc_pipe(STDummyMove); slice_index const played = alloc_defense_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); assert(deadend!=no_slice); pipe_link(condition,alloc_true_slice()); defense_branch_insert_slices(ready,&landing_proto,1); pipe_link(proxy2,SLICE_NEXT1(deadend)); /* the dummy move is needed to make sure that the killer move mechanism * applies to the same play whether the attacker has delivered check or not * TODO only insert the dummy move if the killer move optimisation is used */ pipe_link(proxy1,dummy); pipe_link(dummy,played); pipe_link(deadend,jump); { slice_index const landing = branch_find_slice(STCheckZigzagLanding, deadend, stip_traversal_context_defense); assert(landing!=no_slice); link_to_branch(played,landing); } } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void ready_for_defense_make_root(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); { slice_index const prototype = alloc_pipe(STEndOfRoot); defense_branch_insert_slices(si,&prototype,1); } pipe_spin_off_copy(si,st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void instrument_defense(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children(si,st); if (st->context==stip_traversal_context_defense) { slice_index const prototype = alloc_pipe(STRepublicanType1DeadEnd); defense_branch_insert_slices(si,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_solver(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (SLICE_U(si).branch.length>slack_length+1) { slice_index const prototype = alloc_testing_pipe(STThreatSolver); defense_branch_insert_slices(si,&prototype,1); stip_traverse_structure_children_pipe(si,st); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Produce slices representing set play. * This is supposed to be invoked from within the slice type specific * functions invoked by stip_apply_setplay. * @param adapter identifies the adapter slice into the battle branch * @param state address of structure holding state */ void battle_branch_make_setplay(slice_index adapter, spin_off_state_type *state) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { slice_index const start = branch_find_slice(STReadyForDefense, adapter, stip_traversal_context_intro); stip_structure_traversal st; slice_index const notend = branch_find_slice(STNotEndOfBranchGoal, adapter, stip_traversal_context_intro); slice_index const prototype = alloc_pipe(STEndOfRoot); assert(notend!=no_slice); defense_branch_insert_slices(notend,&prototype,1); assert(start!=no_slice); stip_structure_traversal_init(&st,state); st.context = stip_traversal_context_defense; stip_structure_traversal_override_by_structure(&st, slice_structure_pipe, ©_to_setplay); stip_structure_traversal_override_by_structure(&st, slice_structure_branch, ©_to_setplay); stip_structure_traversal_override_by_structure(&st, slice_structure_fork, ©_to_setplay); stip_structure_traversal_override_single(&st,STEndOfRoot,&serve_as_root_hook); stip_traverse_structure(start,&st); TraceValue("%u",state->spun_off[start]); TraceEOL(); state->spun_off[adapter] = state->spun_off[start]; } TraceValue("%u",state->spun_off[adapter]); TraceEOL(); TraceFunctionExit(__func__); TraceFunctionParamListEnd(); }
/* Instrument a branch with slices dealing with self play * @param si root of branch to be instrumented * @param next1 identifies slice leading towards goal */ void battle_branch_insert_self_end_of_branch(slice_index si, slice_index goal) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",goal); TraceFunctionParamListEnd(); TraceStipulation(si); TraceStipulation(goal); { slice_index const ready = branch_find_slice(STReadyForDefense, si, stip_traversal_context_intro); slice_index const prototype = alloc_fork_slice(STEndOfBranch,goal); assert(ready!=no_slice); defense_branch_insert_slices(ready,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Instrument a battle branch with STConstraint* slices (typically for a reflex * stipulation) * @param si entry slice of branch to be instrumented * @param constraint identifies branch that constrains the attacker */ void battle_branch_insert_defense_goal_constraint(slice_index si, slice_index constraint) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",constraint); TraceFunctionParamListEnd(); TraceStipulation(si); TraceStipulation(constraint); { slice_index const ready = branch_find_slice(STReadyForDefense, si, stip_traversal_context_intro); slice_index const prototype = alloc_goal_constraint_tester_slice(constraint); assert(ready!=no_slice); defense_branch_insert_slices(ready,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Make the postkey play representation of a non-postkey play representation * @param adapter identifies adapter slice into battle branch * @return identifier to adapter slice into postkey representation */ slice_index battle_branch_make_postkeyplay(slice_index adapter) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); TraceStipulation(adapter); assert(SLICE_TYPE(adapter)==STAttackAdapter); { slice_index const notend = branch_find_slice(STNotEndOfBranchGoal, adapter, stip_traversal_context_intro); stip_length_type const length = SLICE_U(adapter).branch.length; stip_length_type const min_length = SLICE_U(adapter).branch.min_length; slice_index const proto = alloc_defense_adapter_slice(length-1, min_length-1); assert(notend!=no_slice); defense_branch_insert_slices(notend,&proto,1); result = branch_find_slice(STDefenseAdapter, notend, stip_traversal_context_defense); assert(result!=no_slice); branch_shorten_slices(adapter,STDefenseAdapter,stip_traversal_context_intro); pipe_remove(adapter); } TraceFunctionExit(__func__); TraceFunctionParam("%u",result); TraceFunctionParamListEnd(); return result; }