void intelligent_place_white_rider(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 = GuardDir[placed_type-Pawn][placed_on].dir; square const target = GuardDir[placed_type-Pawn][placed_on].target; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); switch (dir) { case guard_dir_check_uninterceptable: break; case guard_dir_guard_uninterceptable: if (placed_index>index_of_guarding_piece && intelligent_reserve_officer_moves_from_to(White, placed_comes_from, placed_type, placed_on)) { occupy_square(placed_on,placed_type,placed_flags); (*go_on)(); intelligent_unreserve(); } break; default: if (intelligent_reserve_officer_moves_from_to(White, placed_comes_from, placed_type, placed_on)) { occupy_square(placed_on,placed_type,placed_flags); if (placed_index>index_of_guarding_piece || dir==0 || TSTFLAG(being_solved.spec[target],Black) || !is_line_empty(placed_on,target,dir)) (*go_on)(); else intelligent_intercept_guard_by_white(target,dir,go_on); intelligent_unreserve(); } break; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void by_knight(slice_index si, unsigned int index_of_checker, square const check_from) { int const diff = being_solved.king_square[Black]-check_from; int const dir = CheckDir[Knight][diff]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",index_of_checker); TraceSquare(check_from); TraceFunctionParamListEnd(); if (dir!=0 && intelligent_reserve_white_officer_moves_from_to_checking(white[index_of_checker].diagram_square, Knight, check_from)) { occupy_square(check_from,Knight,white[index_of_checker].flags); init_disturb_mate_dir(check_from,being_solved.king_square[Black]-check_from); pipe_solve_delegate(si); fini_disturb_mate_dir(); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_black_knight(unsigned int placed_index, square placed_on, void (*go_on)(void)) { 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(); if ((being_solved.king_square[White]==initsquare || CheckDir[Knight][being_solved.king_square[White]-placed_on]==0) && intelligent_reserve_officer_moves_from_to(Black, placed_comes_from, Knight, placed_on)) { occupy_square(placed_on,Knight,placed_flags); if (DisturbMateDirKnight[placed_on]==0) (*go_on)(); else intelligent_pin_black_piece(placed_on,go_on); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_pinned_unpromoted_black_pawn(unsigned int placed_index, square placed_on, void (*go_on)(void)) { 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(); if (!TSTFLAGMASK(sq_spec[placed_on],BIT(BlBaseSq)|BIT(BlPromSq)) && !black_pawn_attacks_king(placed_on) && intelligent_reserve_black_pawn_moves_from_to_no_promotion(placed_comes_from, placed_on)) { occupy_square(placed_on,Pawn,placed_flags); (*go_on)(); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_unpromoted_white_pawn(unsigned int placed_index, square placed_on, void (*go_on)(void)) { square const placed_comes_from = white[placed_index].diagram_square; Flags const placed_flags = white[placed_index].flags; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); if (!TSTFLAGMASK(sq_spec[placed_on],BIT(WhBaseSq)|BIT(WhPromSq)) && GuardDir[Pawn-Pawn][placed_on].dir<guard_dir_guard_uninterceptable && intelligent_reserve_white_pawn_moves_from_to_no_promotion(placed_comes_from, placed_on)) { occupy_square(placed_on,Pawn,placed_flags); (*go_on)(); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
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; }
/* Place the white king; intercept checks if necessary * @param place_on where to place the king * @param go_on what to do after having placed the king? */ void intelligent_place_white_king(square place_on, void (*go_on)(void)) { TraceFunctionEntry(__func__); TraceSquare(place_on); TraceFunctionParamListEnd(); if (!guards_from(place_on) && !is_square_uninterceptably_observed_ortho(Black,place_on) && intelligent_reserve_white_king_moves_from_to(white[index_of_king].diagram_square, place_on)) { being_solved.king_square[White] = place_on; occupy_square(place_on,King,white[index_of_king].flags); current_direction = vec_queen_start-1; go_on_after = go_on; continue_intercepting_checks(); being_solved.king_square[White] = initsquare; empty_square(place_on); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_pinned_promoted_black_knight(unsigned int placed_index, square placed_on, void (*go_on)(void)) { square const placed_comes_from = black[placed_index].diagram_square; Flags const placed_flags = black[placed_index].flags; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); if ((being_solved.king_square[White]==initsquare || CheckDir[Knight][being_solved.king_square[White]-placed_on]==0) && intelligent_reserve_promoting_black_pawn_moves_from_to(placed_comes_from, Knight, placed_on)) { occupy_square(placed_on,Knight,placed_flags); (*go_on)(); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Determine whether a specific piece delivers check to a specific side * @param observer_origin potentially delivering check ... * @note the piece on pos_checking must belong to advers(side) * @note sets observation_result */ void marscirce_is_square_observed(slice_index si) { circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer-1]; square const sq_target = move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture; TraceFunctionEntry(__func__); TraceValue("%u",si); TraceFunctionParamListEnd(); assert(circe_rebirth_context_stack_pointer>0); observation_result = false; if (observing_walk[nbply]<Queen || observing_walk[nbply]>Bishop || CheckDir[observing_walk[nbply]][sq_target-context->rebirth_square]!=0) { if (is_square_empty(context->rebirth_square)) { TraceSquare(context->rebirth_square); TraceWalk(context->reborn_walk); TraceValue("%u",TSTFLAG(being_solved.spec[context->rebirth_square],White)); TraceValue("%u",TSTFLAG(being_solved.spec[context->rebirth_square],Black)); TraceEOL(); occupy_square(context->rebirth_square,context->reborn_walk,context->reborn_spec); pipe_is_square_observed_delegate(si); empty_square(context->rebirth_square); } } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void by_rider(slice_index si, unsigned int index_of_checker, square const check_from) { piece_walk_type const checker_type = white[index_of_checker].type; Flags const checker_flags = white[index_of_checker].flags; int const diff = being_solved.king_square[Black]-check_from; int const dir = CheckDir[checker_type][diff]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",index_of_checker); TraceSquare(check_from); TraceFunctionParamListEnd(); if (dir!=0 && intelligent_reserve_white_officer_moves_from_to_checking(white[index_of_checker].diagram_square, checker_type, check_from)) { occupy_square(check_from,checker_type,checker_flags); remember_mating_line(checker_type,check_from,+1); pipe_solve_delegate(si); remember_mating_line(checker_type,check_from,-1); intelligent_unreserve(); } 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 void by_unpromoted_pawn(slice_index si, unsigned int index_of_checker, square const check_from) { square const checker_from = white[index_of_checker].diagram_square; Flags const checker_flags = white[index_of_checker].flags; SquareFlags const prom_square = BIT(WhPromSq)|BIT(BlPromSq); TraceFunctionEntry(__func__); TraceFunctionParam("%u",index_of_checker); TraceSquare(check_from); TraceFunctionParamListEnd(); if (!TSTFLAGMASK(sq_spec[check_from],prom_square) && GuardDir[Pawn-Pawn][check_from].dir==guard_dir_check_uninterceptable && intelligent_reserve_white_pawn_moves_from_to_checking(checker_from,check_from)) { occupy_square(check_from,Pawn,checker_flags); init_disturb_mate_dir(check_from,being_solved.king_square[Black]-check_from); pipe_solve_delegate(si); fini_disturb_mate_dir(); empty_square(check_from); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_mate_square(Side other_side) { boolean result = false; if (is_square_empty(being_solved.king_square[other_side])) { TraceFunctionEntry(__func__); TraceEnumerator(Side,other_side,""); TraceFunctionParamListEnd(); TraceSquare(being_solved.king_square[other_side]);TraceEOL(); occupy_square(being_solved.king_square[other_side],King,BIT(Royal)|BIT(other_side)); if (conditional_pipe_solve_delegate(temporary_hack_mate_tester[other_side]) ==previous_move_has_solved) result = true; empty_square(being_solved.king_square[other_side]); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); } return result; }
void intelligent_place_promoted_white_knight(unsigned int placed_index, square placed_on, void (*go_on)(void)) { square const placed_comes_from = white[placed_index].diagram_square; Flags const placed_flags = white[placed_index].flags; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); if (GuardDir[Knight-Pawn][placed_on].dir<guard_dir_guard_uninterceptable && intelligent_reserve_promoting_white_pawn_moves_from_to(placed_comes_from, Knight, placed_on)) { occupy_square(placed_on,Knight,placed_flags); (*go_on)(); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_white_knight(unsigned int placed_index, square placed_on, void (*go_on)(void)) { square const placed_comes_from = white[placed_index].diagram_square; Flags const placed_flags = white[placed_index].flags; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); switch (GuardDir[Knight-Pawn][placed_on].dir) { case guard_dir_check_uninterceptable: break; case guard_dir_guard_uninterceptable: if (placed_index>index_of_guarding_piece && intelligent_reserve_officer_moves_from_to(White, placed_comes_from, Knight, placed_on)) { occupy_square(placed_on,Knight,placed_flags); (*go_on)(); intelligent_unreserve(); } break; default: if (intelligent_reserve_officer_moves_from_to(White, placed_comes_from, Knight, placed_on)) { occupy_square(placed_on,Knight,placed_flags); (*go_on)(); intelligent_unreserve(); } break; } 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(); }
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 place_rider(unsigned int placed_index, piece_walk_type placed_type, square placed_on, void (*go_on)(void)) { rider_placement_stack_elmt_type const elmt = { placed_on, go_on, stack_top }; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceWalk(placed_type); TraceSquare(placed_on); TraceFunctionParamListEnd(); stack_top = &elmt; occupy_square(placed_on,placed_type,black[placed_index].flags); switch (how_does_rider_disturb(placed_type,placed_on)) { case rider_doesnt_disturb: rider_placed(); break; case rider_requires_interception: { rider_interception_stack_elmt_type elmt = { disturbance_by_rider_index_ranges[placed_type-Queen].start, disturbance_by_rider_index_ranges[placed_type-Queen].end, placed_on, rider_interception_top }; rider_interception_top = &elmt; next_rider_interception(); assert(rider_interception_top==&elmt); rider_interception_top = elmt.succ; intelligent_pin_black_piece(placed_on,&rider_placed); break; } case rider_requires_pin: intelligent_pin_black_piece(placed_on,&rider_placed); break; default: assert(0); break; } assert(stack_top==&elmt); stack_top = elmt.next; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
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; }
void intelligent_place_unpromoted_black_pawn(unsigned int placed_index, square placed_on, void (*go_on)(void)) { 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(); if (!TSTFLAGMASK(sq_spec[placed_on],BIT(BlBaseSq)|BIT(BlPromSq)) && !black_pawn_attacks_king(placed_on) && intelligent_reserve_black_pawn_moves_from_to_no_promotion(placed_comes_from, placed_on)) { occupy_square(placed_on,Pawn,placed_flags); switch (DisturbMateDirPawn[placed_on]) { case disturbance_by_pawn_capture: case disturbance_by_pawn_interception_single: intelligent_pin_black_piece(placed_on,go_on); break; case disturbance_by_pawn_interception_double: { square const target = placed_on+2*dir_down; assert(is_square_empty(target)); if (is_square_empty(placed_on+dir_down)) { intelligent_intercept_black_move(placed_on,target,go_on); intelligent_pin_black_piece(placed_on,go_on); } else (*go_on)(); break; } default: (*go_on)(); break; } intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* 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(); }
boolean mars_enforce_observer(slice_index si) { circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer-1]; square const sq_departure = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; square const sq_observer = context->rebirth_square; boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); assert(circe_rebirth_context_stack_pointer>0); if (sq_observer==sq_departure) { /* restore as if the capture had occcured directly, to allow other * conditions (e.g. Madrasi) to correctly work. */ Flags const spec_observing = being_solved.spec[sq_observer]; empty_square(sq_observer); occupy_square(context->rebirth_from,observing_walk[nbply],spec_observing); move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure = context->rebirth_from; result = pipe_validate_observation_recursive_delegate(si); move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure = sq_observer; empty_square(context->rebirth_from); occupy_square(sq_observer,observing_walk[nbply],spec_observing); } else result = false; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static boolean castlingimok(square sq_departure, square sq_arrival) { boolean ret= false; piece_walk_type const p = get_walk_of_piece_on_square(sq_departure); Flags const flags = being_solved.spec[sq_departure]; /* I think this should work - clear the K, and move the Is, but don't clear the rook. */ /* If the Is crash into the R, the move would be illegal as the K moves first. */ /* The only other test here is for long castling when the Is have to be clear to move */ /* one step right (put K back first)as well as two steps left. */ /* But there won't be an I one sq to the left of a1 (a8) so no need to clear the R */ switch (sq_arrival-sq_departure) { case 2*dir_right: /* 00 - can short-circuit here (only follow K, if ok rest will be ok) */ empty_square(sq_departure); ret = (are_all_imitator_arrivals_empty(sq_departure, sq_departure+dir_right) && are_all_imitator_arrivals_empty(sq_departure, sq_departure+2*dir_right)); occupy_square(sq_departure,p,flags); break; case 2*dir_left: /* 000 - follow K, (and move K as well), then follow R */ empty_square(sq_departure); ret = (are_all_imitator_arrivals_empty(sq_departure, sq_departure+dir_left) && are_all_imitator_arrivals_empty(sq_departure, sq_departure+2*dir_left)); occupy_square(sq_departure+2*dir_left,p,flags); ret = (ret && are_all_imitator_arrivals_empty(sq_departure, sq_departure+dir_left) && are_all_imitator_arrivals_empty (sq_departure, sq_departure) && are_all_imitator_arrivals_empty(sq_departure, sq_departure+dir_right)); empty_square(sq_departure+2*dir_left); occupy_square(sq_departure,p,flags); break; } return ret; }
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 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 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; }
/* 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(); }
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(); }