static boolean is_mover_supported(numecoup n) { square const sq_departure = move_generation_stack[n].departure; boolean result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); if (is_in_chain[sq_departure]) result = false; else { is_in_chain[sq_departure] = true; siblingply(trait[nbply]); push_observation_target(sq_departure); result = is_mover_supported_recursive(); finply(); is_in_chain[sq_departure] = false; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void PushMagicViews(void) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); magic_views_top[stack_pointer] = magic_views_top[stack_pointer-1]; siblingply(no_side); push_observation_target(initsquare); prev_observation_context[nbply] = observation_context; are_we_finding_magic_views[nbply] = true; PushMagicViewsByOneSide(White); PushMagicViewsByOneSide(Black); are_we_finding_magic_views[nbply] = false; /* TODO: remove double views by neutral magic pieces * apply same logic as for cross-eyed pieces? */ finply(); TraceValue("%u",nbply); TraceValue("%u\n",magic_views_top[nbply]); 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; }
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; }
/* 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; }
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 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; }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void take_and_make_generate_make_solve(slice_index si) { numecoup const take_top = CURRMOVE_OF_PLY(nbply); numecoup take_current = MOVEBASE_OF_PLY(nbply)+1; Side const moving = trait[nbply]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); siblingply(advers(moving)); /* generate according to the taken piece's side */ for (; take_current<=take_top; ++take_current) { square const take_capture = move_generation_stack[take_current].capture; if (en_passant_is_ep_capture(take_capture)) generate_make_for_one_take(take_current, take_capture-offset_en_passant_capture); else if (get_walk_of_piece_on_square(take_capture)==Empty) push_move_copy(take_current); else generate_make_for_one_take(take_current,take_capture); } trait[nbply] = moving; /* move on behalf of to the taking piece's side */ pipe_solve_delegate(si); finply(); /* prevent the current take generation from disturbing if we generate more * moves in the current ply, e.g. while testing for immobility of a side */ pop_all(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }