/* Make sure to behave correctly while detecting observations by vaulting kings */ boolean transmuting_kings_enforce_observer_walk(slice_index si) { boolean result; square const sq_king = being_solved.king_square[trait[nbply]]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (transmuting_kings_testing_transmutation[advers(trait[nbply])]) result = pipe_validate_observation_recursive_delegate(si); else if (testing_with_non_transmuting_king[nbply]) { assert(observing_walk[nbply]==get_walk_of_piece_on_square(sq_king)); if (move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure==sq_king) result = pipe_validate_observation_recursive_delegate(si); else result = false; } else if (move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure==sq_king) { if (transmuting_kings_is_king_transmuting_as(observing_walk[nbply])) { piece_walk_type const save_walk = observing_walk[nbply]; observing_walk[nbply] = get_walk_of_piece_on_square(sq_king); result = pipe_validate_observation_recursive_delegate(si); observing_walk[nbply] = save_walk; is_king_transmuting_as_observing_walk[nbply] = does_transmute; } else { result = false; is_king_transmuting_as_observing_walk[nbply] = does_not_transmute; } } else result = pipe_validate_observation_recursive_delegate(si); 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 output_plaintext_tree_try_writer_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert(refutations!=table_nil); if (table_length(refutations)>0) { protocol_fprintf(stdout,"%s"," ?"); pipe_solve_delegate(si); } else output_plaintext_tree_key_writer_solve(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Generate moves for a single piece * @param identifies generator slice */ void transmuting_kings_generate_moves_for_piece(slice_index si) { Flags const mask = BIT(trait[nbply])|BIT(Royal); TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (TSTFULLFLAGMASK(being_solved.spec[curr_generation->departure],mask)) { if (!generate_moves_of_transmuting_king(si)) pipe_move_generation_delegate(si); } else pipe_move_generation_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void output_plaintext_instrument_solving_builder_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); { slice_index const prototypes[] = { alloc_pipe(STOutputPlainTextInstrumentSolvers) }; enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] }; slice_insertion_insert(si,prototypes,nr_prototypes); } pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void init_disturb_mate_dir_knight(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; !TSTFULLFLAGMASK(being_solved.spec[s],mask); s += dir) { vec_index_type i; for (i = vec_knight_start; i<=vec_knight_end; ++i) DisturbMateDirKnight[s+vec[i]] = vec[i]; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void move_imitators(int delta) { unsigned int i; TraceFunctionEntry(__func__); TraceFunctionParam("%d",delta); TraceFunctionParamListEnd(); TraceValue("%u",being_solved.number_of_imitators); for (i=0; i!=being_solved.number_of_imitators; ++i) { being_solved.isquare[i] += delta; TraceSquare(being_solved.isquare[i]); } TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_promoter(slice_index si, stip_structure_traversal *st) { slice_index const * const landing = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); { slice_index const proxy = alloc_proxy_slice(); slice_index const prototype = alloc_fork_slice(STPawnToImitatorPromoter,proxy); assert(*landing!=no_slice); link_to_branch(proxy,*landing); promotion_insert_slices(si,st->context,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Create a shallow copy of the visited fork slice * @param si visited slice * @param st structure representing the copying traversal */ static void copy_shallow(slice_index si, stip_structure_traversal *st) { stip_deep_copies_type * const copies = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert((*copies)[si]==no_slice); (*copies)[si] = copy_slice(si); stip_traverse_structure_children_pipe(si,st); if (SLICE_NEXT1(si)!=no_slice) link_to_branch((*copies)[si],(*copies)[SLICE_NEXT1(si)]); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void move_to_postkey(slice_index si, stip_structure_traversal *st) { slice_index * const root_slice = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); if (*root_slice!=no_slice) { link_to_branch(si,*root_slice); *root_slice = si; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void remove_guard(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); { slice_index const guard = branch_find_slice(STSelfCheckGuard, SLICE_NEXT2(si), stip_traversal_context_intro); assert(guard!=no_slice); pipe_remove(guard); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_white_queen(unsigned int placed_index, square placed_on, void (*go_on)(void)) { piece_walk_type const placed_type = white[placed_index].type; Flags const placed_flags = white[placed_index].flags; square const placed_comes_from = white[placed_index].diagram_square; int const dir_ortho = GuardDir[Rook-Pawn][placed_on].dir; int const dir_diag = GuardDir[Bishop-Pawn][placed_on].dir; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); if (dir_ortho<guard_dir_guard_uninterceptable && dir_diag<guard_dir_guard_uninterceptable && intelligent_reserve_officer_moves_from_to(White, placed_comes_from, placed_type, placed_on)) { square const target_ortho = GuardDir[Rook-Pawn][placed_on].target; stack_elmt_type const new_top = { placed_index, placed_on, go_on, stack_top }; stack_top = &new_top; occupy_square(placed_on,placed_type,placed_flags); if (dir_ortho==0 || TSTFLAG(being_solved.spec[target_ortho],Black) || !is_line_empty(placed_on,target_ortho,dir_ortho)) intercept_queen_diag(); else intelligent_intercept_guard_by_white(target_ortho,dir_ortho,&intercept_queen_diag); assert(stack_top==&new_top); stack_top = stack_top->next; intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Validate an observation according to Patrol Chess * @return true iff the observation is valid */ boolean patrol_validate_observation(slice_index si) { boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (TSTFLAG(being_solved.spec[move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure],Patrol)) result = (is_mover_supported(CURRMOVE_OF_PLY(nbply)) && pipe_validate_observation_recursive_delegate(si)); else result = pipe_validate_observation_recursive_delegate(si); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Determine whether a square is observed be the side at the move according to * Vaulting Kings * @param si identifies next slice * @note sets observation_validation_result */ void vaulting_king_is_square_observed(slice_index si) { Side const side_observing = trait[nbply]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (being_solved.king_square[side_observing]==initsquare) pipe_solve_delegate(si); else { is_king_vaulting[nbply] = dont_know; pipe_solve_delegate(si); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void suspend_insertion(slice_index si, stip_structure_traversal *st) { in_branch_insertion_state_type * const state = st->param; boolean const save_is_instrumented = state->is_branch_instrumented; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); /* prevent instrumentation of next1 branch */ state->is_branch_instrumented = true; stip_traverse_structure_conditional_pipe_tester(si,st); state->is_branch_instrumented = save_is_instrumented; stip_traverse_structure_children_pipe(si,st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void retro_instrument_solving_default(slice_index solving_machinery) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",solving_machinery); TraceFunctionParamListEnd(); { slice_index const protos[] = { alloc_pipe(STRetroStartRetractionPly), alloc_pipe(STRetroStartRetroMovePly), alloc_pipe(STRetroPlayNullMove) }; enum { nr_prototypes = sizeof protos / sizeof protos[0] }; slice_insertion_insert(solving_machinery,protos,nr_prototypes); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_pinned_black_rider(unsigned int placed_index, square placed_on, void (*go_on)(void)) { piece_walk_type const intercepter_type = black[placed_index].type; Flags const placed_flags = black[placed_index].flags; square const placed_comes_from = black[placed_index].diagram_square; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); { int const check_dir = find_interceptable_check_dir(intercepter_type, placed_on); if (check_dir==0) { if (intelligent_reserve_officer_moves_from_to(Black, placed_comes_from, intercepter_type, placed_on)) { occupy_square(placed_on,intercepter_type,placed_flags); (*go_on)(); intelligent_unreserve(); } } else if (check_dir!=checkdir_uninterceptable && intelligent_reserve_officer_moves_from_to(Black, placed_comes_from, intercepter_type, placed_on)) { occupy_square(placed_on,intercepter_type,placed_flags); intelligent_intercept_check_by_black(check_dir,go_on); intelligent_unreserve(); } } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_continuation_solvers_postkey_play(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); if (st->level!=structure_traversal_level_top && SLICE_U(si).branch.length>slack_length) { slice_index const prototype = alloc_continuation_solver_slice(); slice_insertion_insert(si,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Make sure to behave correctly while detecting observations by vaulting kings */ boolean vaulting_kings_enforce_observer_walk(slice_index si) { boolean result; Side const side_observing = trait[nbply]; square const sq_king = being_solved.king_square[side_observing]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (transmuting_kings_testing_transmutation[advers(side_observing)]) result = pipe_validate_observation_recursive_delegate(si); else if (move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure==sq_king) { if (is_king_vaulting[nbply]==dont_know) is_king_vaulting[nbply] = is_kingsquare_observed() ? does_vault : does_not_vault; if (is_king_vaulting[nbply]==does_vault) { if (is_king_vaulter(side_observing,observing_walk[nbply])) { piece_walk_type const save_walk = observing_walk[nbply]; observing_walk[nbply] = get_walk_of_piece_on_square(sq_king); result = pipe_validate_observation_recursive_delegate(si); observing_walk[nbply] = save_walk; if (!result && !vaulting_kings_transmuting[side_observing]) result = pipe_validate_observation_recursive_delegate(si); } else result = pipe_validate_observation_recursive_delegate(si); } else result = pipe_validate_observation_recursive_delegate(si); } else result = pipe_validate_observation_recursive_delegate(si); 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 mummer_bookkeeper_solve(slice_index si) { int current_length; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); current_length = (*mummer_measure_length[SLICE_STARTER(si)])(); TraceValue("%d",current_length); TraceValue("%d\n",mum_length[parent_ply[nbply]]); if (current_length<mum_length[parent_ply[nbply]]) { /* this move will not be played */ } else if (current_length==mum_length[parent_ply[nbply]]) /* this move may be legal, but can't increase the maximum length */ accept_move(nbply-1,CURRMOVE_OF_PLY(nbply)); else { pipe_solve_delegate(si); if (solve_result>=slack_length) { /* we have a new mum */ mum_length[parent_ply[nbply]] = current_length; TraceValue("%u\n",mum_length[parent_ply[nbply]]); reset_accepted_moves(nbply-1); accept_move(nbply-1,CURRMOVE_OF_PLY(nbply)); /* no need to try other flavours of the same move */ post_move_iteration_locked[nbply] = false; } } solve_result = this_move_is_illegal; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Deal with the situation where a rebirth is to occur on an occupied square * @param si identifies entry slice into solving machinery * @param variant identifies address of structure holding the Circe variant * @param interval_start type of slice that starts the sequence of slices * implementing that variant */ void circe_solving_instrument_rebirth_on_occupied_square(slice_index si, circe_variant_type const *variant, slice_type interval_start) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceEnumerator(slice_type,interval_start,""); TraceFunctionParamListEnd(); switch (circe_get_on_occupied_rebirth_square(variant)) { case circe_on_occupied_rebirth_square_assassinate: circe_assassin_initialise_solving(si,interval_start); break; case circe_on_occupied_rebirth_square_parachute: circe_parachute_initialise_solving(si,interval_start); break; case circe_on_occupied_rebirth_square_volcanic: circe_volcanic_initialise_solving(si,interval_start); break; case circe_on_occupied_rebirth_square_strict: stop_rebirth_on_occupied_square(si,interval_start); break; case circe_on_occupied_rebirth_square_relaxed: if (variant->rebirth_reason==move_effect_reason_rebirth_choice) stop_rebirth_on_occupied_square(si,interval_start); else no_rebirth_on_occupied_square(si,interval_start); break; default: assert(0); break; } 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_remove_capturer_solve(slice_index si) { circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer]; square const sq_departure = context->rebirth_from; piece_walk_type const walk = get_walk_of_piece_on_square(sq_departure); Flags const flags = being_solved.spec[sq_departure]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert(walk!=Empty); empty_square(sq_departure); pipe_dispatch_delegate(si); occupy_square(sq_departure,walk,flags); 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 move_execution_post_move_iterator_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); pipe_solve_delegate(si); if (post_move_iteration_locked[nbply]) post_move_iteration_locked[nbply] = false; else { pop_move(); ++post_move_iteration_id[nbply]; TraceValue("%u",nbply);TraceValue("%u\n",post_move_iteration_id[nbply]); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Detect whether a goal implies immobility of the "goaled" side * @param si identifies entry slice to the goal testing machinery * @return true iff the goal implies immobility */ static boolean does_goal_imply_immobility(slice_index si) { boolean result = false; stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&result); stip_structure_traversal_override(&st, end_of_branch_goal_immobility_detectors, nr_end_of_branch_goal_immobility_detectors); stip_traverse_structure(si,&st); 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 nopromotion_avoid_promotion_moving_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); { move_effect_journal_index_type const base = move_effect_journal_base[nbply]; move_effect_journal_index_type const movement = base+move_effect_journal_index_offset_movement; square const sq_arrival = move_effect_journal[movement].u.piece_movement.to; PieceIdType const moving_id = GetPieceId(move_effect_journal[movement].u.piece_movement.movingspec); square const pos = move_effect_journal_follow_piece_through_other_effects(nbply, moving_id, sq_arrival); pipe_this_move_illegal_if(si,is_square_occupied_by_promotable_pawn(pos,trait[nbply])); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Instrument the solving machinery with the necessary STAvoidUnusable slices * @param root_slice identifies root slice of the solving machinery */ void solving_insert_avoid_unsolvable_forks(slice_index root_slice) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",root_slice); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_by_contextual(&st, slice_contextual_end_of_branch, &insert_avoid_unsolvable); stip_structure_traversal_override(&st, avoid_unusable_inserters, nr_avoid_unusable_inserters); stip_traverse_structure(root_slice,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_counter_at_goal(slice_index si, stip_structure_traversal *st) { insertion_struct * const insertion = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children(si,st); if (st->context==stip_traversal_context_help && !insertion->inserted) { slice_index const prototype = alloc_maxsolutions_counter_slice(insertion->incomplete); help_branch_insert_slices_behind_proxy(SLICE_NEXT2(si),&prototype,1,si); insertion->inserted = true; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void avoid_instrumenting_exclusivity_detecting_move(slice_index si, stip_structure_traversal *st) { insertion_state_type * const state = st->param; insertion_state_type const save_state = *state; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); state->is_this_mating_move_played_for_testing_exclusivity = true; state->are_we_testing_exclusivity = true; stip_traverse_structure_conditional_pipe_tester(si,st); *state = save_state; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Has the input branch already been instrumend with a proofgame solver? * @param start entry into input branch * @return true iff input branch has already been instrumend */ boolean input_is_instrumented_with_proof(slice_index start) { boolean result = false; stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",start); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&result); stip_structure_traversal_override_single(&st,STProofSolverBuilder,&report_instrumented); stip_structure_traversal_override_single(&st,STAToBSolverBuilder,&report_instrumented); stip_structure_traversal_override_single(&st,STStartOfCurrentTwin,&stip_structure_visitor_noop); stip_traverse_structure(start,&st); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static slice_index MakeSemireflexBranch(slice_index proxy_to_goal) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",proxy_to_goal); TraceFunctionParamListEnd(); { slice_index const branch = alloc_battle_branch(1,0); result = alloc_proxy_slice(); link_to_branch(result,branch); battle_branch_insert_direct_end_of_branch_goal(branch,proxy_to_goal); } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void invert_last_checked(slice_index si, stip_structure_traversal *st) { in_branch_insertion_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (state->last_checked==no_side) stip_traverse_structure_children_pipe(si,st); else { state->last_checked = advers(state->last_checked); stip_traverse_structure_children_pipe(si,st); state->last_checked = advers(state->last_checked); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }