static void by_promoted_rider(slice_index si, unsigned int index_of_checker, piece_walk_type promotee_type, square const check_from) { int const diff = being_solved.king_square[Black]-check_from; int const dir = CheckDir[promotee_type][diff]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",index_of_checker); TraceWalk(promotee_type); TraceSquare(check_from); TraceFunctionParamListEnd(); if (dir!=0 && intelligent_reserve_promoting_white_pawn_moves_from_to(white[index_of_checker].diagram_square, promotee_type, check_from)) { occupy_square(check_from,promotee_type,white[index_of_checker].flags); remember_mating_line(promotee_type,check_from,+1); pipe_solve_delegate(si); remember_mating_line(promotee_type,check_from,-1); intelligent_unreserve(); } 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; }
/* 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(); }
void intelligent_place_promoted_black_rider(unsigned int placed_index, piece_walk_type promotee_type, square placed_on, void (*go_on)(void)) { square const placed_comes_from = black[placed_index].diagram_square; int const check_diff = being_solved.king_square[White]-placed_on; int const check_dir = CheckDir[promotee_type][check_diff]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",placed_index); TraceWalk(promotee_type); TraceSquare(placed_on); TraceFunctionParamListEnd(); if (check_dir!=check_diff && intelligent_reserve_promoting_black_pawn_moves_from_to(placed_comes_from, promotee_type, placed_on)) { place_rider(placed_index,promotee_type,placed_on,go_on); intelligent_unreserve(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static rider_disturbance_type how_does_rider_disturb(piece_walk_type placed_type, square placed_on) { rider_disturbance_type result = rider_doesnt_disturb; unsigned int const start = disturbance_by_rider_index_ranges[placed_type-Queen].start; unsigned int const end = disturbance_by_rider_index_ranges[placed_type-Queen].end; unsigned int i; TraceFunctionEntry(__func__); TraceWalk(placed_type); TraceSquare(placed_on); TraceFunctionParamListEnd(); for (i = start; i<=end; ++i) { int const disturbance_dir = DisturbMateDirRider[i][placed_on].dir; if (disturbance_dir==disturbance_by_rider_uninterceptable) { result = rider_requires_pin; break; } else if (disturbance_dir!=0) result = rider_requires_interception; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
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 void advance_latent_pawn_promotion(void) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); singlebox_type2_continue_singlebox_promotion_sequence(singlebox_type2_latent_pawn_promotions[nbply].side, &singlebox_type2_latent_pawn_promotions[nbply].promotion); TraceWalk(singlebox_type2_latent_pawn_promotions[nbply].promotion.promotee);TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
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; }
/* Generate moves for the current piece, but based on a different walk * @param si identifies the generator slices * @param walk the basis to be used for the move generation */ void generate_moves_different_walk(slice_index si, piece_walk_type walk) { piece_walk_type const save_current_walk = move_generation_current_walk; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceWalk(walk); TraceFunctionParamListEnd(); move_generation_current_walk = walk; generate_moves_delegate(si); move_generation_current_walk = save_current_walk; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_pinned_promoted_black_rider(unsigned int placed_index, piece_walk_type promotee_type, 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); TraceWalk(promotee_type); TraceSquare(placed_on); TraceFunctionParamListEnd(); { int const check_dir = find_interceptable_check_dir(promotee_type,placed_on); if (check_dir==0) { if (intelligent_reserve_promoting_black_pawn_moves_from_to(placed_comes_from, promotee_type, placed_on)) { occupy_square(placed_on,promotee_type,placed_flags); (*go_on)(); intelligent_unreserve(); } } else if (check_dir!=checkdir_uninterceptable && intelligent_reserve_promoting_black_pawn_moves_from_to(placed_comes_from, promotee_type, placed_on)) { occupy_square(placed_on,promotee_type,placed_flags); intelligent_intercept_check_by_black(check_dir,go_on); intelligent_unreserve(); } } 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 extinction_extincted_tester_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); { Side const side_in_check = SLICE_STARTER(si); piece_walk_type const capturee = find_capturee(); TraceWalk(capturee); TraceEnumerator(Side,side_in_check,"\n"); pipe_this_move_doesnt_solve_if(si, capturee==Empty || being_solved.number_of_pieces[side_in_check][capturee]!=0); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_king_vaulter(Side side, piece_walk_type walk) { unsigned int i; boolean result = false; TraceFunctionEntry(__func__); TraceEnumerator(Side,side,""); TraceWalk(walk); TraceFunctionParamListEnd(); for (i = 0; i!=nr_king_vaulters[side]; ++i) if (walk==king_vaulters[side][i]) { result = true; break; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void PushMagicViewsByOnePiece(piece_walk_type pi_magic) { square const *pos_viewed; TraceFunctionEntry(__func__); TraceWalk(pi_magic); TraceFunctionParamListEnd(); for (pos_viewed = boardnum; *pos_viewed; pos_viewed++) if (get_walk_of_piece_on_square(*pos_viewed)>Invalid && !TSTFLAGMASK(being_solved.spec[*pos_viewed],BIT(Magic)|BIT(Royal)) && !is_piece_neutral(being_solved.spec[*pos_viewed])) { replace_observation_target(*pos_viewed); observing_walk[nbply] = pi_magic; /* ignore return value - it's ==false */ fork_is_square_observed_nested_delegate(temporary_hack_is_square_observed_specific[trait[nbply]], EVALUATE(observation)); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void intelligent_place_promoted_white_rider(piece_walk_type promotee_type, 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; int const dir = GuardDir[promotee_type-Pawn][placed_on].dir; square const target = GuardDir[promotee_type-Pawn][placed_on].target; TraceFunctionEntry(__func__); TraceWalk(promotee_type); TraceFunctionParam("%u",placed_index); TraceSquare(placed_on); TraceFunctionParamListEnd(); if (dir>=guard_dir_guard_uninterceptable) { /* nothing */ } else if (intelligent_reserve_promoting_white_pawn_moves_from_to(placed_comes_from, promotee_type, placed_on)) { occupy_square(placed_on,promotee_type,placed_flags); if (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(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void remember_mating_line(piece_walk_type checker_type, square const check_from, int delta) { int const diff = being_solved.king_square[Black]-check_from; int const dir = CheckDir[checker_type][diff]; TraceFunctionEntry(__func__); TraceWalk(checker_type); TraceSquare(check_from); TraceFunctionParam("%d",delta); TraceFunctionParamListEnd(); remember_to_keep_rider_line_open(check_from, being_solved.king_square[Black], dir, delta); if (delta==+1) init_disturb_mate_dir(check_from,dir); else fini_disturb_mate_dir(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static int find_interceptable_check_dir(piece_walk_type rider_type, square placed_on) { int result; square const king_pos = being_solved.king_square[White]; TraceFunctionEntry(__func__); TraceWalk(rider_type); TraceSquare(placed_on); TraceFunctionParamListEnd(); if (king_pos==initsquare) result = 0; else { int const diff = king_pos-placed_on; result = CheckDir[rider_type][diff]; if (result==diff) result = checkdir_uninterceptable; else if (result!=0) { square s; for (s = placed_on+result; s!=king_pos; s += result) if (!is_square_empty(s)) { result = 0; break; } } } TraceFunctionExit(__func__); TraceFunctionResult("%d",result); TraceFunctionResultEnd(); return result; }
static void identify_line(void) { square const sq_observer = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceSquare(sq_observer); TraceWalk(being_solved.board[sq_observer]); TraceEOL(); switch (being_solved.board[sq_observer]) { /* TODO simplify using classes? */ case Rook: case Queen: case Bishop: case NightRider: case Waran: case Camelrider: case Zebrarider: case Gnurider: case SuperBerolinaPawn: case SuperPawn: case RookHunter: case BishopHunter: case WesirRider: case FersRider: case Elephant: case Lion: case RookLion: case BishopLion: case NightRiderLion: case Pao: case Leo: case Vao: case Nao: case Locust: case NightLocust: case BishopLocust: case RookLocust: case Sirene: case Triton: case Nereide: case Kangaroo: case KangarooLion: case Rabbit: case Kao: case Elk: case RookMoose: case BishopMoose: case Eagle: case RookEagle: case BishopEagle: case Sparrow: case RookSparrow: case BishopSparrow: case Marguerite: case EquiHopper: case Orix: case EdgeHog: case Grasshopper: case NightriderHopper: case CamelRiderHopper: case ZebraRiderHopper: case GnuRiderHopper: case RookHopper: case BishopHopper: case ContraGras: case GrassHopper2: case GrassHopper3: case Bob: case EquiStopper: case MaoRider: case MoaRider: case MaoRiderLion: case MoaRiderLion: case Dolphin: case Bouncer : case RookBouncer: case BishopBouncer: identify_straight_line(); break; case Rose: case RoseLion: case RoseHopper: case RoseLocust: case Rao: identify_circular_line(); break; case SpiralSpringer: case DiagonalSpiralSpringer: case SpiralSpringer40: case SpiralSpringer20: case SpiralSpringer33: case SpiralSpringer11: case BoyScout: case GirlScout: identify_zigzag_line(); break; case DoubleGras: case DoubleRookHopper: case DoubleBishopper: identify_doublehopper_line(); break; case Amazone: case Empress: case Princess: case Gryphon: case Ship: case Gral: case Scorpion: case Querquisite: case MarineShip: identify_combined_rider_leaper_line(); break; case King: case Poseidon: case ErlKing: case Knight: case Zebra: case Camel: case Giraffe: case RootFiftyLeaper: case Bucephale: case Wesir: case Alfil: case Fers: case Dabbaba: case Gnu: case Antilope: case Squirrel: case Okapi: case Leap37: case Leap16: case Leap24: case Leap35: case Leap15: case Leap25: case Bison: case Zebu: case Leap36: case Mao: case Moa: case NonStopEquihopper: case NonStopOrix: case NonstopEquiStopper: case KingHopper: case KnightHopper: case MarineKnight: case Pawn: case BerolinaPawn: case ReversePawn: case ChinesePawn: case MarinePawn: case RadialKnight: case Treehopper: case Leafhopper : case GreaterTreehopper: case GreaterLeafhopper: case Skylla: case Charybdis: case Dragon: identify_leaper_pseudoline(); break; default: assert(0); break; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Validate an observation according to Imitators * @return true iff the observation is valid */ boolean imitator_validate_observation(slice_index si) { square const sq_observer = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure; boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); TraceWalk(being_solved.board[sq_observer]);TraceEOL(); switch (being_solved.board[sq_observer]) { case King: case ErlKing: case Knight: case Wesir: case Dabbaba: case Fers: case Alfil: case Bucephale: case Giraffe: case Camel: case Zebra: case Okapi: case Bison: case Gnu: case Antilope: case Squirrel: case RootFiftyLeaper: case Leap15: case Leap16: case Leap24: case Leap25: case Leap35: case Leap36: case Leap37: case Pawn: case BerolinaPawn: case ReversePawn: { square const sq_landing = move_generation_stack[CURRMOVE_OF_PLY(nbply)].arrival; result = are_all_imitator_arrivals_empty(sq_observer,sq_landing); break; } case Queen: case Rook: case Bishop: case NightRider: case Elephant: case Waran: case Camelrider: case Zebrarider: case Gnurider: case Amazone: case Empress: case Princess: case RookHunter: case BishopHunter: case WesirRider: case FersRider: result = avoid_observing_if_imitator_blocked_rider(); break; case Mao: case Moa: result = avoid_observing_if_imitator_blocked_chinese_leaper(); break; case NonStopEquihopper: case NonStopOrix: result = avoid_observing_if_imitator_blocked_nonstop_equihopper(); break; case Orix: result = avoid_observing_if_imitator_blocked_orix(); break; case EquiHopper: if (interceptable_observation[observation_context].vector_index1==0) result = avoid_observing_if_imitator_blocked_nonstop_equihopper(); else result = avoid_observing_if_imitator_blocked_orix(); break; case Grasshopper: case NightriderHopper: case CamelRiderHopper: case ZebraRiderHopper: case GnuRiderHopper: case RookHopper: case BishopHopper: case KingHopper: case KnightHopper: result = avoid_observing_if_imitator_blocked_rider_hopper(); break; case ContraGras: result = avoid_observing_if_imitator_blocked_contragrasshopper(); break; case GrassHopper2: result = avoid_observing_if_imitator_blocked_grasshopper_n(2); break; case GrassHopper3: result = avoid_observing_if_imitator_blocked_grasshopper_n(3); break; case Elk: case RookMoose: case BishopMoose: result = avoid_observing_if_imitator_blocked_angle_hopper(angle_45); break; case Eagle: case RookEagle: case BishopEagle: result = avoid_observing_if_imitator_blocked_angle_hopper(angle_90); break; case Sparrow: case RookSparrow: case BishopSparrow: result = avoid_observing_if_imitator_blocked_angle_hopper(angle_135); break; default: result = true; break; } if (result) result = pipe_validate_observation_recursive_delegate(si); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }