Ejemplo n.º 1
0
static slice_index make_mate_tester_fork(Side side)
{
  slice_index result;

  if (CondFlag[exclusive] || CondFlag[republican])
  {
    Goal const mate_goal = { goal_mate, initsquare };
    slice_index const mate_tester = alloc_goal_mate_reached_tester_system();
    result = alloc_goal_reached_tester_slice(mate_goal,mate_tester);
    dealloc_slice(SLICE_NEXT1(result));
    solving_impose_starter(result,side);
  }
  else
    result = alloc_proxy_slice();

  return result;
}
Ejemplo n.º 2
0
static void instrument_generating(slice_index si, stip_structure_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  stip_traverse_structure_children_pipe(si,st);

  {
    insertion_configuration const * config = st->param;
    if (config->side==nr_sides || config->side==SLICE_STARTER(si))
    {
      slice_index const prototype = alloc_pipe(config->type);
      move_generation_branch_insert_slices_impl(si,&prototype,1,si);
      dealloc_slice(prototype);
    }
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 3
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();
}
Ejemplo n.º 4
0
/* Parse a stipulation expression
 * @param tok input token
 * @param start index of entry into solving machinery
 * @param proxy index of expression slice; no_slice if expression
 *              can't be parsed
 * @param level nesting level of the operand (0 means top level)
 * @return remainder of input token; 0 if parsing failed
 */
static char *ParseStructuredStip_expression(char *tok,
                                            slice_index start,
                                            slice_index proxy,
                                            expression_type *type,
                                            unsigned int level)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%s",tok);
  TraceFunctionParam("%u",start);
  TraceFunctionParam("%u",proxy);
  TraceFunctionParam("%u",level);
  TraceFunctionParamListEnd();

  {
    slice_index const operand1 = alloc_proxy_slice();
    tok = ParseStructuredStip_operand(tok,start,operand1,type,level);
    if (tok!=0 && SLICE_NEXT1(operand1)!=no_slice)
    {
      slice_type operator_type;
      tok = ParseStructuredStip_operator(tok,&operator_type);
      if (tok!=0 && operator_type!=no_slice_type)
      {
        if (*type==expression_type_defense)
          tok = 0;
        else
        {
          slice_index const operand2 = alloc_proxy_slice();
          expression_type type2;
          tok = ParseStructuredStip_expression(tok,start,operand2,&type2,level);
          if (tok!=0 && SLICE_NEXT1(operand2)!=no_slice)
          {
            if (*type==type2)
              switch (operator_type)
              {
                case STAnd:
                {
                  slice_index const and = alloc_and_slice(operand1,operand2);
                  pipe_link(proxy,and);
                  break;
                }

                case STOr:
                {
                  slice_index const or = alloc_or_slice(operand1,operand2);
                  pipe_link(proxy,or);
                  break;
                }

                default:
                  assert(0);
                  break;
              }
            else
              tok = 0;
          }
        }
      }
      else
      {
        if (SLICE_PREV(SLICE_NEXT1(operand1))==operand1)
          pipe_link(proxy,SLICE_NEXT1(operand1));
        else
          pipe_set_successor(proxy,SLICE_NEXT1(operand1));

        dealloc_slice(operand1);
      }
    }
  }

  TraceFunctionExit(__func__);
  TraceFunctionResult("%s",tok);
  TraceFunctionResultEnd();
  return tok;
}
Ejemplo n.º 5
0
static char *ParsePlay(char *tok,
                       slice_index start,
                       slice_index proxy,
                       play_length_type play_length)
{
    /* seriesmovers with introductory moves */
    char *result = 0;
    char *arrowpos;
    slice_index const proxy_next = alloc_proxy_slice();

    TraceFunctionEntry(__func__);
    TraceFunctionParam("%s",tok);
    TraceFunctionParam("%u",start);
    TraceFunctionParam("%u",proxy);
    TraceFunctionParamListEnd();

    if (token_starts_with("exact-",tok))
    {
        play_length = play_length_exact;
        tok += 6;
    }

    arrowpos = strstr(tok,"->");
    if (arrowpos!=0)
    {
        char *end;
        unsigned long const intro_len= strtoul(tok,&end,10);
        if (intro_len<1 || tok==end || end!=arrowpos)
            output_plaintext_input_error_message(WrongInt, 0);
        else
        {
            result = ParsePlay(arrowpos+2,start,proxy_next,play_length);
            if (result!=0 && SLICE_NEXT1(proxy_next)!=no_slice)
            {
                /* >=1 move of starting side required */
                slice_index const branch = alloc_series_branch(2*intro_len-1,1);
                help_branch_set_end(branch,proxy_next,1);
                link_to_branch(proxy,branch);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("ser-reci-h",tok))
    {
        /* skip over "ser-reci-h" */
        tok = ParseReciEnd(tok+10,start,proxy_next);
        if (tok!=0 && SLICE_NEXT1(proxy_next)!=no_slice)
        {
            stip_length_type length;
            stip_length_type min_length;
            result = ParseSeriesLength(tok,&length,&min_length,play_length);
            if (result!=0)
            {
                slice_index const branch = alloc_series_branch(length-1,min_length+1);
                help_branch_set_end(branch,proxy_next,1);
                link_to_branch(proxy,branch);

                solving_impose_starter(proxy_next,Black);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("ser-hs",tok))
    {
        tok = ParseGoal(tok+6,start,proxy_next); /* skip over "ser-hs" */
        if (tok!=0)
        {
            stip_length_type length;
            stip_length_type min_length;
            result = ParseSeriesLength(tok,&length,&min_length,play_length);
            if (result!=0)
            {
                slice_index const defense_branch = MakeEndOfSelfPlay(proxy_next);

                /* in ser-hs, the series is 1 half-move longer than in usual
                 * series play! */
                if (length==0)
                    pipe_link(proxy,defense_branch);
                else
                {
                    slice_index const series = alloc_series_branch(length,min_length);

                    slice_index const help_proxy = alloc_proxy_slice();
                    slice_index const help = alloc_help_branch(1,1);
                    link_to_branch(help_proxy,help);
                    help_branch_set_end_forced(help_proxy,defense_branch,1);
                    help_branch_set_end(series,help_proxy,1);
                    link_to_branch(proxy,series);
                }

                solving_impose_starter(proxy_next,White);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("ser-h",tok))
    {
        result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-h" */
        if (result!=0)
        {
            slice_index const help = alloc_help_branch(1,1);
            help_branch_set_end_goal(help,proxy_next,1);
            help_branch_set_end(proxy,help,1);

            {
                slice_index const next = SLICE_NEXT1(proxy_next);
                assert(next!=no_slice);
                if (SLICE_TYPE(next)==STGoalReachedTester
                        && SLICE_U(next).goal_handler.goal.type==goal_proofgame)
                    solving_impose_starter(proxy_next,White);
                else
                    solving_impose_starter(proxy_next,Black);
            }
        }
    }

    else if (token_starts_with("ser-s",tok))
    {
        result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-s" */
        if (result!=0)
        {
            help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("ser-r",tok))
    {
        result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-r" */
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            help_branch_set_end_forced(proxy,proxy_semi,1);
            series_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi));
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("ser-",tok))
    {
        result = ParseSeries(tok+4,start,proxy,proxy_next,play_length); /* skip over "ser-" */
        if (result!=0)
        {
            help_branch_set_end_goal(proxy,proxy_next,1);
            solving_impose_starter(proxy_next,Black);
        }
    }

    else if (token_starts_with("phser-r",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+7, /* skip over phser-r */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            help_branch_set_end_forced(proxy,proxy_semi,1);
            if (help_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi),0))
            {
                help_branch_insert_check_zigzag(proxy);
                solving_impose_starter(proxy_next,White);
            }
            else
                result = 0;
        }
    }

    else if (token_starts_with("phser-s",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+7, /* skip over phser-s */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1);
            help_branch_insert_check_zigzag(proxy);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("phser-",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+6, /* skip over phser- */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            help_branch_set_end_goal(proxy,proxy_next,1);
            help_branch_insert_check_zigzag(proxy);
            solving_impose_starter(proxy_next,Black);
        }
    }

    else if (token_starts_with("pser-hs",tok))
    {
        tok = ParseGoal(tok+7,start,proxy_next); /* skip over "ser-hs" */
        if (tok!=0)
        {
            stip_length_type length;
            stip_length_type min_length;
            result = ParseSeriesLength(tok,&length,&min_length,play_length);
            if (result!=0)
            {
                slice_index const series = alloc_help_branch(length,min_length);
                slice_index const help_proxy = alloc_proxy_slice();
                slice_index const help = alloc_help_branch(1,1);
                slice_index const defense_branch = MakeEndOfSelfPlay(proxy_next);
                link_to_branch(help_proxy,help);
                help_branch_set_end_forced(help_proxy,defense_branch,1);
                help_branch_set_end(series,help_proxy,1);
                link_to_branch(proxy,series);
                help_branch_insert_check_zigzag(proxy);
                solving_impose_starter(proxy_next,White);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("pser-h",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+6, /* skip over pser-h */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            slice_index const to_goal = SLICE_NEXT1(proxy_next);
            slice_index const nested = alloc_help_branch(1,1);
            help_branch_set_end_goal(nested,proxy_next,1);
            help_branch_set_end(proxy,nested,1);
            help_branch_insert_check_zigzag(proxy);
            if (SLICE_TYPE(to_goal)==STGoalReachedTester
                    && SLICE_U(to_goal).goal_handler.goal.type==goal_proofgame)
                solving_impose_starter(proxy_next,White);
            else
                solving_impose_starter(proxy_next,Black);
        }
    }

    else if (token_starts_with("pser-r",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+6, /* skip over pser-r */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            battle_branch_insert_end_of_branch_forced(proxy,proxy_semi);
            battle_branch_insert_attack_constraint(proxy,MakeReflexBranch(proxy_semi));
            battle_branch_insert_defense_check_zigzag(proxy);
            select_output_mode(proxy,output_mode_line);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("pser-s",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+6, /* skip over pser-s */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            battle_branch_insert_direct_end_of_branch(proxy,
                    MakeEndOfSelfPlay(proxy_next));
            solving_impose_starter(proxy_next,Black);
            select_output_mode(proxy,output_mode_line);
            battle_branch_insert_defense_check_zigzag(proxy);
        }
    }

    else if (token_starts_with("pser-",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+5, /* skip over pser- */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            select_output_mode(proxy,output_mode_line);
            battle_branch_insert_direct_end_of_branch_goal(proxy,proxy_next);
            battle_branch_insert_defense_check_zigzag(proxy);
        }
    }

    else if (token_starts_with("reci-h",tok))
    {
        char * const tok2 = ParseReciEnd(tok+6, /* skip over "reci-h" */
                                         start,proxy_next);
        if (tok2!=0 && SLICE_NEXT1(proxy_next)!=no_slice)
        {
            stip_length_type length;
            stip_length_type min_length;
            result = ParseHelpLength(tok2,&length,&min_length,play_length);

            if (length==1)
            {
                /* at least 2 half moves requried for a reciprocal stipulation */
                output_plaintext_input_error_message(StipNotSupported,0);
                result = 0;
            }

            if (result!=0)
            {
                if (length==2)
                {
                    pipe_link(proxy,SLICE_NEXT1(proxy_next));
                    dealloc_slice(proxy_next);
                }
                else
                {
                    stip_length_type const min_length2 = (min_length<2
                                                          ? min_length
                                                          : min_length-2);
                    slice_index const branch = alloc_help_branch(length-2,min_length2);
                    help_branch_set_end(branch,proxy_next,1);
                    attach_help_branch(length,proxy,branch);
                }

                solving_impose_starter(proxy_next,Black);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("dia",tok))
    {
        result = ParseHelpDia(tok,start,proxy,proxy_next,play_length);
        if (result!=0)
            solving_impose_starter(proxy,White);
    }
    else if (token_starts_with("a=>b",tok))
    {
        result = ParseHelpDia(tok,start,proxy,proxy_next,play_length);
        if (result!=0)
            solving_impose_starter(proxy,Black);
    }

    else if (token_starts_with("hs",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+2, /* skip over "hs" */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("hr",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+2, /* skip over "hr" */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            help_branch_set_end_forced(proxy,proxy_semi,1);
            if (help_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi),0))
                solving_impose_starter(proxy_next,White);
            else
                result = 0;
        }
    }

    else if (token_starts_with("h",tok))
    {
        boolean const shorten = false;
        result = ParseHelp(tok+1, /* skip over "h" */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            help_branch_set_end_goal(proxy,proxy_next,1);
            solving_impose_starter(proxy_next,Black);
        }
    }

    else if (token_starts_with("semi-r",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+6, /* skip over "semi-r" */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            battle_branch_insert_end_of_branch_forced(proxy,
                    MakeSemireflexBranch(proxy_next));
            select_output_mode(proxy,output_mode_tree);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("s",tok))
    {
        boolean const ends_on_defense = true;
        result = ParseBattle(tok+1, /* skip over 's' */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            select_output_mode(proxy,output_mode_tree);
            battle_branch_insert_self_end_of_branch_goal(proxy,proxy_next);
        }
    }

    else if (token_starts_with("r",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+1, /* skip over 'r' */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            battle_branch_insert_end_of_branch_forced(proxy,proxy_semi);
            battle_branch_insert_attack_constraint(proxy,MakeReflexBranch(proxy_semi));
            select_output_mode(proxy,output_mode_tree);
            solving_impose_starter(proxy_next,White);
        }
    }

    else
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok,start,proxy,proxy_next,play_length,ends_on_defense);
        if (result!=0)
        {
            select_output_mode(proxy,output_mode_tree);
            battle_branch_insert_direct_end_of_branch_goal(proxy,proxy_next);
        }
    }

    if (result==0)
        dealloc_slices(proxy_next);

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