/* (Approximately) depth-first traversl of the stipulation * @param root start of the stipulation (sub)tree * @param st address of data structure holding parameters for the operation */ void stip_traverse_moves(slice_index root, stip_moves_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",root); TraceFunctionParam("%p",st); TraceFunctionParamListEnd(); TraceValue("%u",st->remaining); TraceEOL(); TraceEnumerator(slice_type,SLICE_TYPE(root)); TraceEOL(); assert(SLICE_TYPE(root)<=nr_slice_types); if (st->remaining_watermark[root]<=st->remaining) { stip_moves_visitor const operation = st->map.visitors[SLICE_TYPE(root)]; assert(operation!=0); (*operation)(root,st); st->remaining_watermark[root] = st->remaining+1; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Iterate if square observation testing uses a post-move iterating slice (e.g. * for MarsCirce Super) * @param si identifies move generator slice */ void square_observation_post_move_iterator_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); ++current_level; TraceValue("%u",current_level);TraceEOL(); if (current_level>iteration_level) { iteration_level = current_level; TraceValue("%u",iteration_level);TraceValue("%u",current_level);TraceEOL(); } do { pipe_is_square_observed_delegate(si); } while (iteration_level>current_level && !observation_result); --current_level; TraceValue("%u",current_level);TraceEOL(); post_move_iteration_cancel(); 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(); }
/* Plan optimising away a STOhneschachStopIfCheckAndNotMate slice * @param stop identifies STOhneschachStopIfCheckAndNotMate slice * @param to_be_optimised true iff stop is going to be optimised away */ void ohneschach_stop_if_check_plan_to_optimise_away_stop(slice_index stop, boolean to_be_optimised) { slice_index const immobility_tester = SLICE_NEXT2(stop); TraceFunctionEntry(__func__); TraceFunctionParam("%u",stop); TraceFunctionParam("%u",to_be_optimised); TraceFunctionParamListEnd(); TraceValue("%u",fate[immobility_tester]); TraceEOL(); if (to_be_optimised) { fate[stop] = fate_stop_to_be_optimised; if (fate[immobility_tester]==fate_dont_know) fate[immobility_tester] = fate_immobility_tester_obsolete; } else { fate[stop] = fate_stop_not_to_be_optimised; fate[immobility_tester] = fate_immobility_tester_still_used; } TraceValue("->%u",fate[immobility_tester]); TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void post_move_iteration_init_ply(void) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceValue("%u",current_level);TraceEOL(); iteration_level = current_level; TraceValue("%u",iteration_level);TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void post_move_iteration_end(void) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceValue("%u",iteration_level);TraceValue("%u",current_level);TraceEOL(); assert(iteration_level==current_level+1); --iteration_level; TraceValue("%u",iteration_level);TraceValue("%u",current_level);TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* iterate until we detect an input token that identifies the user's language * @return the detected language */ static Language detect_user_language(char *tok) { Language result = LanguageCount; TraceFunctionEntry(__func__); TraceFunctionParam("%s",tok); TraceFunctionParamListEnd(); { Language candidate; for (candidate = 0; candidate<LanguageCount; ++candidate) { TraceValue("%u",candidate);TraceEOL(); if (GetUniqIndex(GlobalTokenCount,GlobalTokenString[candidate],tok)==BeginProblem) { result = candidate; break; } } } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static boolean advance_rebirth_square(void) { boolean result = true; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); do { if (circe_rebirth_context_stack[circe_rebirth_context_stack_pointer].rebirth_square<square_h8) ++circe_rebirth_context_stack[circe_rebirth_context_stack_pointer].rebirth_square; else { circe_rebirth_context_stack[circe_rebirth_context_stack_pointer].rebirth_square = initsquare; result = false; break; } } while (is_square_blocked(circe_rebirth_context_stack[circe_rebirth_context_stack_pointer].rebirth_square)); TraceSquare(circe_rebirth_context_stack[circe_rebirth_context_stack_pointer].rebirth_square); TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static boolean are_all_imitator_lines_clear(numvec diff_first_necessarily_empty, numvec step, numvec diff_first_not_necessarily_empty) { boolean result = true; unsigned int i; TraceFunctionEntry(__func__); TraceValue("%d",diff_first_necessarily_empty); TraceValue("%d",step); TraceValue("%d",diff_first_not_necessarily_empty); TraceFunctionParamListEnd(); TraceValue("%u",being_solved.number_of_imitators); TraceEOL(); for (i = 0; i!=being_solved.number_of_imitators; ++i) if (!is_imitator_line_clear(i,diff_first_necessarily_empty,step,diff_first_not_necessarily_empty)) { result = false; break; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Is an en passant capture possible to a specific square? * @param side for which side * @param s the square * @return true iff an en passant capture to s is currently possible */ boolean en_passant_is_capture_possible_to(Side side, square s) { boolean result = false; ply const ply_parent = parent_ply[nbply]; TraceFunctionEntry(__func__); TraceEnumerator(Side,side); TraceSquare(s); TraceFunctionParamListEnd(); TraceEnumerator(Side,trait[ply_parent]); TraceEOL(); if (trait[ply_parent]!=side) { unsigned int i; for (i = en_passant_top[ply_parent-1]+1; i<=en_passant_top[ply_parent]; ++i) if (en_passant_multistep_over[i]==s) { result = true; break; } } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Start a new ply as a sibling of the current ply, making the child the new * current ply * @param side the side at the move in the child ply */ void siblingply(Side side) { ply const elder = nbply; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); assert(ply_watermark<maxply); ply_stack[ply_stack_pointer++] = nbply; nbply = ply_watermark+1; current_move[nbply] = current_move[ply_watermark]; current_move_id[nbply] = current_move_id[ply_watermark]; ++ply_watermark; TraceValue("%u",elder); TraceValue("%u",nbply); TraceEOL(); parent_ply[nbply] = parent_ply[elder]; trait[nbply] = side; move_effect_journal_base[nbply+1] = move_effect_journal_base[nbply]; en_passant_top[nbply] = en_passant_top[nbply-1]; promotion_horizon[nbply] = move_effect_journal_base[nbply]; post_move_iteration_init_ply(); 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(); }
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; }
boolean pawn_check(validator_id evaluate) { square const sq_target = move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture; SquareFlags const capturable = trait[nbply]==White ? CapturableByWhPawnSq : CapturableByBlPawnSq; boolean result = false; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceSquare(sq_target); TraceEOL(); if (TSTFLAG(sq_spec[sq_target],capturable) || observing_walk[nbply]==Orphan || observing_walk[nbply]>=Hunter0) { numvec const dir_forward = trait[nbply]==White ? dir_up : dir_down; numvec const dir_forward_right = dir_forward+dir_right; numvec const dir_forward_left = dir_forward+dir_left; if (pawn_test_check(sq_target-dir_forward_right,sq_target,evaluate)) result = true; else if (pawn_test_check(sq_target-dir_forward_left,sq_target,evaluate)) result = true; else if (en_passant_test_check(dir_forward_right,&pawn_test_check,evaluate)) result = true; else if (en_passant_test_check(dir_forward_left,&pawn_test_check,evaluate)) result = true; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static void stip_traverse_moves_defense_adapter(slice_index si, stip_moves_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (st->context==stip_traversal_context_intro) { assert(st->remaining==STIP_MOVES_TRAVERSAL_LENGTH_UNINITIALISED); assert(st->full_length==STIP_MOVES_TRAVERSAL_LENGTH_UNINITIALISED); st->full_length = SLICE_U(si).branch.length-slack_length; TraceValue("->%u",st->full_length); TraceEOL(); st->remaining = st->full_length; st->context = stip_traversal_context_defense; stip_traverse_moves_pipe(si,st); st->context = stip_traversal_context_intro; st->remaining = STIP_MOVES_TRAVERSAL_LENGTH_UNINITIALISED; st->full_length = STIP_MOVES_TRAVERSAL_LENGTH_UNINITIALISED; } else stip_traverse_moves_pipe(si,st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
boolean riders_check(vec_index_type kanf, vec_index_type kend, validator_id evaluate) { square const sq_target = move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture; boolean result = false; TraceFunctionEntry(__func__); TraceSquare(sq_target); TraceFunctionParamListEnd(); ++observation_context; TraceEnumerator(Side,trait[nbply],"\n"); for (interceptable_observation[observation_context].vector_index1 = kanf; interceptable_observation[observation_context].vector_index1<= kend; ++interceptable_observation[observation_context].vector_index1) { square const sq_departure = find_end_of_line(sq_target,vec[interceptable_observation[observation_context].vector_index1]); TraceSquare(sq_departure);TraceEOL(); if (EVALUATE_OBSERVATION(evaluate,sq_departure,sq_target)) { result = true; break; } } --observation_context; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static boolean is_imitator_line_clear(unsigned int i, numvec diff_first_necessarily_empty, numvec step, numvec diff_first_not_necessarily_empty) { boolean result = true; square const sq_first_not_necessarily_empty = being_solved.isquare[i]+diff_first_not_necessarily_empty; square sq_curr; TraceFunctionEntry(__func__); TraceValue("%u",i); TraceValue("%d",diff_first_necessarily_empty); TraceValue("%d",step); TraceValue("%d",diff_first_not_necessarily_empty); TraceFunctionParamListEnd(); for (sq_curr = being_solved.isquare[i]+diff_first_necessarily_empty; sq_curr!=sq_first_not_necessarily_empty; sq_curr += step) { TraceSquare(sq_curr);TraceEOL(); if (!is_square_empty(sq_curr)) { result = false; break; } } 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(); }
static char *ParseLength(char *tok, stip_length_type *length) { char *end; unsigned long tmp_length; TraceFunctionEntry(__func__); TraceFunctionParam("%s",tok); TraceFunctionParamListEnd(); if (tok!=0 && *tok==0) /* allow white space before length, e.g. "dia 4" */ tok = ReadNextTokStr(); tmp_length = strtoul(tok,&end,10); TraceValue("%ld",tmp_length); TraceEOL(); if (tok==end || tmp_length>UINT_MAX) { output_plaintext_input_error_message(WrongInt,0); tok = 0; } else { *length = tmp_length; tok = end; } TraceFunctionExit(__func__); TraceFunctionResult("%s",tok); TraceFunctionResultEnd(); return tok; }
/* Produce slices representing set play. * This is supposed to be invoked from within the slice type specific * functions invoked by stip_apply_setplay. * @param adapter identifies the adapter slice into the battle branch * @param state address of structure holding state */ void battle_branch_make_setplay(slice_index adapter, spin_off_state_type *state) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { slice_index const start = branch_find_slice(STReadyForDefense, adapter, stip_traversal_context_intro); stip_structure_traversal st; slice_index const notend = branch_find_slice(STNotEndOfBranchGoal, adapter, stip_traversal_context_intro); slice_index const prototype = alloc_pipe(STEndOfRoot); assert(notend!=no_slice); defense_branch_insert_slices(notend,&prototype,1); assert(start!=no_slice); stip_structure_traversal_init(&st,state); st.context = stip_traversal_context_defense; stip_structure_traversal_override_by_structure(&st, slice_structure_pipe, ©_to_setplay); stip_structure_traversal_override_by_structure(&st, slice_structure_branch, ©_to_setplay); stip_structure_traversal_override_by_structure(&st, slice_structure_fork, ©_to_setplay); stip_structure_traversal_override_single(&st,STEndOfRoot,&serve_as_root_hook); stip_traverse_structure(start,&st); TraceValue("%u",state->spun_off[start]); TraceEOL(); state->spun_off[adapter] = state->spun_off[start]; } TraceValue("%u",state->spun_off[adapter]); TraceEOL(); TraceFunctionExit(__func__); TraceFunctionParamListEnd(); }
/* 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 move_execution_post_move_iterator_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); TraceValue("%u",iteration_level);TraceValue("%u",current_level);TraceEOL(); pipe_solve_delegate(si); TraceValue("%u",iteration_level);TraceValue("%u",current_level);TraceEOL(); if (iteration_level==current_level) pop_move(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void optimise_stop(slice_index stop, stip_structure_traversal *st) { slice_index const immobility_tester = SLICE_NEXT2(stop); TraceFunctionEntry(__func__); TraceFunctionParam("%u",stop); TraceFunctionParamListEnd(); TraceValue("%u",fate[stop]); TraceEOL(); TraceValue("%u",immobility_tester); TraceValue("%u",fate[immobility_tester]); TraceEOL(); switch (fate[stop]) { case fate_stop_to_be_optimised: if (fate[immobility_tester]==fate_immobility_tester_obsolete) dealloc_slices(immobility_tester); if (SLICE_TESTER(stop)!=no_slice && fate[SLICE_TESTER(stop)]==fate_dont_know) /* substitute unreachable tester slice */ pipe_substitute(SLICE_TESTER(stop),alloc_pipe(STOhneschachStopIfCheck)); pipe_substitute(stop,alloc_pipe(STOhneschachStopIfCheck)); break; case fate_stop_not_to_be_optimised: assert(fate[immobility_tester]!=fate_immobility_tester_obsolete); break; default: assert(0); break; } fate[stop] = fate_dont_know; fate[immobility_tester] = fate_dont_know; stip_traverse_structure_children_pipe(stop,st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Add the copy of a slice into the set play branch * @param si slice index * @param st state of traversal */ static void copy_to_setplay(slice_index si, stip_structure_traversal *st) { spin_off_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); TraceValue("%u",state->spun_off[SLICE_NEXT1(si)]); TraceEOL(); state->spun_off[si] = copy_slice(si); link_to_branch(state->spun_off[si],state->spun_off[SLICE_NEXT1(si)]); TraceValue("%u",state->spun_off[si]); TraceEOL(); 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(); }
/* 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 reset_unsolvable_solve(slice_index si) { stip_length_type const save_max_unsolvable = max_unsolvable; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); max_unsolvable = slack_length; TraceValue("->%u",max_unsolvable); TraceEOL(); pipe_solve_delegate(si); max_unsolvable = save_max_unsolvable; TraceValue("->%u",max_unsolvable); TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Deallocate the table that was last allocated. * @param expected_top_table table expected to be freed by caller */ void free_table(table expected_top_table) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceValue("%u",number_of_tables); TraceEOL(); assert(number_of_tables>0); assert(number_of_tables==expected_top_table); --number_of_tables; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
void post_move_iteration_solve_fork(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); ++current_level; TraceValue("%u",current_level);TraceEOL(); if (current_level>iteration_level) { iteration_level = current_level; TraceValue("%u",iteration_level);TraceValue("%u",current_level);TraceEOL(); } fork_solve_delegate(si); --current_level; TraceValue("%u",current_level);TraceEOL(); 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(); }
boolean post_move_iteration_ply_was_ended(void) { boolean result = iteration_level==current_level; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceValue("%u",iteration_level);TraceValue("%u",current_level);TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Determine whether the current post move iteration participant has the lock * @param true iff it has */ boolean post_move_have_i_lock(void) { boolean const result = iteration_level==current_level+1; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceValue("%u",iteration_level);TraceValue("%u",current_level);TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }