Пример #1
0
/* Instrument a battle branch with STConstraint* slices (typically for a reflex
 * stipulation)
 * @param si entry slice of branch to be instrumented
 * @param constraint identifies branch that constrains the attacker
 */
void battle_branch_insert_defense_goal_constraint(slice_index si,
                                                  slice_index constraint)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParam("%u",constraint);
  TraceFunctionParamListEnd();

  TraceStipulation(si);
  TraceStipulation(constraint);

  {
    slice_index const ready = branch_find_slice(STReadyForDefense,
                                                si,
                                                stip_traversal_context_intro);
    slice_index const prototype = alloc_goal_constraint_tester_slice(constraint);
    assert(ready!=no_slice);
    defense_branch_insert_slices(ready,&prototype,1);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #2
0
/* Instrument the solving machinery with Circe Kamikaze
 * @param si identifies the root slice of the solving machinery
 */
void circe_kamikaze_initialise_solving(slice_index si)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  anticirce_variant.on_occupied_rebirth_square_default = circe_on_occupied_rebirth_square_relaxed;
  circe_initialise_solving(si,&anticirce_variant,STMove,&move_insert_slices,STAnticirceConsideringRebirth);
  circe_instrument_solving(si,
                           STAnticirceConsideringRebirth,
                           STCirceDeterminedRebirth,
                           alloc_pipe(STAnticirceRemoveCapturer));
  circe_insert_rebirth_avoider(si,
                               STAnticirceConsideringRebirth,
                               STAnticirceConsideringRebirth,
                               alloc_fork_slice(STCirceKamikazeCaptureFork,
                                                no_slice),
                               STCirceRebirthAvoided,
                               STCirceDoneWithRebirth);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #3
0
static void instrument_testing(slice_index si, stip_structure_traversal *st)
{
  instrumentation_state_type * const state = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  if (SLICE_STARTER(si)==state->side)
  {
    assert(state->past_detector==no_slice);
    is_square_observed_insert_slice(si,alloc_pipe(STTransmutingKingDetectNonTransmutation));
    stip_traverse_structure_children(si,st);
    assert(state->past_detector!=no_slice);
    is_square_observed_insert_slice(si,
                                    alloc_fork_slice(STTransmutingKingIsSquareObserved,
                                                     state->past_detector));
    state->past_detector = no_slice;
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #4
0
/* Allocate a STGoalImmobileReachedTester slice.
 * @param starter_or_adversary is the starter immobilised or its adversary?
 * @return index of allocated slice
 */
slice_index
alloc_goal_immobile_reached_tester_slice(goal_applies_to_starter_or_adversary starter_or_adversary)
{
  slice_index result;

  TraceFunctionEntry(__func__);
  TraceValue("%u",starter_or_adversary);
  TraceFunctionParamListEnd();

  {
    slice_index const proxy = alloc_proxy_slice();
    slice_index const tester = alloc_pipe(STImmobilityTester);
    result = alloc_conditional_pipe(STGoalImmobileReachedTester,proxy);
    pipe_link(proxy,tester);
    link_to_branch(tester,alloc_defense_branch(1,1));
    SLICE_U(result).goal_filter.applies_to_who = starter_or_adversary;
  }

  TraceFunctionExit(__func__);
  TraceFunctionResult("%u",result);
  TraceFunctionResultEnd();
  return result;
}
Пример #5
0
static void keepmating_filter_inserter_help(slice_index si,
                                            stip_structure_traversal *st)
{
  insertion_state_type const * const state = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  stip_traverse_structure_children_pipe(si,st);

  {
    slice_index const prototype = alloc_appropriate_filter(state);
    if (prototype!=no_slice)
    {
      SLICE_STARTER(prototype) = advers(SLICE_STARTER(si));
      help_branch_insert_slices(si,&prototype,1);
    }
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #6
0
/* Intercept a guard by white
 * @param target guard of what square
 * @param dir_from_rider direction from guarding rider
 * @param go_on what to do after each successful interception?
 */
void intelligent_intercept_guard_by_white(square target,
                                          int dir_from_rider,
                                          void (*go_on)(void))
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%d",dir_from_rider);
  TraceFunctionParamListEnd();

  if (intelligent_reserve_masses(Black,1,piece_intercepts))
  {
    black_piece(target,dir_from_rider,go_on);
    intelligent_unreserve();
  }

  if (intelligent_reserve_masses(White,1,piece_intercepts))
  {
    white_piece(target,dir_from_rider,go_on);
    intelligent_unreserve();
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #7
0
static void init_disturb_mate_dir_pawn(square const check_from, int dir)
{
  square s;
  Flags const mask = BIT(Black)|BIT(Royal);

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%d",dir);
  TraceFunctionParamListEnd();

  for (s = check_from+dir; !TSTFULLFLAGMASK(being_solved.spec[s],mask); s += dir)
  {
    DisturbMateDirPawn[s+dir_up] = disturbance_by_pawn_interception_single;
    if (square_a5<=s && s<=square_h5)
      DisturbMateDirPawn[s+2*dir_up] = disturbance_by_pawn_interception_double;
  }

  /* only now - capture trumps interception */
  DisturbMateDirPawn[check_from+dir_up+dir_left] = disturbance_by_pawn_capture;
  DisturbMateDirPawn[check_from+dir_up+dir_right] = disturbance_by_pawn_capture;

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #8
0
static boolean is_attacked_exactly_once(square sq_departure, Side trait_ply)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParamListEnd();

  assert(!are_we_counting);

  are_we_counting = true;

  amu_attack_count = 0;
  single_attacker_departure = initsquare;

  is_square_observed_general_post_move_iterator_solve(advers(trait_ply),
                                                      sq_departure,
                                                      EVALUATE(observation));

  are_we_counting = false;

  TraceFunctionExit(__func__);
  TraceFunctionResult("%u",amu_attack_count==1);
  TraceFunctionResultEnd();
  return amu_attack_count==1;
}
Пример #9
0
static boolean avoid_observing_if_imitator_blocked_rider(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;
  numvec const step = -vec[interceptable_observation[observation_context].vector_index1];
  piece_walk_type const p = get_walk_of_piece_on_square(sq_observer);
  Flags const flags = being_solved.spec[sq_observer];

  TraceFunctionEntry(__func__);
  TraceSquare(sq_observer);
  TraceSquare(sq_landing);
  TraceFunctionParamListEnd();

  empty_square(sq_observer);/* an imitator might be disturbed by the moving rider! */
  result = are_all_imitator_lines_clear(step,step,sq_landing-sq_observer+step);
  occupy_square(sq_observer,p,flags);

  TraceFunctionExit(__func__);
  TraceFunctionResult("%u",result);
  TraceFunctionResultEnd();
  return result;
}
Пример #10
0
void push_move(void)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParamListEnd();

  INCREMENT_COUNTER(add_to_move_generation_stack);

  assert(current_move[nbply]<toppile);

  TraceSquare(curr_generation->departure);
  TraceSquare(curr_generation->arrival);
  TraceEOL();

  curr_generation->capture = curr_generation->arrival;
  ++current_move[nbply];
  move_generation_stack[CURRMOVE_OF_PLY(nbply)] = *curr_generation;
  move_generation_stack[CURRMOVE_OF_PLY(nbply)].id = current_move_id[nbply];
  ++current_move_id[nbply];
  TraceValue("%u\n",CURRMOVE_OF_PLY(nbply));

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #11
0
/* 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 bgl_adjuster_solve(slice_index si)
{
  long int const diff = calculate_diff(CURRMOVE_OF_PLY(nbply));

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  assert(BGL_values[trait[nbply]]>=diff); /* BGL enforcer takes care of that */

  if (BGL_global)
  {
    do_bgl_adjustment(White,diff);
    do_bgl_adjustment(Black,diff);
  }
  else
    do_bgl_adjustment(trait[nbply],diff);

  pipe_solve_delegate(si);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #12
0
/* 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 threat_solver_solve(slice_index si)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  threats[nbply] = allocate_table();

  if (!is_in_check(SLICE_STARTER(si)))
  {
    fork_solve_delegate(si);
    threat_lengths[nbply] = solve_result-1;
  }

  pipe_solve_delegate(si);

  free_table(threats[nbply]);
  threat_lengths[nbply] = no_threats_found;
  threats[nbply] = table_nil;

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #13
0
/* Instrument a branch for detecting whether the defense was forced to reach a
 * goal
 * @param si root of branch to be instrumented
 * @param goal identifies slice leading towards goal
 */
void battle_branch_insert_self_end_of_branch_goal(slice_index si,
                                                  slice_index goal)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParam("%u",goal);
  TraceFunctionParamListEnd();

  TraceStipulation(si);
  TraceStipulation(goal);

  {
    slice_index const ready = branch_find_slice(STReadyForDefense,
                                                si,
                                                stip_traversal_context_intro);
    slice_index const prototype = alloc_fork_slice(STEndOfBranchGoal,goal);
    assert(ready!=no_slice);
    defense_branch_insert_slices(ready,&prototype,1);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #14
0
/* Like defense_branch_insert_slices, but starting at a proxy slice
 * @param base_rank used instead of proxy for determining the current position in the
 *             sequence of defense branches
 */
void defense_branch_insert_slices_behind_proxy(slice_index proxy,
                                               slice_index const prototypes[],
                                               unsigned int nr_prototypes,
                                               slice_index base)
{
  stip_structure_traversal st;
  branch_slice_insertion_state_type state =
  {
    prototypes, nr_prototypes,
    slice_rank_order, nr_slice_rank_order_elmts, 0,
    branch_slice_rank_order_recursive,
    0,
    proxy,
    0
  };

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",proxy);
  TraceFunctionParam("%u",nr_prototypes);
  TraceFunctionParam("%u",base);
  TraceFunctionParamListEnd();

  state.base_rank = get_slice_rank(STAttackPlayed,&state);
  assert(state.base_rank!=no_slice_rank);
  ++state.base_rank;

  slice_insertion_init_traversal(&st,&state,stip_traversal_context_defense);
  move_init_slice_insertion_traversal(&st);

  state.base_rank = get_slice_rank(SLICE_TYPE(base),&state);
  stip_traverse_structure(proxy,&st);

  deallocate_slice_insertion_prototypes(prototypes,nr_prototypes);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #15
0
void intelligent_place_white_piece(unsigned int placed_index,
                                   square placed_on,
                                   void (*go_on)(void))
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",placed_index);
  TraceSquare(placed_on);
  TraceFunctionParamListEnd();

  switch (white[placed_index].type)
  {
    case Queen:
      intelligent_place_white_queen(placed_index,placed_on,go_on);
      break;

    case Rook:
    case Bishop:
      intelligent_place_white_rider(placed_index,placed_on,go_on);
      break;

    case Knight:
      intelligent_place_white_knight(placed_index,placed_on,go_on);
      break;

    case Pawn:
      intelligent_place_unpromoted_white_pawn(placed_index,placed_on,go_on);
      intelligent_place_promoted_white_pawn(placed_index,placed_on,go_on);
      break;

    default:
      assert(0);
      break;
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #16
0
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;
}
Пример #17
0
static void init_disturb_mate_dir_rider(square const check_from, int dir)
{
  vec_index_type i;
  unsigned int disturb_index = 0;
  Flags const mask = BIT(Black)|BIT(Royal);

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%d",dir);
  TraceFunctionParamListEnd();

  disturbance_by_rider_index_ranges[Queen-Queen].start = disturb_index;
  disturbance_by_rider_index_ranges[Rook-Queen].start = disturb_index;
  for (i = vec_rook_start; i<=vec_rook_end; ++i)
    if (vec[i]>0)
    {
      square s;
      for (s = check_from; !TSTFULLFLAGMASK(being_solved.spec[s],mask); s += dir)
        init_disturb_mate_rider_onedir(s,vec[i],disturb_index);
      ++disturb_index;
    }
  disturbance_by_rider_index_ranges[Rook-Queen].end = disturb_index-1;

  disturbance_by_rider_index_ranges[Bishop-Queen].start = disturb_index;
  for (i = vec_bishop_start; i<=vec_bishop_end; ++i)
    if (vec[i]>0)
    {
      square s;
      for (s = check_from; !TSTFULLFLAGMASK(being_solved.spec[s],mask); s += dir)
        init_disturb_mate_rider_onedir(s,vec[i],disturb_index);
      ++disturb_index;
    }
  disturbance_by_rider_index_ranges[Bishop-Queen].end = disturb_index-1;
  disturbance_by_rider_index_ranges[Queen-Queen].end = disturb_index-1;

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #18
0
static void next_rider_interception(void)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%p",rider_interception_top);
  TraceFunctionParam("%u",rider_interception_top->next);
  TraceFunctionParam("%u",rider_interception_top->end);
  TraceSquare(rider_interception_top->placed_on);
  TraceFunctionParamListEnd();

  if (rider_interception_top->next<=rider_interception_top->end)
  {
    square const placed_on = rider_interception_top->placed_on;
    int const dir = DisturbMateDirRider[rider_interception_top->next][placed_on].dir;
    square const target = DisturbMateDirRider[rider_interception_top->next][placed_on].target;

    assert(dir!=disturbance_by_rider_uninterceptable);
    ++rider_interception_top->next;

    if (dir!=0 && is_line_empty(placed_on,target,dir))
      intelligent_intercept_black_move(placed_on,target,&next_rider_interception);
    else
      next_rider_interception();

    assert(rider_interception_top->next>0);
    --rider_interception_top->next;
  }
  else
  {
    rider_interception_stack_elmt_type * const save_top = rider_interception_top;
    rider_interception_top = rider_interception_top->succ;
    rider_placed();
    rider_interception_top = save_top;
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #19
0
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();
}
Пример #20
0
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;
}
Пример #21
0
/* Shorten a help branch by 1 half move
 * @param identifies entry slice of branch to be shortened
 */
void help_branch_shorten(slice_index adapter)
{
  slice_index const next = SLICE_NEXT1(adapter);

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",adapter);
  TraceFunctionParamListEnd();

  assert(SLICE_TYPE(adapter)==STHelpAdapter);

  {
    /* find the new spot for adapter by inserting a copy */
    slice_index const prototype = copy_slice(adapter);
    help_branch_insert_slices(next,&prototype,1);
  }

  {
    /* move adapter to its new spot */
    slice_index const copy = branch_find_slice(STHelpAdapter,
                                               next,
                                               stip_traversal_context_help);
    assert(copy!=no_slice);
    pipe_link(SLICE_PREV(adapter),next);
    pipe_append(copy,adapter);
    pipe_remove(copy);
  }

  /* adjust the length and min_length members */
  --SLICE_U(adapter).branch.length;
  if (SLICE_U(adapter).branch.min_length<=0)
    increase_min_length(adapter);
  --SLICE_U(adapter).branch.min_length;
  branch_shorten_slices(next,STHelpAdapter,stip_traversal_context_help);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #22
0
/* Detect starter field with the starting side if possible.
 * @param si identifies slice being traversed
 * @param st status of traversal
 */
void fork_detect_starter(slice_index si, stip_structure_traversal *st)
{
  slice_index const fork = SLICE_NEXT2(si);

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  stip_traverse_structure_next_branch(si,st);

  if (SLICE_STARTER(si)==no_side)
  {
    if (SLICE_STARTER(fork)==no_side)
    {
      stip_traverse_structure_children_pipe(si,st);
      SLICE_STARTER(si) = SLICE_STARTER(SLICE_NEXT1(si));
    }
    else
      SLICE_STARTER(si) = SLICE_STARTER(fork);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #23
0
/* Initialise a move traversal structure with default visitors
 * @param st to be initialised
 * @param param parameter to be passed t operations
 */
void stip_moves_traversal_init(stip_moves_traversal *st, void *param)
{
  unsigned int i;

  TraceFunctionEntry(__func__);
  TraceFunctionParamListEnd();

  st->map = moves_children_traversers;

  for (i = 0; i!=nr_slice_types; ++i)
    st->map.visitors[i] = moves_children_traversers.visitors[i];

  for (i = 0; i!=max_nr_slices; ++i)
    st->remaining_watermark[i] = 0;

  st->context = stip_traversal_context_intro;
  st->activity = stip_traversal_activity_solving;
  st->remaining = STIP_MOVES_TRAVERSAL_LENGTH_UNINITIALISED;
  st->full_length = STIP_MOVES_TRAVERSAL_LENGTH_UNINITIALISED;
  st->param = param;

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #24
0
/* Try to solve in solve_nr_remaining half-moves.
 * @param si slice index
 * @note assigns solve_result the length of solution found and written, i.e.:
 *            previous_move_is_illegal the move just played is illegal
 *            this_move_is_illegal     the move being played is illegal
 *            immobility_on_next_move  the moves just played led to an
 *                                     unintended immobility on the next move
 *            <=n+1 length of shortest solution found (n+1 only if in next
 *                                     branch)
 *            n+2 no solution found in this branch
 *            n+3 no solution found in next branch
 *            (with n denominating solve_nr_remaining)
 */
void take_make_circe_collect_rebirth_squares_solve(slice_index si)
{
  numecoup i;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  if (CURRMOVE_OF_PLY(nbply)>MOVEBASE_OF_PLY(nbply))
  {
    solve_result = MOVE_HAS_SOLVED_LENGTH();

    for (i = CURRMOVE_OF_PLY(nbply); i>MOVEBASE_OF_PLY(nbply); --i)
    {
      ++take_make_circe_current_rebirth_square_index[stack_pointer];
      rebirth_square[take_make_circe_current_rebirth_square_index[stack_pointer]] = move_generation_stack[i].arrival;
    }
  }
  else
    solve_result = this_move_is_illegal;

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #25
0
static void identify_doublehopper_line(void)
{
  square const sq_observer = move_generation_stack[CURRMOVE_OF_PLY(nbply)].departure;
  square const sq_observee = move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture;
  vec_index_type const idx_firstleg = interceptable_observation[observation_context].vector_index1;
  numvec const dir_firstleg = vec[idx_firstleg];
  vec_index_type const sq_intermediate = interceptable_observation[observation_context].auxiliary;
  square sq_curr = sq_intermediate+dir_firstleg;

  TraceFunctionEntry(__func__);
  TraceFunctionParamListEnd();

  /* we identify doublehopper lines by the intermediate square and the square
   * just off the board on the first leg
   */

  while (!is_square_blocked(sq_curr))
    sq_curr += dir_firstleg;

  PushMagicView(sq_observee,sq_observer,sq_curr,sq_intermediate);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #26
0
void move_effect_journal_do_remember_ghost(void)
{
  move_effect_journal_index_type const top = move_effect_journal_base[nbply+1];
  move_effect_journal_entry_type * const top_elmt = &move_effect_journal[top];
  move_effect_journal_index_type const base = move_effect_journal_base[nbply];
  move_effect_journal_index_type const capture = base+move_effect_journal_index_offset_capture;
  square const sq_capture = move_effect_journal[capture].u.piece_removal.on;
  piece_walk_type const removed = move_effect_journal[capture].u.piece_removal.walk;
  Flags const removedspec = move_effect_journal[capture].u.piece_removal.flags;

  TraceFunctionEntry(__func__);
  TraceFunctionParamListEnd();

  assert(top+1<move_effect_journal_size);
  assert(move_effect_journal[capture].type==move_effect_piece_removal);

  top_elmt->type = move_effect_remember_ghost;
  top_elmt->reason = move_effect_reason_regular_capture;
  top_elmt->u.handle_ghost.pos = nr_ghosts;
  top_elmt->u.handle_ghost.ghost.walk = removed;
  top_elmt->u.handle_ghost.ghost.flags = removedspec;
  top_elmt->u.handle_ghost.ghost.on = sq_capture;
#if defined(DOTRACE)
  top_elmt->id = move_effect_journal_next_id++;
  TraceValue("%lu",top_elmt->id);
  TraceEOL();
#endif

  ++move_effect_journal_base[nbply+1];

  underworld[nr_ghosts] = top_elmt->u.handle_ghost.ghost;
  ++nr_ghosts;

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #27
0
/* Generate moves for a piece with a specific walk from a specific departure
 * square.
 * @note the piece on the departure square need not necessarily have walk p
 */
void marscirce_generate_from_rebirth_square(slice_index si)
{
  circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer-1];
  square const sq_departure = curr_generation->departure;
  square const sq_rebirth = context->rebirth_square;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceSquare(sq_rebirth);
  TraceFunctionParamListEnd();

  assert(circe_rebirth_context_stack_pointer>0);

  curr_generation->departure = sq_rebirth;

  occupy_square(sq_rebirth,context->reborn_walk,context->reborn_spec);
  pipe_move_generation_delegate(si);
  empty_square(sq_rebirth);

  curr_generation->departure = sq_departure;

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #28
0
/* Solve the next2 part of a fork
 * @param si identifies the fork slice
 * @param n maximum number of moves (typically slack_length or
 *         length_unspecified)
 * @return 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
 */
stip_length_type testing_pipe_solve_delegate(slice_index si, stip_length_type n)
{
  stip_length_type result;
  stip_length_type const save_solve_nr_remaining = solve_nr_remaining;
  stip_length_type const save_solve_result = solve_result;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParam("%u",n);
  TraceFunctionParamListEnd();

  solve_nr_remaining = n;

  fork_solve_delegate(si);
  result = solve_result;

  solve_nr_remaining = save_solve_nr_remaining;
  solve_result = save_solve_result;

  TraceFunctionExit(__func__);
  TraceFunctionResult("%u",result);
  TraceFunctionResultEnd();
  return result;
}
Пример #29
0
/* Spin a copy off a conditional pipe to add it to the root or set play branch
 * @param si identifies (non-root) slice
 * @param st address of structure representing traversal
 */
void conditional_pipe_spin_off_copy(slice_index si,
                                    stip_structure_traversal *st)
{
  spin_off_state_type * const state = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  state->spun_off[si] = copy_slice(si);

  stip_traverse_structure_children_pipe(si,st);

  if (state->spun_off[SLICE_NEXT1(si)]==no_slice)
  {
    dealloc_slice(state->spun_off[si]);
    state->spun_off[si] = no_slice;
  }
  else
    link_to_branch(state->spun_off[si],state->spun_off[SLICE_NEXT1(si)]);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Пример #30
0
/* Allocate a system of slices that tests whether mate has been reached
 * @return index of entry slice
 */
slice_index alloc_goal_mate_reached_tester_system(void)
{
  slice_index result;

  TraceFunctionEntry(__func__);
  TraceFunctionParamListEnd();

  {
    slice_index const mate_tester = alloc_pipe(STGoalMateReachedTester);
    slice_index const check_tester = alloc_goal_check_reached_tester_slice(goal_applies_to_starter);
    slice_index const immobile_tester = alloc_goal_immobile_reached_tester_slice(goal_applies_to_starter);

    pipe_link(mate_tester,check_tester);
    pipe_link(check_tester,immobile_tester);
    pipe_link(immobile_tester,alloc_true_slice());

    result = mate_tester;
  }

  TraceFunctionExit(__func__);
  TraceFunctionResult("%u",result);
  TraceFunctionResultEnd();
  return result;
}