Ejemplo n.º 1
0
static char *ParseReciGoal(char *tok,
                           slice_index start,
                           slice_index proxy_nonreci,
                           slice_index proxy_reci)
{
    char *result = 0;

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

    if (*tok=='(')
    {
        char const *closingParenPos = strchr(tok,')');
        if (closingParenPos!=0)
        {
            slice_index const proxy_to_reci = alloc_proxy_slice();
            tok = ParseGoal(tok+1,start,proxy_to_reci);
            if (tok!=0)
            {
                if (tok==closingParenPos)
                {
                    slice_index const proxy_to_nonreci = alloc_proxy_slice();
                    result = ParseGoal(tok+1,start,proxy_to_nonreci);
                    if (result!=NULL)
                    {
                        slice_index const nonreci = SLICE_NEXT1(proxy_to_nonreci);
                        SLICE_STARTER(nonreci) = Black;
                        alloc_reci_end(proxy_nonreci,proxy_reci,
                                       proxy_to_nonreci,proxy_to_reci);
                    }
                }
                else
                    output_plaintext_input_error_message(UnrecStip, 0);
            }
        }
        else
            output_plaintext_input_error_message(UnrecStip, 0);
    }
    else
    {
        slice_index const proxy_to_nonreci = alloc_proxy_slice();
        result = ParseGoal(tok,start,proxy_to_nonreci);
        if (result!=NULL)
        {
            slice_index const nonreci_testing = SLICE_NEXT1(proxy_to_nonreci);
            slice_index const nonreci_tester = SLICE_NEXT1(nonreci_testing);
            slice_index const proxy_to_reci = stip_deep_copy(proxy_to_nonreci);
            alloc_reci_end(proxy_nonreci,proxy_reci,
                           proxy_to_nonreci,proxy_to_reci);
            SLICE_STARTER(nonreci_tester) = Black;
        }
    }

    TraceFunctionExit(__func__);
    TraceFunctionResult("%s",result);
    TraceFunctionResultEnd();
    return result;
}
Ejemplo n.º 2
0
char *ParsePieceWalk(char *tok, piece_walk_type *walk)
{
  size_t len_token;
  char const * const hunterseppos = strchr(tok,'/');
  if (hunterseppos!=0 && hunterseppos-tok<=2)
  {
    piece_walk_type away;
    piece_walk_type home;
    tok = ParseWalkShortcut((hunterseppos-tok)%2==1,tok,&away);
    ++tok; /* skip separator */
    len_token = strlen(tok);
    tok = ParseWalkShortcut(len_token%2==1,tok,&home);
    *walk = hunter_find_type(away,home);
    if (*walk==Invalid)
    {
      *walk = hunter_make_type(away,home);
      if (*walk==Invalid)
        output_plaintext_input_error_message(HunterTypeLimitReached,max_nr_hunter_walks);
    }
  }
  else
  {
    len_token = strlen(tok);
    tok = ParseWalkShortcut(len_token%2==1,tok,walk);
  }

  return tok;
}
Ejemplo n.º 3
0
static char *ParseSeriesLength(char *tok,
                               stip_length_type *length,
                               stip_length_type *min_length,
                               play_length_type play_length)
{
    TraceFunctionEntry(__func__);
    TraceFunctionParam("%s",tok);
    TraceFunctionParamListEnd();

    tok = ParseLength(tok,length);
    if (tok!=0)
    {
        if (*length==0)
        {
            output_plaintext_input_error_message(WrongInt,0);
            tok = 0;
        }
        else
        {
            /* we count half moves in series play */
            *length *= 2;
            *length -= 1;
            if (play_length==play_length_minimum)
                *min_length = 1;
            else
                *min_length = *length;
        }
    }

    TraceFunctionExit(__func__);
    TraceFunctionResult("%s",tok);
    TraceFunctionResultEnd();
    return tok;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
Flags ParseColour(char *tok, boolean colour_is_mandatory)
{
    Colour const colour = GetUniqIndex(nr_colours,ColourTab,tok);
    if (colour==nr_colours)
    {
        if (colour_is_mandatory)
            output_plaintext_input_error_message(NoColourSpec,0);
        return 0;
    }
    else if (colour>nr_colours)
    {
        output_plaintext_input_error_message(PieSpecNotUniq,0);
        return 0;
    }
    else if (colour==colour_neutral)
        return NeutralMask;
    else
        return BIT(colour);
}
Ejemplo n.º 6
0
char *ReadNextTokStr(void)
{
  while (strchr(SpaceChar,LastChar))
    NextChar();

  if (strchr(TokenChar,LastChar))
  {
    char *p = InputLine;
    char *t = TokenLine;

    do {
      *p++ = LastChar;
      *t++ = LastChar;
      /* *t++= (isupper(ch)?tolower(ch):ch);  */
      /* EBCDIC support ! HD */
      NextChar();
    } while (strchr(TokenChar,LastChar));

    if (p >= (InputLine+sizeof(InputLine)))
      output_plaintext_fatal_message(InpLineOverflow);

    *t = '\0';
    *p = '\0';

    return TokenLine;
  }
  else if (strchr(SepraChar,LastChar))
  {
    do
    {
      NextChar();
    } while (strchr(SepraChar,LastChar));
    return Sep;
  }
  else
  {
    output_plaintext_input_error_message(WrongChar,LastChar);
    LastChar = TokenLine[0]= ' ';
    TokenLine[1] = '\0';
    return TokenLine;
  }
}
Ejemplo n.º 7
0
void input_plaintext_detect_user_language(slice_index si)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParamListEnd();

  UserLanguage = detect_user_language(ReadNextTokStr());

  if (UserLanguage==LanguageCount)
    output_plaintext_input_error_message(NoBegOfProblem, 0);
  else
  {
    output_plaintext_select_language(UserLanguage);
    output_message_initialise_language(UserLanguage);

    pipe_solve_delegate(si);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 8
0
char *ParsePieceFlags(Flags *flags)
{
    char *tok;

    while (true)
    {
        tok = ReadNextTokStr();

        {
            piece_flag_type const ps = GetUniqIndex(nr_piece_flags-nr_sides,PieSpTab,tok);
            if (ps==nr_piece_flags-nr_sides)
                break;
            else if (ps>nr_piece_flags-nr_sides)
                output_plaintext_input_error_message(PieSpecNotUniq,0);
            else
                SETFLAG(*flags,ps+nr_sides);
        }
    }

    return tok;
}
Ejemplo n.º 9
0
/* Parse starter of stipulation
 * @param tok input token
 * @return starter; no_side if starter couldn't be parsed
 */
static Side ParseStructuredStip_starter(char *tok)
{
  Side result = no_side;
  Side ps;

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

  /* We don't make any unsafe assumptions here; PieSpec enumerators
   * are initialised in terms of nr_sides */
  ps = GetUniqIndex(nr_sides,ColourTab,tok);
  if (ps>nr_sides)
    output_plaintext_input_error_message(PieSpecNotUniq,0);
  else if (ps<nr_sides)
    result = ps;

  TraceFunctionExit(__func__);
  TraceEnumerator(Side,result,"");
  TraceFunctionResultEnd();
  return result;
}
Ejemplo n.º 10
0
/* Instrument the input machinery with a proof games type
 * @param start start slice of input machinery
 */
void input_instrument_proof(slice_index start)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",start);
  TraceFunctionParamListEnd();

  if (input_is_instrumented_with_proof(start))
    output_plaintext_input_error_message(InconsistentProofTarget,0);
  else
  {
    slice_index const prototypes[] = {
        alloc_pipe(STProofSolver),
        alloc_pipe(STPiecesCounter),
        alloc_pipe(STRoyalsLocator),
        alloc_pipe(STPiecesFlagsInitialiser)
    };
    enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] };
    slice_insertion_insert(start,prototypes,nr_prototypes);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 11
0
void input_plaintext_iterate_problems(slice_index si)
{
  boolean halt = false;

  do
  {
    pipe_solve_delegate(si);

    switch (GetUniqIndex(ProblemTokenCount,ProblemTokenTab,TokenLine))
    {
      case ProblemTokenCount:
      case EndProblem:
        halt = true;
        break;

      case NextProblem:
        break;

      default:
        output_plaintext_input_error_message(ComNotUniq,0);
        break;
    }
  } while (!halt);
}
Ejemplo n.º 12
0
static char *ParsePieceWalkAndSquares(char *tok, Flags Spec, piece_addition_type type)
{
    unsigned int nr_walks_parsed = 0;

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

    while (true)
    {
        piece_walk_type walk;
        char * const save_tok = tok;

        tok = ParsePieceWalk(tok,&walk);

        if (walk>=King)
        {
            piece_addition_settings settings = { walk, Spec, type};

            ++nr_walks_parsed;

            if (tok[0]==0)
            {
                /* the next token must be a valid square list, e.g. B a1b2
                 */
                char * const squares_tok = ReadNextTokStr();
                tok = ParseSquareList(squares_tok,&HandleAddedPiece,&settings);
                if (tok==squares_tok)
                    output_plaintext_input_error_message(MissngSquareList,0);
                else if (*tok!=0)
                    output_plaintext_error_message(WrongSquareList);
            }
            else
            {
                /* the remainder of the token may be
                 * * a valid square list, e.g. Ba1b2
                 * * the remainder of a different word e.g. Black
                 */
                if (*ParseSquareList(tok,&HandleAddedPiece,&settings)!=0)
                {
                    tok = save_tok;
                    break;
                }
            }

            tok = ReadNextTokStr();

            /* undocumented feature: "royal" only applies to the immediately next
             * piece indication because there can be at most 1 royal piece per side
             */
            CLRFLAG(Spec,Royal);
        }
        else
        {
            if (nr_walks_parsed==0)
            {
                output_plaintext_input_error_message(WrongPieceName,0);
                tok = ReadNextTokStr();
            }
            else
                tok = save_tok;

            break;
        }
    }

    TraceFunctionExit(__func__);
    TraceFunctionResult("%s",tok);
    TraceFunctionResultEnd();
    return tok;
}
Ejemplo n.º 13
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;
}