/* Try observing with both sides * @param si identifies next slice * @note sets observation_result */ void bicolores_try_both_sides(slice_index si) { pipe_is_square_observed_delegate(si); if (!observation_result) { trait[nbply] = advers(trait[nbply]); pipe_is_square_observed_delegate(si); trait[nbply] = advers(trait[nbply]); } }
/* Redo the deneutralisation a half-neutral piece */ void redo_half_neutral_deneutralisation(move_effect_journal_entry_type const *entry) { square const on = entry->u.half_neutral_phase_change.on; Side const to = entry->u.half_neutral_phase_change.side; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); --being_solved.number_of_pieces[advers(to)][get_walk_of_piece_on_square(on)]; occupy_square(on,get_walk_of_piece_on_square(on),being_solved.spec[on]&~BIT(advers(to))); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Find a square for the opposite king * @param side side looking for a square for the opposite king */ static void advance_mate_square(Side side) { Side const other_side = advers(side); TraceFunctionEntry(__func__); TraceEnumerator(Side,side,""); TraceFunctionParamListEnd(); assert(republican_goal.type==goal_mate); being_solved.king_square[other_side] = king_placement[nbply]+1; ++being_solved.number_of_pieces[other_side][King]; while (being_solved.king_square[other_side]<=square_h8) if (is_mate_square(other_side)) break; else ++being_solved.king_square[other_side]; --being_solved.number_of_pieces[other_side][King]; king_placement[nbply] = being_solved.king_square[other_side]; being_solved.king_square[other_side] = initsquare; TraceSquare(king_placement[nbply]);TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Determine whether a side observes a specific square * @param si identifies the tester slice * @note sets observation_result */ void marscirce_iterate_observers(slice_index si) { circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer]; Side const side_observing = trait[nbply]; square const *observer_origin; square const sq_target = move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture; TraceFunctionEntry(__func__); TraceValue("%u",si); TraceFunctionParamListEnd(); observation_result = false; context->relevant_ply = nbply; for (observer_origin = boardnum; *observer_origin; ++observer_origin) if (*observer_origin!=sq_target /* no auto-observation */ && TSTFLAG(being_solved.spec[*observer_origin],side_observing) && get_walk_of_piece_on_square(*observer_origin)==observing_walk[nbply]) { context->rebirth_from = *observer_origin; context->reborn_walk = observing_walk[nbply]; context->reborn_spec = being_solved.spec[context->rebirth_from]; context->relevant_side = advers(side_observing); context->relevant_square = context->rebirth_from; pipe_is_square_observed_delegate(si); if (observation_result) break; } 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 goalreachable_guard_mate_solve(slice_index si) { Side const just_moved = advers(SLICE_STARTER(si)); TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); --MovesLeft[just_moved]; TraceEnumerator(Side,SLICE_STARTER(si)); TraceEnumerator(Side,just_moved); TraceValue("%u",MovesLeft[SLICE_STARTER(si)]); TraceValue("%u",MovesLeft[just_moved]); TraceEOL(); pipe_this_move_doesnt_solve_if(si,!mate_isGoalReachable()); ++MovesLeft[just_moved]; TraceValue("%u",MovesLeft[SLICE_STARTER(si)]); TraceValue("%u",MovesLeft[just_moved]); TraceEOL(); 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 circe_couscous_make_capturer_relevant_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); circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer]; context->relevant_walk = get_walk_of_piece_on_square(pos); context->relevant_spec = being_solved.spec[pos]; context->relevant_side = advers(context->relevant_side); } pipe_dispatch_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 retro_start_retro_move_ply(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); /* Make sure that trait is the opposite of the first move (or there * will be no e.p. capture). */ assert(slices[si].starter!=no_side); nextply(advers(slices[si].starter)); assert(nbply==ply_retro_move); { /* TODO let Mars Circe or SingleBox Type 3 add slices here that do this */ unsigned int i; for (i = 0; i!=move_effect_journal_index_offset_capture; ++i) move_effect_journal_do_null_effect(); } pipe_solve_delegate(si); undo_move_effects(); finply(); 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 orthodox_mating_king_contact_generator_solve(slice_index si) { Side const moving = SLICE_STARTER(si); Side const mated = advers(moving); square const sq_mated_king = being_solved.king_square[mated]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert(solve_nr_remaining==slack_length+1); curr_generation->departure = being_solved.king_square[moving]; if (curr_generation->departure!=sq_mated_king) { vec_index_type k; for (k = vec_queen_start; k<=vec_queen_end; k++) { curr_generation->arrival = curr_generation->departure+vec[k]; if ((is_square_empty(curr_generation->arrival) || TSTFLAG(being_solved.spec[curr_generation->arrival],mated)) && move_diff_code[abs(sq_mated_king-curr_generation->arrival)]<=1+1) push_move(); } } pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_not_king_captures_guarded_king(numecoup n) { square const sq_observer = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; square const sq_observee = move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture; boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",n); TraceFunctionParamListEnd(); if (TSTFLAG(being_solved.spec[sq_observer],Royal) && TSTFLAG(being_solved.spec[sq_observee],Royal)) { siblingply(advers(trait[nbply])); push_observation_target(move_generation_stack[n].capture); result = !is_square_observed(EVALUATE(observer)); finply(); } 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 exclusive_chess_legality_tester_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if ((table_length(exclusive_chess_undecidable_continuations[parent_ply[nbply]]) +exclusive_chess_nr_continuations_reaching_goal[parent_ply[nbply]]) >1) { if (is_current_move_in_table(exclusive_chess_undecidable_continuations[parent_ply[nbply]])) solve_result = this_move_is_illegal; else switch (conditional_pipe_solve_delegate(temporary_hack_mate_tester[advers(trait[nbply])])) { case this_move_is_illegal: solve_result = this_move_is_illegal; break; case previous_move_has_not_solved: pipe_solve_delegate(si); break; default: solve_result = previous_move_has_solved; break; } } else pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_kingsquare_observed(void) { Side const side = trait[nbply]; boolean result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); if (transmuting_kings_testing_transmutation[side]) result = false; else { transmuting_kings_testing_transmutation[side] = true; siblingply(advers(side)); push_observation_target(being_solved.king_square[side]); result = fork_is_square_observed_nested_delegate(temporary_hack_is_square_observed[side], EVALUATE(observation)); finply(); transmuting_kings_testing_transmutation[side] = false; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Impose the starting side on a stipulation. * @param si identifies slice * @param st address of structure that holds the state of the traversal */ void impose_starter_goal_immobile_tester(slice_index si, stip_structure_traversal *st) { Side * const starter = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceEnumerator(Side,*starter,""); TraceFunctionParamListEnd(); SLICE_STARTER(si) = *starter; stip_traverse_structure_children_pipe(si,st); { Side const immobilised = (SLICE_U(si).goal_filter.applies_to_who ==goal_applies_to_starter ? SLICE_STARTER(si) : advers(SLICE_STARTER(si))); *starter = immobilised; stip_traverse_structure_conditional_pipe_tester(si,st); } *starter = SLICE_STARTER(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Determine whether the moving side's king is transmuting as a specific walk * @param p the piece */ boolean transmuting_kings_is_king_transmuting_as(piece_walk_type walk) { boolean result; Side const side_attacking = trait[nbply]; TraceFunctionEntry(__func__); TraceWalk(walk); TraceFunctionParamListEnd(); if (transmuting_kings_testing_transmutation[side_attacking]) result = false; else { transmuting_kings_testing_transmutation[side_attacking] = true; siblingply(advers(side_attacking)); push_observation_target(being_solved.king_square[side_attacking]); observing_walk[nbply] = walk; result = fork_is_square_observed_nested_delegate(temporary_hack_is_square_observed_specific[trait[nbply]], EVALUATE(observation)); finply(); transmuting_kings_testing_transmutation[side_attacking] = false; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
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; }
/* Undo the neutralisation a half-neutral piece * @param curr identifies the neutralisation effect */ void undo_half_neutral_neutralisation(move_effect_journal_entry_type const *entry) { square const on = entry->u.half_neutral_phase_change.on; Side const from = entry->u.half_neutral_phase_change.side; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); assert(TSTFLAG(being_solved.spec[on],White)); assert(TSTFLAG(being_solved.spec[on],Black)); assert(is_piece_neutral(being_solved.spec[on])); --being_solved.number_of_pieces[advers(from)][get_walk_of_piece_on_square(on)]; occupy_square(on,get_walk_of_piece_on_square(on),being_solved.spec[on]&~BIT(advers(from))); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Neutralise a half-neutral piece * @param on position of the piece to be changed */ static void do_neutralisation(square on) { move_effect_journal_entry_type * const entry = move_effect_journal_allocate_entry(move_effect_half_neutral_neutralisation,move_effect_reason_half_neutral_neutralisation); Side const from = TSTFLAG(being_solved.spec[on],White) ? White : Black; TraceFunctionEntry(__func__); TraceSquare(on); TraceEnumerator(Side,from); TraceFunctionParamListEnd(); entry->u.half_neutral_phase_change.on = on; entry->u.half_neutral_phase_change.side = from; occupy_square(on,get_walk_of_piece_on_square(on),being_solved.spec[on]|BIT(advers(from))); ++being_solved.number_of_pieces[advers(from)][get_walk_of_piece_on_square(on)]; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
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(); }
/* 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 opponent_king_capture_avoider_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); pipe_this_move_illegal_if(si,is_king_captured(advers(SLICE_STARTER(si)))); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Deneutralise a half-neutral piece * @param on position of the piece to be changed * @param to new side of half-neutral piece */ static void do_deneutralisation(square on, Side to) { move_effect_journal_entry_type * const entry = move_effect_journal_allocate_entry(move_effect_half_neutral_deneutralisation,move_effect_reason_half_neutral_deneutralisation); TraceFunctionEntry(__func__); TraceSquare(on); TraceEnumerator(Side,to); TraceFunctionParamListEnd(); entry->u.half_neutral_phase_change.on = on; entry->u.half_neutral_phase_change.side = to; assert(TSTFLAG(being_solved.spec[on],White)); assert(TSTFLAG(being_solved.spec[on],Black)); assert(is_piece_neutral(being_solved.spec[on])); --being_solved.number_of_pieces[advers(to)][get_walk_of_piece_on_square(on)]; occupy_square(on,get_walk_of_piece_on_square(on),being_solved.spec[on]&~BIT(advers(to))); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void keepmating_filter_inserter_goal(slice_index si, stip_structure_traversal *st) { insertion_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); state->for_side[advers(SLICE_STARTER(si))] = true; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void advance_latent_pawn_selection(Side trait_ply) { Side const adv = advers(trait_ply); TraceFunctionEntry(__func__); TraceEnumerator(Side,trait_ply,""); TraceFunctionParamListEnd(); singlebox_type2_latent_pawn_promotions[nbply].where = next_latent_pawn(singlebox_type2_latent_pawn_promotions[nbply].where,adv); TraceSquare(singlebox_type2_latent_pawn_promotions[nbply].where);TraceEOL(); 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 selfcheck_guard_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (is_in_check(advers(SLICE_STARTER(si)))) solve_result = previous_move_is_illegal; else 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 antiandernach_side_changer_solve(slice_index si) { 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; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (move_effect_journal[capture].type==move_effect_no_piece_removal) andernach_assume_side(advers(SLICE_STARTER(si))); pipe_solve_delegate(si); 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(); }
/* Place the opposite king as part of playing a move * @param moving side at the move */ static void place_king(Side moving) { Side const other_side = advers(moving); Flags king_flags = all_royals_flags|BIT(Royal)|BIT(other_side); TraceFunctionEntry(__func__); TraceEnumerator(Side,moving,""); TraceFunctionParamListEnd(); move_effect_journal_do_piece_creation(move_effect_reason_republican_king_insertion, king_placement[nbply], King, king_flags, trait[nbply]); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_target_unguarded(numecoup n) { boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",n); TraceFunctionParamListEnd(); siblingply(advers(trait[nbply])); push_observation_target(move_generation_stack[n].capture); result = !is_square_observed(EVALUATE(observer)); finply(); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* 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; }
/* 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; }
static boolean init_rebirth_squares(circe_rebirth_context_elmt_type const *context) { boolean result = false; square const sq_capture = context->relevant_square; piece_walk_type const pi_capturing = get_walk_of_piece_on_square(sq_capture); Flags const flags_capturing = being_solved.spec[sq_capture]; /* we need to do this for this module to work in both Circe and Anticirce: * normally (i.e. unless e.g. mirror is selected), the capturee's walk * determines the squares reachable by the make part of moves, independently * of whether the reborn piece is the capturer or the capturee. */ Side const relevant_side = (trait[context->relevant_ply]==context->relevant_side ? advers(context->relevant_side) : context->relevant_side); TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); take_make_circe_current_rebirth_square_index[stack_pointer] = take_make_circe_current_rebirth_square_index[stack_pointer-1]; occupy_square(context->relevant_square, context->relevant_walk, context->reborn_spec); init_single_piece_move_generator(context->relevant_square); result = (conditional_pipe_solve_delegate(temporary_hack_circe_take_make_rebirth_squares_finder[relevant_side]) ==previous_move_has_solved); assert(pi_capturing!=Invalid); if (pi_capturing==Empty) /* en passant, Locust, ... */ empty_square(context->relevant_square); else occupy_square(context->relevant_square,pi_capturing,flags_capturing); 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 republican_king_placer_solve(slice_index si) { move_effect_journal_index_type const save_horizon = king_square_horizon; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); update_king_squares(); if (being_solved.king_square[advers(SLICE_STARTER(si))]==initsquare) { determine_king_placement(SLICE_STARTER(si)); if (king_placement[nbply]==king_not_placed) { pipe_solve_delegate(si); king_placement[nbply] = to_be_initialised; } else { place_king(SLICE_STARTER(si)); pipe_solve_delegate(si); if (!post_move_iteration_locked[nbply]) { is_mate_square_dirty[nbply] = true; lock_post_move_iterations(); } } prev_post_move_iteration_id[nbply] = post_move_iteration_id[nbply]; } else pipe_solve_delegate(si); king_square_horizon = save_horizon; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }