/* 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 en_passant_undo_multistep(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert(en_passant_nr_retro_squares>=en_passant_retro_min_squares); move_effect_journal_do_piece_movement(move_effect_reason_diagram_setup, en_passant_retro_squares[en_passant_nr_retro_squares-1], en_passant_retro_squares[0]); pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void instrument_promotion(slice_index si, stip_structure_traversal *st) { slice_index * const landing = st->param; slice_index const save_landing = *landing; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); *landing = no_slice; stip_traverse_structure_children_pipe(si,st); insert_promoter(si,st); *landing = save_landing; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Iterate if square observation testing uses a post-move iterating slice (e.g. * for MarsCirce Super) * @param si identifies move generator slice */ void square_observation_post_move_iterator_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); do { post_move_iteration_locked[nbply] = false; pipe_is_square_observed_delegate(si); } while (post_move_iteration_locked[nbply] && !observation_result); post_move_iteration_locked[nbply] = false; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* solve a proofgame stipulation * @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 proof_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); move_effect_journal_do_snapshot_proofgame_target_position(move_effect_reason_diagram_setup); being_solved = proofgames_start_position; initialise_target_pieces_cache(); pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void substitute_avoid_promotion_moving(slice_index si, stip_structure_traversal *st) { boolean const (* const enabled)[nr_sides] = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children(si,st); if ((*enabled)[SLICE_STARTER(si)]) pipe_substitute(si,alloc_pipe(STNoPromotionsRemovePromotionMoving)); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void remember_last_checked(slice_index si, stip_structure_traversal *st) { in_branch_insertion_state_type * const state = st->param; Side const save_last_checked = state->last_checked; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert(SLICE_STARTER(si)!=no_side); state->last_checked = SLICE_STARTER(si); stip_traverse_structure_children_pipe(si,st); state->last_checked = save_last_checked; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void connect_solver_to_tester(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (st->activity==stip_traversal_activity_solving) { assert(SLICE_TESTER(SLICE_PREV(si))!=no_slice); SLICE_TESTER(si) = SLICE_NEXT1(SLICE_TESTER(SLICE_PREV(si))); } stip_traverse_structure_children_pipe(si,st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void generate_moves_for_possibly_confronted_piece(slice_index si, numvec dir_confronter) { square const confronter_pos = curr_generation->departure+dir_confronter; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (TSTFLAG(being_solved.spec[confronter_pos],advers(trait[nbply]))) pipe_move_generation_differnt_walk_delegate(si,get_walk_of_piece_on_square(confronter_pos)); else pipe_move_generation_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Attempt to apply the postkey play option to the current stipulation * @param root_proxy identifies root proxy slice * @return true iff postkey play option is applicable (and has been * applied) */ static boolean battle_branch_apply_postkeyplay(slice_index root_proxy) { boolean result; slice_index postkey_slice = no_slice; stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",root_proxy); TraceFunctionParamListEnd(); TraceStipulation(root_proxy); stip_structure_traversal_init(&st,&postkey_slice); stip_structure_traversal_override_by_structure(&st, slice_structure_pipe, &move_to_postkey); stip_structure_traversal_override_by_contextual(&st, slice_contextual_testing_pipe, &move_to_postkey); stip_structure_traversal_override_single(&st, STAttackAdapter, &attack_adapter_make_postkeyplay); stip_structure_traversal_override_single(&st, STHelpAdapter, &stip_structure_visitor_noop); stip_traverse_structure_children_pipe(root_proxy,&st); if (postkey_slice==no_slice) result = false; else { link_to_branch(root_proxy,postkey_slice); { slice_index const prototype = alloc_move_inverter_slice(); slice_insertion_insert(root_proxy,&prototype,1); } result = true; } TraceFunctionExit(__func__); TraceFunctionParam("%u",result); TraceFunctionParamListEnd(); return result; }
static void init_latent_pawn_promotion(void) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); if (singlebox_type2_latent_pawn_promotions[nbply].where!=initsquare) { singlebox_type2_initialise_singlebox_promotion_sequence(singlebox_type2_latent_pawn_promotions[nbply].where, &singlebox_type2_latent_pawn_promotions[nbply].side, &singlebox_type2_latent_pawn_promotions[nbply].promotion); if (singlebox_type2_latent_pawn_promotions[nbply].promotion.promotee==Empty) singlebox_type2_latent_pawn_promotions[nbply].where = initsquare; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Allocate a STDefenseAdapter slice. * @param length maximum number of half-moves of slice (+ slack) * @param min_length minimum number of half-moves of slice (+ slack) * @return index of allocated slice */ slice_index alloc_defense_adapter_slice(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); result = alloc_branch(STDefenseAdapter,length,min_length); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Execute the optimisations planned before and communicated using a series of * invokations of ohneschach_stop_if_check_plan_to_optimise_away_stop() * @param root root slice of the stiptulation */ void ohneschach_stop_if_check_execute_optimisations(slice_index root) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",root); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STOhneschachStopIfCheckAndNotMate, &optimise_stop); stip_traverse_structure(root,&st); 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 output_plaintext_tree_refuting_variation_writer_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); pipe_solve_delegate(si); if (solve_result>MOVE_HAS_SOLVED_LENGTH()) { unsigned int const move_depth = depth(nbply)+output_plaintext_nr_move_inversions; write_refuting_varation(move_depth); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Generate moves for a single piece * @param identifies generator slice */ void annan_generate_moves_for_piece(slice_index si) { int const annaniser_dir = trait[nbply]==White ? -onerow : +onerow; square const annaniser_pos = curr_generation->departure+annaniser_dir; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (annanises(trait[nbply],annaniser_pos,curr_generation->departure)) pipe_move_generation_differnt_walk_delegate(si,get_walk_of_piece_on_square(annaniser_pos)); else pipe_move_generation_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean find_flights(slice_index si, Side side_in_check, unsigned int nr_flights_to_find) { unsigned int nr_flights_found = 0; square const save_king_square = being_solved.king_square[side_in_check]; piece_walk_type const king_walk = get_walk_of_piece_on_square(save_king_square); Flags const king_flags = being_solved.spec[save_king_square]; square const save_departure = curr_generation->departure ; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); siblingply(side_in_check); curr_generation->departure = save_king_square; move_generation_current_walk = king_walk; generate_moves_for_piece_based_on_walk(); empty_square(save_king_square); while (encore()) { being_solved.king_square[side_in_check] = move_generation_stack[CURRMOVE_OF_PLY(nbply)].arrival; if ((is_square_empty(being_solved.king_square[side_in_check]) || TSTFLAG(being_solved.spec[being_solved.king_square[side_in_check]],advers(side_in_check))) && being_solved.king_square[side_in_check]!=being_solved.king_square[advers(side_in_check)] && !pipe_is_in_check_recursive_delegate(si,side_in_check)) ++nr_flights_found; pop_move(); } being_solved.king_square[side_in_check] = save_king_square; occupy_square(save_king_square,king_walk,king_flags); curr_generation->departure = save_departure; finply(); TraceFunctionExit(__func__); TraceFunctionResult("%u",nr_flights_found>nr_flights_to_find); TraceFunctionResultEnd(); return nr_flights_found>nr_flights_to_find; }
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 dont_instrument_selfcheck_ignoring_goals(slice_index si, stip_structure_traversal *st) { in_branch_insertion_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (SLICE_U(si).goal_filter.applies_to_who==goal_applies_to_adversary) state->is_branch_instrumented = true; else stip_traverse_structure_children_pipe(si,st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_mover_supported(numecoup n) { boolean result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); siblingply(trait[nbply]); push_observation_target(move_generation_stack[n].departure); result = is_square_observed(EVALUATE(observer)); finply(); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void remember_checked_side(slice_index si, stip_structure_traversal *st) { Side * const side = st->param; Side const save_side = *side; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); *side = SLICE_STARTER(si); stip_traverse_structure_children_pipe(si,st); *side = save_side; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_not_unsupported_patrol_capture(numecoup n) { boolean result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); if (TSTFLAG(being_solved.spec[move_generation_stack[n].departure],Patrol)) result = is_mover_supported(n); else result = true; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* 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 null_move_player_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (move_generation_stack[CURRMOVE_OF_PLY(nbply)].arrival==nullsquare) { move_effect_journal_do_null_move(); fork_solve_delegate(si); } else pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void remember_goal_with_potential_king_capture(slice_index si, stip_structure_traversal *st) { insertion_state * const state = st->param; twin_id_type const save_own_king_capture_possible = state->own_king_capture_possible; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); state->own_king_capture_possible = twin_id; stip_traverse_structure_children(si,st); state->own_king_capture_possible = save_own_king_capture_possible; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
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(); }
/* Allocate a STEndOfBranch slice. * @param to_goal identifies slice leading towards goal * @return index of allocated slice */ slice_index alloc_avoid_unsolvable_slice(slice_index proxy_op1, slice_index proxy_op2) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",proxy_op1); TraceFunctionParam("%u",proxy_op2); TraceFunctionParamListEnd(); result = alloc_binary_slice(STAvoidUnsolvable,proxy_op1,proxy_op2); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void insert_continuation_solvers_remember_attack(slice_index si, stip_structure_traversal *st) { boolean * const attack_played = st->param; boolean const save_attack_played = *attack_played; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); *attack_played = true; stip_traverse_structure_children_pipe(si,st); *attack_played = save_attack_played; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_reset_unsolvable_help(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_reset_unsolvable_slice(); slice_insertion_insert(si,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Allocate a conditional pipe slice. * @param type which slice type * @param condition entry slice into condition * @return index of allocated slice */ slice_index alloc_conditional_pipe(slice_type type, slice_index condition) { slice_index result; TraceFunctionEntry(__func__); TraceEnumerator(slice_type,type,""); TraceFunctionParam("%u",condition); TraceFunctionParamListEnd(); result = alloc_pipe(type); SLICE_NEXT2(result) = condition; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* When counting mating moves, it is not necessary to detect self-check in moves * that don't deliver mate; remove the slices that would detect these * self-checks * @param si identifies slice where to start */ void optimise_away_unnecessary_selfcheckguards(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STExclusiveChessMatingMoveCounterFork, &remove_guard); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Allocate a STFindByIncreasingLength slice. * @param length maximum number of half-moves of slice (+ slack) * @param min_length minimum number of half-moves of slice (+ slack) * @return index of allocated slice */ slice_index alloc_find_by_increasing_length_slice(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); result = alloc_branch(STFindByIncreasingLength,length,min_length); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void keepmating_filter_inserter_binary(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); /* we can't rely on the (arbitrary) order stip_traverse_structure_children() * would use; instead make sure that we first traverse towards the * goal(s). */ stip_traverse_structure_binary_operand2(si,st); stip_traverse_structure_binary_operand1(si,st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }