예제 #1
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 exclusive_chess_legality_tester_solve(slice_index si)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  if ((table_length(exclusive_chess_undecidable_continuations[parent_ply[nbply]])
       +exclusive_chess_nr_continuations_reaching_goal[parent_ply[nbply]])
      >1)
  {
    if (is_current_move_in_table(exclusive_chess_undecidable_continuations[parent_ply[nbply]]))
      solve_result = this_move_is_illegal;
    else
      switch (conditional_pipe_solve_delegate(temporary_hack_mate_tester[advers(trait[nbply])]))
      {
        case this_move_is_illegal:
          solve_result = this_move_is_illegal;
          break;

        case previous_move_has_not_solved:
          pipe_solve_delegate(si);
          break;

        default:
          solve_result = previous_move_has_solved;
          break;
      }
  }
  else
    pipe_solve_delegate(si);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
예제 #2
0
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;
}
예제 #3
0
/* @return true iff >=1 black pieces needed to be immobilised
 */
boolean intelligent_stalemate_immobilise_black(void)
{
    boolean result = false;
    immobilisation_state_type immobilisation_state = null_state;
    castling_rights_type const save_castling_flag = being_solved.castling_rights;

    TraceFunctionEntry(__func__);
    TraceFunctionParamListEnd();

    /* we temporarily disable Black castling for two reasons:
     * 1. we are solving from the target position here where king or rook may be
     *    at different positions than in the diagram; attempting to generate
     *    (let alone) execute castling moves would cause problems in this case
     * 2. castlings are presumable never the only legal black moves
     */
    CLRCASTLINGFLAGMASK(Black,k_cancastle);
    current_state = &immobilisation_state;

    conditional_pipe_solve_delegate(current_start_slice);

    next_trouble_maker();
    current_state = 0;
    being_solved.castling_rights = save_castling_flag;

    if (immobilisation_state.worst.requirement>no_requirement)
    {
        assert(immobilisation_state.worst.target_square!=initsquare);

        TraceSquare(immobilisation_state.worst.target_square);
        TraceValue("%u",immobilisation_state.worst.requirement);
        TraceValue("%u\n",immobilisation_state.worst.nr_flight_directions);

        if (immobilisation_state.worst.requirement<immobilisation_impossible)
        {
            intelligent_stalemate_pin_black_piece(immobilisation_state.worst.target_square);

            if (immobilisation_state.worst.requirement<pin_required
                    && can_we_block_all_necessary_squares(&immobilisation_state.worst))
                block_squares(&immobilisation_state.worst);
        }

        result = true;
    }

    TraceFunctionExit(__func__);
    TraceFunctionResult("%u",result);
    TraceFunctionResultEnd();
    return result;
}
예제 #4
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 doublemate_filter_solve(slice_index si)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  if (conditional_pipe_solve_delegate(si)==previous_move_has_not_solved)
    SETFLAG(goal_preprequisites_met[nbply],goal_doublemate);

  pipe_solve_delegate(si);
  CLRFLAG(goal_preprequisites_met[nbply],goal_doublemate);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
예제 #5
0
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;
}
예제 #6
0
파일: mummer.c 프로젝트: Die9teWoge/popeye
/* Validate an observation according to Ultra-Mummer
 * @return true iff the observation is valid
 */
boolean ultra_mummer_validate_observation(slice_index si)
{
  Side const side_observing = trait[nbply];
  boolean result;

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

  conditional_pipe_solve_delegate(temporary_hack_ultra_mummer_length_measurer[side_observing]);

  result = (*mummer_measure_length[side_observing])()==mum_length[nbply];

  if (result)
    result = pipe_validate_observation_recursive_delegate(si);

  TraceFunctionExit(__func__);
  TraceFunctionResult("%u",result);
  TraceFunctionResultEnd();
  return result;
}
예제 #7
0
/* Detect exclusivity and solve accordingly
 * @param si slice index
 * @param n maximum number of half moves
 * @return see exclusive_chess_exclusivity_detector_solve
 * @note The caller must have initialized ply_horizon for recursive testing for
 *       exclusivity and is responsible of allocating
 *       exclusive_chess_undecidable_continuations[nbply] before and deallocating it
 *       after the invokation.
 */
static void detect_exclusivity_and_solve_accordingly(slice_index si)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  exclusive_chess_nr_continuations_reaching_goal[nbply] = 0;
  nr_decidable_continuations_not_reaching_goal[nbply] = 0;

  conditional_pipe_solve_delegate(temporary_hack_exclusive_mating_move_counter[SLICE_STARTER(si)]);

  TraceValue("%u",nbply);
  TraceValue("%u",nr_decidable_continuations_not_reaching_goal[nbply]);
  TraceValue("%u",exclusive_chess_nr_continuations_reaching_goal[nbply]);
  TraceValue("%u\n",table_length(exclusive_chess_undecidable_continuations[nbply]));

  ply_horizon = maxply;

  pipe_solve_delegate(si);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}