/* 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(); }
/* 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 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(); }
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(); }
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 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(); }
/* Instrument a stipulation * @param si identifies root slice of stipulation */ void strictsat_initialise_solving(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); { stip_structure_traversal st; stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st,STMove,&instrument_move_with_updater); stip_traverse_structure(si,&st); } solving_instrument_check_testing(si,STStrictSATCheckTester); { slice_index const prototype = alloc_pipe(STStrictSATInitialiser); slice_insertion_insert(si,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_legality_tester(slice_index si, stip_structure_traversal *st) { insertion_state_type * const state = st->param; boolean const save_is_this_mating_move_played_for_testing_exclusivity = state->is_this_mating_move_played_for_testing_exclusivity; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); state->is_this_mating_move_played_for_testing_exclusivity = false; stip_traverse_structure_children_pipe(si,st); state->is_this_mating_move_played_for_testing_exclusivity = save_is_this_mating_move_played_for_testing_exclusivity; if (!state->is_this_mating_move_played_for_testing_exclusivity) { slice_index const prototype = alloc_pipe(STExclusiveChessLegalityTester); move_insert_slices(si,st->context,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Detect exclusivity and solve accordingly * @param si slice index * @param n maximum number of half moves * @return see exclusive_chess_exclusivity_detector_solve * @note The caller must have initialized ply_horizon for recursive testing for * exclusivity and is responsible of allocating * exclusive_chess_undecidable_continuations[nbply] before and deallocating it * after the invokation. */ static void detect_exclusivity_and_solve_accordingly(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); exclusive_chess_nr_continuations_reaching_goal[nbply] = 0; nr_decidable_continuations_not_reaching_goal[nbply] = 0; conditional_pipe_solve_delegate(temporary_hack_exclusive_mating_move_counter[SLICE_STARTER(si)]); TraceValue("%u",nbply); TraceValue("%u",nr_decidable_continuations_not_reaching_goal[nbply]); TraceValue("%u",exclusive_chess_nr_continuations_reaching_goal[nbply]); TraceValue("%u\n",table_length(exclusive_chess_undecidable_continuations[nbply])); ply_horizon = maxply; pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Continue intercepting checks to the placed white king */ static void continue_intercepting_checks(void) { vec_index_type const save_current_direction = current_direction; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); do { ++current_direction; } while (current_direction<=vec_queen_end && !check_from_direction(vec[current_direction])); if (current_direction<=vec_queen_end) intelligent_intercept_check_by_black(vec[current_direction], &continue_intercepting_checks); else (*go_on_after)(); current_direction = save_current_direction; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_exclusivity_detector(slice_index si, stip_structure_traversal *st) { insertion_state_type const * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (!state->is_this_mating_move_played_for_testing_exclusivity) { slice_type const type = (state->are_we_testing_exclusivity ? STExclusiveChessNestedExclusivityDetector : STExclusiveChessExclusivityDetector); slice_index const prototype = alloc_pipe(type); slice_insertion_insert_contextually(si,st->context,&prototype,1); } stip_traverse_structure_children_pipe(si,st); 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_attack_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(STReadyForAttack, si, stip_traversal_context_intro); slice_index const prototype = alloc_constraint_tester_slice(constraint); assert(ready!=no_slice); attack_branch_insert_slices(ready,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Cause moves with Circe rebirth on an occupied square to not be played * @param si entry slice into the solving machinery * @param interval_start start of the slices interval where to instrument */ static void stop_rebirth_on_occupied_square(slice_index si, slice_type interval_start) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceEnumerator(slice_type,interval_start,""); TraceFunctionParamListEnd(); circe_insert_rebirth_avoider(si, interval_start, STCirceDeterminedRebirth, alloc_fork_slice(STCirceTestRebirthSquareEmpty,no_slice), STCirceRebirthOnNonEmptySquare, STCirceDoneWithRebirth); circe_instrument_solving(si, interval_start, STCirceRebirthOnNonEmptySquare, alloc_pipe(STSupercircePreventRebirthOnNonEmptySquare)); 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 fork_make_root(slice_index si, stip_structure_traversal *st) { spin_off_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); TraceValue("%u",state->spun_off[SLICE_NEXT1(si)]); TraceEOL(); if (state->spun_off[SLICE_NEXT1(si)]!=no_slice) { state->spun_off[si] = copy_slice(si); link_to_branch(state->spun_off[si],state->spun_off[SLICE_NEXT1(si)]); } TraceValue("%u",state->spun_off[si]); TraceEOL(); 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 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; }
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(); }
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; }
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(); }
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(); }
/* 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(); }
/* 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_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(); }
/* 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(); }