/* 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(); }
/* Instrument the solving machinery with Circe Kamikaze * @param si identifies the root slice of the solving machinery */ void circe_kamikaze_initialise_solving(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); anticirce_variant.on_occupied_rebirth_square_default = circe_on_occupied_rebirth_square_relaxed; circe_initialise_solving(si,&anticirce_variant,STMove,&move_insert_slices,STAnticirceConsideringRebirth); circe_instrument_solving(si, STAnticirceConsideringRebirth, STCirceDeterminedRebirth, alloc_pipe(STAnticirceRemoveCapturer)); circe_insert_rebirth_avoider(si, STAnticirceConsideringRebirth, STAnticirceConsideringRebirth, alloc_fork_slice(STCirceKamikazeCaptureFork, no_slice), STCirceRebirthAvoided, STCirceDoneWithRebirth); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void instrument_testing(slice_index si, stip_structure_traversal *st) { instrumentation_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (SLICE_STARTER(si)==state->side) { assert(state->past_detector==no_slice); is_square_observed_insert_slice(si,alloc_pipe(STTransmutingKingDetectNonTransmutation)); stip_traverse_structure_children(si,st); assert(state->past_detector!=no_slice); is_square_observed_insert_slice(si, alloc_fork_slice(STTransmutingKingIsSquareObserved, state->past_detector)); state->past_detector = no_slice; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Allocate a STGoalImmobileReachedTester slice. * @param starter_or_adversary is the starter immobilised or its adversary? * @return index of allocated slice */ slice_index alloc_goal_immobile_reached_tester_slice(goal_applies_to_starter_or_adversary starter_or_adversary) { slice_index result; TraceFunctionEntry(__func__); TraceValue("%u",starter_or_adversary); TraceFunctionParamListEnd(); { slice_index const proxy = alloc_proxy_slice(); slice_index const tester = alloc_pipe(STImmobilityTester); result = alloc_conditional_pipe(STGoalImmobileReachedTester,proxy); pipe_link(proxy,tester); link_to_branch(tester,alloc_defense_branch(1,1)); SLICE_U(result).goal_filter.applies_to_who = starter_or_adversary; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
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(); }
/* Intercept a guard by white * @param target guard of what square * @param dir_from_rider direction from guarding rider * @param go_on what to do after each successful interception? */ void intelligent_intercept_guard_by_white(square target, int dir_from_rider, void (*go_on)(void)) { TraceFunctionEntry(__func__); TraceFunctionParam("%d",dir_from_rider); TraceFunctionParamListEnd(); if (intelligent_reserve_masses(Black,1,piece_intercepts)) { black_piece(target,dir_from_rider,go_on); intelligent_unreserve(); } if (intelligent_reserve_masses(White,1,piece_intercepts)) { white_piece(target,dir_from_rider,go_on); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void init_disturb_mate_dir_pawn(square const check_from, int dir) { square s; Flags const mask = BIT(Black)|BIT(Royal); TraceFunctionEntry(__func__); TraceFunctionParam("%d",dir); TraceFunctionParamListEnd(); for (s = check_from+dir; !TSTFULLFLAGMASK(being_solved.spec[s],mask); s += dir) { DisturbMateDirPawn[s+dir_up] = disturbance_by_pawn_interception_single; if (square_a5<=s && s<=square_h5) DisturbMateDirPawn[s+2*dir_up] = disturbance_by_pawn_interception_double; } /* only now - capture trumps interception */ DisturbMateDirPawn[check_from+dir_up+dir_left] = disturbance_by_pawn_capture; DisturbMateDirPawn[check_from+dir_up+dir_right] = disturbance_by_pawn_capture; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_attacked_exactly_once(square sq_departure, Side trait_ply) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); assert(!are_we_counting); are_we_counting = true; amu_attack_count = 0; single_attacker_departure = initsquare; is_square_observed_general_post_move_iterator_solve(advers(trait_ply), sq_departure, EVALUATE(observation)); are_we_counting = false; TraceFunctionExit(__func__); TraceFunctionResult("%u",amu_attack_count==1); TraceFunctionResultEnd(); return amu_attack_count==1; }
static boolean avoid_observing_if_imitator_blocked_rider(void) { boolean result; square const sq_observer = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; square const sq_landing = move_generation_stack[CURRMOVE_OF_PLY(nbply)].arrival; numvec const step = -vec[interceptable_observation[observation_context].vector_index1]; piece_walk_type const p = get_walk_of_piece_on_square(sq_observer); Flags const flags = being_solved.spec[sq_observer]; TraceFunctionEntry(__func__); TraceSquare(sq_observer); TraceSquare(sq_landing); TraceFunctionParamListEnd(); empty_square(sq_observer);/* an imitator might be disturbed by the moving rider! */ result = are_all_imitator_lines_clear(step,step,sq_landing-sq_observer+step); occupy_square(sq_observer,p,flags); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
void push_move(void) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); INCREMENT_COUNTER(add_to_move_generation_stack); assert(current_move[nbply]<toppile); TraceSquare(curr_generation->departure); TraceSquare(curr_generation->arrival); TraceEOL(); curr_generation->capture = curr_generation->arrival; ++current_move[nbply]; move_generation_stack[CURRMOVE_OF_PLY(nbply)] = *curr_generation; move_generation_stack[CURRMOVE_OF_PLY(nbply)].id = current_move_id[nbply]; ++current_move_id[nbply]; TraceValue("%u\n",CURRMOVE_OF_PLY(nbply)); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void bgl_adjuster_solve(slice_index si) { long int const diff = calculate_diff(CURRMOVE_OF_PLY(nbply)); TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert(BGL_values[trait[nbply]]>=diff); /* BGL enforcer takes care of that */ if (BGL_global) { do_bgl_adjustment(White,diff); do_bgl_adjustment(Black,diff); } else do_bgl_adjustment(trait[nbply],diff); pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void threat_solver_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); threats[nbply] = allocate_table(); if (!is_in_check(SLICE_STARTER(si))) { fork_solve_delegate(si); threat_lengths[nbply] = solve_result-1; } pipe_solve_delegate(si); free_table(threats[nbply]); threat_lengths[nbply] = no_threats_found; threats[nbply] = table_nil; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Instrument a branch for detecting whether the defense was forced to reach a * goal * @param si root of branch to be instrumented * @param goal identifies slice leading towards goal */ void battle_branch_insert_self_end_of_branch_goal(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(STEndOfBranchGoal,goal); assert(ready!=no_slice); defense_branch_insert_slices(ready,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Like defense_branch_insert_slices, but starting at a proxy slice * @param base_rank used instead of proxy for determining the current position in the * sequence of defense branches */ void defense_branch_insert_slices_behind_proxy(slice_index proxy, slice_index const prototypes[], unsigned int nr_prototypes, slice_index base) { stip_structure_traversal st; branch_slice_insertion_state_type state = { prototypes, nr_prototypes, slice_rank_order, nr_slice_rank_order_elmts, 0, branch_slice_rank_order_recursive, 0, proxy, 0 }; TraceFunctionEntry(__func__); TraceFunctionParam("%u",proxy); TraceFunctionParam("%u",nr_prototypes); TraceFunctionParam("%u",base); TraceFunctionParamListEnd(); state.base_rank = get_slice_rank(STAttackPlayed,&state); assert(state.base_rank!=no_slice_rank); ++state.base_rank; slice_insertion_init_traversal(&st,&state,stip_traversal_context_defense); move_init_slice_insertion_traversal(&st); state.base_rank = get_slice_rank(SLICE_TYPE(base),&state); stip_traverse_structure(proxy,&st); deallocate_slice_insertion_prototypes(prototypes,nr_prototypes); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_white_piece(unsigned int placed_index, square placed_on, void (*go_on)(void)) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); switch (white[placed_index].type) { case Queen: intelligent_place_white_queen(placed_index,placed_on,go_on); break; case Rook: case Bishop: intelligent_place_white_rider(placed_index,placed_on,go_on); break; case Knight: intelligent_place_white_knight(placed_index,placed_on,go_on); break; case Pawn: intelligent_place_unpromoted_white_pawn(placed_index,placed_on,go_on); intelligent_place_promoted_white_pawn(placed_index,placed_on,go_on); break; default: assert(0); break; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean enforce_possibly_confronted_observer_walk(slice_index si, numvec dir_confronter) { square const sq_departure = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; Side const side_attacking = trait[nbply]; square const pos_confronter = sq_departure+dir_confronter; piece_walk_type walk; boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%d",dir_confronter); TraceFunctionParamListEnd(); TraceSquare(sq_departure); TraceSquare(pos_confronter); TraceEOL(); if (TSTFLAG(being_solved.spec[pos_confronter],advers(side_attacking))) walk = get_walk_of_piece_on_square(pos_confronter); else walk = get_walk_of_piece_on_square(sq_departure); TraceWalk(walk); TraceWalk(observing_walk[nbply]); TraceEOL(); if (walk==observing_walk[nbply]) result = pipe_validate_observation_recursive_delegate(si); else result = false; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void init_disturb_mate_dir_rider(square const check_from, int dir) { vec_index_type i; unsigned int disturb_index = 0; Flags const mask = BIT(Black)|BIT(Royal); TraceFunctionEntry(__func__); TraceFunctionParam("%d",dir); TraceFunctionParamListEnd(); disturbance_by_rider_index_ranges[Queen-Queen].start = disturb_index; disturbance_by_rider_index_ranges[Rook-Queen].start = disturb_index; for (i = vec_rook_start; i<=vec_rook_end; ++i) if (vec[i]>0) { square s; for (s = check_from; !TSTFULLFLAGMASK(being_solved.spec[s],mask); s += dir) init_disturb_mate_rider_onedir(s,vec[i],disturb_index); ++disturb_index; } disturbance_by_rider_index_ranges[Rook-Queen].end = disturb_index-1; disturbance_by_rider_index_ranges[Bishop-Queen].start = disturb_index; for (i = vec_bishop_start; i<=vec_bishop_end; ++i) if (vec[i]>0) { square s; for (s = check_from; !TSTFULLFLAGMASK(being_solved.spec[s],mask); s += dir) init_disturb_mate_rider_onedir(s,vec[i],disturb_index); ++disturb_index; } disturbance_by_rider_index_ranges[Bishop-Queen].end = disturb_index-1; disturbance_by_rider_index_ranges[Queen-Queen].end = disturb_index-1; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void next_rider_interception(void) { TraceFunctionEntry(__func__); TraceFunctionParam("%p",rider_interception_top); TraceFunctionParam("%u",rider_interception_top->next); TraceFunctionParam("%u",rider_interception_top->end); TraceSquare(rider_interception_top->placed_on); TraceFunctionParamListEnd(); if (rider_interception_top->next<=rider_interception_top->end) { square const placed_on = rider_interception_top->placed_on; int const dir = DisturbMateDirRider[rider_interception_top->next][placed_on].dir; square const target = DisturbMateDirRider[rider_interception_top->next][placed_on].target; assert(dir!=disturbance_by_rider_uninterceptable); ++rider_interception_top->next; if (dir!=0 && is_line_empty(placed_on,target,dir)) intelligent_intercept_black_move(placed_on,target,&next_rider_interception); else next_rider_interception(); assert(rider_interception_top->next>0); --rider_interception_top->next; } else { rider_interception_stack_elmt_type * const save_top = rider_interception_top; rider_interception_top = rider_interception_top->succ; rider_placed(); rider_interception_top = save_top; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_promoted_white_rider(piece_walk_type promotee_type, unsigned int placed_index, square placed_on, void (*go_on)(void)) { square const placed_comes_from = white[placed_index].diagram_square; Flags const placed_flags = white[placed_index].flags; int const dir = GuardDir[promotee_type-Pawn][placed_on].dir; square const target = GuardDir[promotee_type-Pawn][placed_on].target; TraceFunctionEntry(__func__); TraceWalk(promotee_type); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); if (dir>=guard_dir_guard_uninterceptable) { /* nothing */ } else if (intelligent_reserve_promoting_white_pawn_moves_from_to(placed_comes_from, promotee_type, placed_on)) { occupy_square(placed_on,promotee_type,placed_flags); if (dir==0 || TSTFLAG(being_solved.spec[target],Black) || !is_line_empty(placed_on,target,dir)) (*go_on)(); else intelligent_intercept_guard_by_white(target,dir,go_on); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
boolean mars_enforce_observer(slice_index si) { circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer-1]; square const sq_departure = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; square const sq_observer = context->rebirth_square; boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert(circe_rebirth_context_stack_pointer>0); if (sq_observer==sq_departure) { /* restore as if the capture had occcured directly, to allow other * conditions (e.g. Madrasi) to correctly work. */ Flags const spec_observing = being_solved.spec[sq_observer]; empty_square(sq_observer); occupy_square(context->rebirth_from,observing_walk[nbply],spec_observing); move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure = context->rebirth_from; result = pipe_validate_observation_recursive_delegate(si); move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure = sq_observer; empty_square(context->rebirth_from); occupy_square(sq_observer,observing_walk[nbply],spec_observing); } else result = false; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* 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(); }
/* Detect starter field with the starting side if possible. * @param si identifies slice being traversed * @param st status of traversal */ void fork_detect_starter(slice_index si, stip_structure_traversal *st) { slice_index const fork = SLICE_NEXT2(si); TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_next_branch(si,st); if (SLICE_STARTER(si)==no_side) { if (SLICE_STARTER(fork)==no_side) { stip_traverse_structure_children_pipe(si,st); SLICE_STARTER(si) = SLICE_STARTER(SLICE_NEXT1(si)); } else SLICE_STARTER(si) = SLICE_STARTER(fork); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Initialise a move traversal structure with default visitors * @param st to be initialised * @param param parameter to be passed t operations */ void stip_moves_traversal_init(stip_moves_traversal *st, void *param) { unsigned int i; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); st->map = moves_children_traversers; for (i = 0; i!=nr_slice_types; ++i) st->map.visitors[i] = moves_children_traversers.visitors[i]; for (i = 0; i!=max_nr_slices; ++i) st->remaining_watermark[i] = 0; st->context = stip_traversal_context_intro; st->activity = stip_traversal_activity_solving; st->remaining = STIP_MOVES_TRAVERSAL_LENGTH_UNINITIALISED; st->full_length = STIP_MOVES_TRAVERSAL_LENGTH_UNINITIALISED; st->param = param; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void take_make_circe_collect_rebirth_squares_solve(slice_index si) { numecoup i; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (CURRMOVE_OF_PLY(nbply)>MOVEBASE_OF_PLY(nbply)) { solve_result = MOVE_HAS_SOLVED_LENGTH(); for (i = CURRMOVE_OF_PLY(nbply); i>MOVEBASE_OF_PLY(nbply); --i) { ++take_make_circe_current_rebirth_square_index[stack_pointer]; rebirth_square[take_make_circe_current_rebirth_square_index[stack_pointer]] = move_generation_stack[i].arrival; } } else solve_result = this_move_is_illegal; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void identify_doublehopper_line(void) { square const sq_observer = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; square const sq_observee = move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture; vec_index_type const idx_firstleg = interceptable_observation[observation_context].vector_index1; numvec const dir_firstleg = vec[idx_firstleg]; vec_index_type const sq_intermediate = interceptable_observation[observation_context].auxiliary; square sq_curr = sq_intermediate+dir_firstleg; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); /* we identify doublehopper lines by the intermediate square and the square * just off the board on the first leg */ while (!is_square_blocked(sq_curr)) sq_curr += dir_firstleg; PushMagicView(sq_observee,sq_observer,sq_curr,sq_intermediate); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void move_effect_journal_do_remember_ghost(void) { move_effect_journal_index_type const top = move_effect_journal_base[nbply+1]; move_effect_journal_entry_type * const top_elmt = &move_effect_journal[top]; move_effect_journal_index_type const base = move_effect_journal_base[nbply]; move_effect_journal_index_type const capture = base+move_effect_journal_index_offset_capture; square const sq_capture = move_effect_journal[capture].u.piece_removal.on; piece_walk_type const removed = move_effect_journal[capture].u.piece_removal.walk; Flags const removedspec = move_effect_journal[capture].u.piece_removal.flags; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); assert(top+1<move_effect_journal_size); assert(move_effect_journal[capture].type==move_effect_piece_removal); top_elmt->type = move_effect_remember_ghost; top_elmt->reason = move_effect_reason_regular_capture; top_elmt->u.handle_ghost.pos = nr_ghosts; top_elmt->u.handle_ghost.ghost.walk = removed; top_elmt->u.handle_ghost.ghost.flags = removedspec; top_elmt->u.handle_ghost.ghost.on = sq_capture; #if defined(DOTRACE) top_elmt->id = move_effect_journal_next_id++; TraceValue("%lu",top_elmt->id); TraceEOL(); #endif ++move_effect_journal_base[nbply+1]; underworld[nr_ghosts] = top_elmt->u.handle_ghost.ghost; ++nr_ghosts; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Generate moves for a piece with a specific walk from a specific departure * square. * @note the piece on the departure square need not necessarily have walk p */ void marscirce_generate_from_rebirth_square(slice_index si) { circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer-1]; square const sq_departure = curr_generation->departure; square const sq_rebirth = context->rebirth_square; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceSquare(sq_rebirth); TraceFunctionParamListEnd(); assert(circe_rebirth_context_stack_pointer>0); curr_generation->departure = sq_rebirth; occupy_square(sq_rebirth,context->reborn_walk,context->reborn_spec); pipe_move_generation_delegate(si); empty_square(sq_rebirth); curr_generation->departure = sq_departure; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Solve the next2 part of a fork * @param si identifies the fork slice * @param n maximum number of moves (typically slack_length or * length_unspecified) * @return length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch */ stip_length_type testing_pipe_solve_delegate(slice_index si, stip_length_type n) { stip_length_type result; stip_length_type const save_solve_nr_remaining = solve_nr_remaining; stip_length_type const save_solve_result = solve_result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",n); TraceFunctionParamListEnd(); solve_nr_remaining = n; fork_solve_delegate(si); result = solve_result; solve_nr_remaining = save_solve_nr_remaining; solve_result = save_solve_result; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Spin a copy off a conditional pipe to add it to the root or set play branch * @param si identifies (non-root) slice * @param st address of structure representing traversal */ void conditional_pipe_spin_off_copy(slice_index si, stip_structure_traversal *st) { spin_off_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); state->spun_off[si] = copy_slice(si); stip_traverse_structure_children_pipe(si,st); if (state->spun_off[SLICE_NEXT1(si)]==no_slice) { dealloc_slice(state->spun_off[si]); state->spun_off[si] = no_slice; } else link_to_branch(state->spun_off[si],state->spun_off[SLICE_NEXT1(si)]); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Allocate a system of slices that tests whether mate has been reached * @return index of entry slice */ slice_index alloc_goal_mate_reached_tester_system(void) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); { slice_index const mate_tester = alloc_pipe(STGoalMateReachedTester); slice_index const check_tester = alloc_goal_check_reached_tester_slice(goal_applies_to_starter); slice_index const immobile_tester = alloc_goal_immobile_reached_tester_slice(goal_applies_to_starter); pipe_link(mate_tester,check_tester); pipe_link(check_tester,immobile_tester); pipe_link(immobile_tester,alloc_true_slice()); result = mate_tester; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }