static void write_piece_exchange(output_plaintext_move_context_type *context, move_effect_journal_index_type curr) { switch (move_effect_journal[curr].reason) { case move_effect_reason_exchange_castling_exchange: case move_effect_reason_messigny_exchange: /* already dealt with */ assert(0); break; case move_effect_reason_oscillating_kings: next_context(context,curr,"[","]"); WriteWalk(context->engine,context->file,get_walk_of_piece_on_square(move_effect_journal[curr].u.piece_exchange.from)); WriteSquare(context->engine,context->file,move_effect_journal[curr].u.piece_exchange.to); (*context->engine->fprintf)(context->file,"%s",(*context->symbol_table)[output_symbol_left_right_arrow]); WriteWalk(context->engine,context->file,get_walk_of_piece_on_square(move_effect_journal[curr].u.piece_exchange.to)); WriteSquare(context->engine,context->file,move_effect_journal[curr].u.piece_exchange.from); break; default: write_exchange(context,curr); break; } }
/* Make sure that the observer has the expected walk - annanised or originally * @return true iff the observation is valid */ boolean annan_enforce_observer_walk(slice_index si) { square const sq_departure = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; Side const side_attacking = trait[nbply]; numvec const dir_annaniser = side_attacking==White ? dir_down : dir_up; square const pos_annaniser = sq_departure+dir_annaniser; piece_walk_type walk; boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (annanises(side_attacking,pos_annaniser,sq_departure)) walk = get_walk_of_piece_on_square(pos_annaniser); else walk = get_walk_of_piece_on_square(sq_departure); if (walk==observing_walk[nbply]) result = pipe_validate_observation_recursive_delegate(si); else result = false; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void write_exchange(output_plaintext_move_context_type *context, move_effect_journal_index_type movement) { WriteWalk(context->engine,context->file,get_walk_of_piece_on_square(move_effect_journal[movement].u.piece_exchange.from)); WriteSquare(context->engine,context->file,move_effect_journal[movement].u.piece_exchange.to); (*context->engine->fprintf)(context->file,"%s",(*context->symbol_table)[output_symbol_left_right_arrow]); WriteWalk(context->engine,context->file,get_walk_of_piece_on_square(move_effect_journal[movement].u.piece_exchange.to)); WriteSquare(context->engine,context->file,move_effect_journal[movement].u.piece_exchange.from); }
/* 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(); }
/* Determine whether the retro information concernng en passant is consistent * @return true iff the informatoin is consistent */ boolean en_passant_are_retro_squares_consistent(void) { if (en_passant_nr_retro_squares>=en_passant_retro_min_squares) { unsigned int i; for (i = 0; i!=en_passant_nr_retro_squares-1; ++i) if (get_walk_of_piece_on_square(en_passant_retro_squares[i])!=Empty) return false; if (get_walk_of_piece_on_square(en_passant_retro_squares[en_passant_nr_retro_squares-1])==Empty) return false; } return true; }
boolean amu_count_observation(slice_index si) { boolean result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); if (are_we_counting) { square const sq_departure = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; if (get_walk_of_piece_on_square(sq_departure)==observing_walk[nbply] && TSTFLAG(being_solved.spec[sq_departure],trait[nbply])) { /* this deals correctly with double attacks by the same piece (e.g. a rose) */ if (single_attacker_departure==sq_departure) result = false; else { ++amu_attack_count; single_attacker_departure = sq_departure; result = amu_attack_count==2; } } else result = false; } else result = pipe_validate_observation_recursive_delegate(si); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Is the placed white king in check from a particular direction? * @param dir direction * @return true iff the placed white king is in check from dir */ static boolean check_from_direction(int dir) { square curr = being_solved.king_square[White]-dir; boolean const is_diagonal = SquareCol(curr)==SquareCol(being_solved.king_square[White]); boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%d",dir); TraceFunctionParamListEnd(); while (is_square_empty(curr)) curr -= dir; if (TSTFLAG(being_solved.spec[curr],Black)) { piece_walk_type const checker = get_walk_of_piece_on_square(curr); result = checker==Queen || checker==(is_diagonal ? Bishop : Rook); } else result = false; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* 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(); }
static void HandleAddedPiece(square s, void *param) { piece_addition_settings * const settings = param; if (!is_square_empty(s)) { if (settings->type==piece_addition_initial) { WriteSquare(&output_plaintext_engine,stdout,s); output_plaintext_message(OverwritePiece); underworld_make_space(nr_ghosts); underworld[nr_ghosts-1].walk = get_walk_of_piece_on_square(s); underworld[nr_ghosts-1].flags = being_solved.spec[s]; underworld[nr_ghosts-1].on = s; } else { move_effect_journal_do_circe_volcanic_remember(move_effect_reason_diagram_setup, s); move_effect_journal_do_piece_removal(move_effect_reason_diagram_setup, s); } } if (settings->type==piece_addition_twinning) move_effect_journal_do_piece_creation(move_effect_reason_diagram_setup, s,settings->walk, settings->spec, no_side); else occupy_square(s,settings->walk,settings->spec); }
static boolean avoid_observing_if_imitator_blocked_angle_hopper(angle_t angle) { 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; piece_walk_type const p = get_walk_of_piece_on_square(sq_observer); Flags const flags = being_solved.spec[sq_observer]; vec_index_type const vec_index_departure_hurdle = 2*interceptable_observation[observation_context].vector_index1; numvec const vec_departure_hurdle1 = -angle_vectors[angle][vec_index_departure_hurdle]; numvec const vec_departure_hurdle2 = -angle_vectors[angle][vec_index_departure_hurdle-1]; square const sq_hurdle = sq_landing+vec[interceptable_observation[observation_context].vector_index1]; numvec const diff_observer_hurdle = sq_hurdle-sq_observer; int const nr_steps1 = abs(diff_observer_hurdle/vec_departure_hurdle1); int const nr_steps2 = abs(diff_observer_hurdle/vec_departure_hurdle2); numvec step; if (nr_steps1==0) step = vec_departure_hurdle2; else if (nr_steps2==0) step = vec_departure_hurdle1; else step = nr_steps1<nr_steps2 ? vec_departure_hurdle1 : vec_departure_hurdle2; empty_square(sq_observer); result = (have_all_imitators_hurdle(diff_observer_hurdle) && are_all_imitator_lines_clear(step,step,diff_observer_hurdle) && are_all_imitator_arrivals_empty(sq_observer,sq_landing)); occupy_square(sq_observer,p,flags); return result; }
static void adjust(void) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); { square const capturer_origin = einstein_collect_capturers(); move_effect_journal_index_type const top = move_effect_journal_base[nbply+1]; move_effect_journal_index_type curr; assert(move_effect_journal_base[parent_ply[nbply]+1]<=top); for (curr = move_effect_journal_base[parent_ply[nbply]+1]; curr!=top; ++curr) if (move_effect_journal[curr].type==move_effect_piece_movement && (move_effect_journal[curr].reason==move_effect_reason_moving_piece_movement || move_effect_journal[curr].reason==move_effect_reason_castling_king_movement || move_effect_journal[curr].reason==move_effect_reason_castling_partner_movement)) { square const from = move_effect_journal[curr].u.piece_movement.from; square const to = move_effect_journal[curr].u.piece_movement.to; piece_walk_type const einsteined = get_walk_of_piece_on_square(to); piece_walk_type const substitute = (capturer_origin==from ? einstein_decrease_walk(einsteined) : einstein_increase_walk(einsteined)); if (einsteined!=substitute) move_effect_journal_do_walk_change(move_effect_reason_einstein_chess, to,substitute); } } 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(); }
/* Determine whether a square is observed be the side at the move according to * Transmuting Kings * @param si identifies next slice * @note sets observation_result */ void transmuting_king_is_square_observed(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); pipe_is_square_observed_delegate(si); if (!observation_result) { square const sq_king = being_solved.king_square[trait[nbply]]; if (sq_king!=initsquare && !is_king_transmuting_as_any_walk[nbply]) { testing_with_non_transmuting_king[nbply] = true; observing_walk[nbply] = get_walk_of_piece_on_square(sq_king); fork_is_square_observed_delegate(si); testing_with_non_transmuting_king[nbply] = false; } } is_king_transmuting_as_any_walk[nbply] = false; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean can_piece_move(numecoup n) { boolean result = true; ply const parent = parent_ply[nbply]; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); if (nbply>2 && trait[nbply]!=trait[parent]) { move_effect_journal_index_type const parent_base = move_effect_journal_base[parent]; move_effect_journal_index_type const parent_movement = parent_base+move_effect_journal_index_offset_movement; if (parent_movement>=move_effect_journal_base[parent+1]) { /* we are solving a threat - no disparate effect there */ } else { square const sq_departure = move_generation_stack[n].departure; piece_walk_type const pi_parent_moving = move_effect_journal[parent_movement].u.piece_movement.moving; if (get_walk_of_piece_on_square(sq_departure)==pi_parent_moving) result = false; } } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void rider_placed(void) { rider_placement_stack_elmt_type const * const save_top = stack_top; TraceFunctionEntry(__func__); TraceSquare(stack_top->placed_on); TraceFunctionParamListEnd(); stack_top = stack_top->next; if (being_solved.king_square[White]==initsquare) (*save_top->go_on)(); else { int const check_diff = being_solved.king_square[White]-save_top->placed_on; int const check_dir = CheckDir[get_walk_of_piece_on_square(save_top->placed_on)][check_diff]; assert(check_dir!=check_diff); if (check_dir!=0 && is_line_empty(save_top->placed_on,being_solved.king_square[White],check_dir)) intelligent_intercept_check_by_black(check_dir,save_top->go_on); else (*save_top->go_on)(); } assert(stack_top==save_top->next); stack_top = save_top; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
unsigned int pawn_get_no_capture_length(Side side, square sq_departure) { unsigned int result; SquareFlags const base_square = WhBaseSq+side; SquareFlags const doublestep_square = WhPawnDoublestepSq+side; TraceFunctionEntry(__func__); TraceEnumerator(Side,side); TraceSquare(sq_departure); TraceFunctionParamListEnd(); if (TSTFLAG(sq_spec[sq_departure],base_square)) { if (CondFlag[einstein]) result = 3; else if (circe_variant.determine_rebirth_square==circe_determine_rebirth_square_equipollents || CondFlag[normalp] || circe_variant.determine_rebirth_square==circe_determine_rebirth_square_cage || get_walk_of_piece_on_square(sq_departure)==Orphan /* we are generating for a pawned Orphan! */ || TSTFLAG(sq_spec[sq_departure],Wormhole)) result = 1; else result = 0; } else if (TSTFLAG(sq_spec[sq_departure],doublestep_square)) result = 2; else result = 1; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static boolean en_passant_test_check_one_square_crossed(square sq_crossed, numvec dir_capture, en_passant_check_tester_type tester, validator_id evaluate) { square const sq_departure = sq_crossed-dir_capture; return ((get_walk_of_piece_on_square(sq_departure)!=Orphan && (*tester)(sq_departure,sq_crossed,evaluate))); }
/* 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(); }
static void generate_make_for_one_take(numecoup take_current, square take_capture) { piece_walk_type const taken = get_walk_of_piece_on_square(take_capture); Flags const taken_spec = being_solved.spec[take_capture]; square const take_departure = move_generation_stack[take_current].departure; square const take_arrival = move_generation_stack[take_current].arrival; numecoup const make_filtered_base = CURRMOVE_OF_PLY(nbply); numecoup make_current; TraceFunctionEntry(__func__); TraceFunctionParam("%u",take_current); TraceSquare(take_capture); TraceFunctionParamListEnd(); empty_square(take_capture); occupy_square(take_arrival, get_walk_of_piece_on_square(take_departure), being_solved.spec[take_departure]); empty_square(take_departure); curr_generation->departure = take_arrival; move_generation_current_walk = taken; generate_moves_for_piece_based_on_walk(); curr_generation->departure = take_departure; move_generator_filter_captures(make_filtered_base,&always_reject); for (make_current = make_filtered_base+1; make_current<=CURRMOVE_OF_PLY(nbply); ++make_current) { square const make_arrival = move_generation_stack[make_current].arrival; move_generation_stack[make_current] = move_generation_stack[take_current]; move_generation_stack[make_current].arrival = make_arrival; } occupy_square(take_departure, get_walk_of_piece_on_square(take_arrival), being_solved.spec[take_arrival]); empty_square(take_arrival); occupy_square(take_capture,taken,taken_spec); 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(); }
/* 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; }
/* Initiate the generation of moves for the piece occupying a specific square * @param sq_departure square occupied by the piece for which to generate moves */ void generate_moves_for_piece(square sq_departure) { TraceFunctionEntry(__func__); TraceSquare(sq_departure); TraceFunctionParamListEnd(); curr_generation->departure = sq_departure; move_generation_current_walk = get_walk_of_piece_on_square(sq_departure); generate_moves_delegate(SLICE_NEXT2(temporary_hack_move_generator[trait[nbply]])); 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(); }
/* Initialise the sequence of promotions of a latent pawn * @param sq_prom potential promotion square * @param side address of side; *side will be assigned the side of which sq_prom * is a promotion square * @param sequence address of structure holding the promotion sequence * @pre square sq_prom is occupied by a promotable pawn * @note the sequence only contains the promotees legal according to type 2 */ void singlebox_type2_initialise_singlebox_promotion_sequence(square sq_prom, Side *side, pieces_pawns_promotion_sequence_type *sequence) { *side = (is_forwardpawn(get_walk_of_piece_on_square(sq_prom)) ? ForwardPromSq(White,sq_prom) : ReversePromSq(White,sq_prom)) ? White : Black; pieces_pawns_start_promotee_sequence(sq_prom,*side,sequence); while (sequence->promotee!=Empty) if (sequence->promotee!=Pawn && being_solved.number_of_pieces[*side][sequence->promotee]<game_array.number_of_pieces[*side][sequence->promotee]) break; else pieces_pawns_continue_promotee_sequence(sequence); }
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; }
static boolean avoid_observing_if_imitator_blocked_nonstop_equihopper(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; piece_walk_type const p = get_walk_of_piece_on_square(sq_observer); Flags const flags = being_solved.spec[sq_observer]; numvec const diff_hurdle = (sq_landing-sq_observer)/2; empty_square(sq_observer); result = (have_all_imitators_hurdle(diff_hurdle) && are_all_imitator_arrivals_empty(sq_observer,sq_landing)); occupy_square(sq_observer,p,flags); return result; }
static boolean avoid_observing_if_imitator_blocked_contragrasshopper(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; piece_walk_type const p = get_walk_of_piece_on_square(sq_observer); Flags const flags = being_solved.spec[sq_observer]; numvec const step = -vec[interceptable_observation[observation_context].vector_index1]; empty_square(sq_observer); result = (have_all_imitators_hurdle(step) && are_all_imitator_lines_clear(step+step,step,sq_landing-sq_observer+step)); occupy_square(sq_observer,p,flags); return result; }
static boolean avoid_observing_if_imitator_blocked_chinese_leaper(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; piece_walk_type const p = get_walk_of_piece_on_square(sq_observer); Flags const flags = being_solved.spec[sq_observer]; numvec const vec_pass_target = vec[interceptable_observation[observation_context].vector_index1]; square const sq_pass = sq_landing+vec_pass_target; empty_square(sq_observer); result = (are_all_imitator_arrivals_empty(sq_observer,sq_pass) && are_all_imitator_arrivals_empty(sq_observer,sq_landing)); occupy_square(sq_observer,p,flags); return result; }
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(); }
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; }