示例#1
0
fcs_state_with_locations_t freecell_solver_initial_user_state_to_c(
    const char * string,
    int freecells_num,
    int stacks_num,
    int decks_num
#ifdef FCS_WITH_TALONS
    ,int talon_type
#endif
#ifdef INDIRECT_STACK_STATES
    , char * indirect_stacks_buffer
#endif
    )
{
    fcs_state_with_locations_t ret_with_locations;

    int s,c;
    const char * str;
    fcs_card_t card;
    int first_line;

    int prefix_found;
    const char * const * prefixes;
    int i;
    int decks_index[4];

    fcs_state_init(
        &ret_with_locations, 
        stacks_num
#ifdef INDIRECT_STACK_STATES        
        , indirect_stacks_buffer  
#endif
        );
    str = string;

    first_line = 1;

#define ret (ret_with_locations.s)

#ifdef FCS_WITH_TALONS
    if (talon_type == FCS_TALON_KLONDIKE)
    {
        fcs_klondike_talon_num_redeals_left(ret) = -1;
    }
#endif

    for(s=0;s<stacks_num;s++)
    {
        /* Move to the next stack */
        if (!first_line)
        {
            while((*str) != '\n')
            {
                str++;
            }
            str++;
        }
        first_line = 0;

        prefixes = freecells_prefixes;
        prefix_found = 0;
        for(i=0;prefixes[i][0] != '\0'; i++)
        {
            if (!strncasecmp(str, prefixes[i], strlen(prefixes[i])))
            {
                prefix_found = 1;
                str += strlen(prefixes[i]);
                break;
            }
        }

        if (prefix_found)
        {
            for(c=0;c<freecells_num;c++)
            {
                fcs_empty_freecell(ret, c);
            }
            for(c=0;c<freecells_num;c++)
            {
                if (c!=0)
                {
                    while(
                            ((*str) != ' ') &&
                            ((*str) != '\t') &&
                            ((*str) != '\n') &&
                            ((*str) != '\r')
                         )
                    {
                        str++;
                    }
                    if ((*str == '\n') || (*str == '\r'))
                    {
                        break;
                    }
                    str++;
                }

                while ((*str == ' ') || (*str == '\t'))
                {
                    str++;
                }
                if ((*str == '\r') || (*str == '\n'))
                    break;

                if ((*str == '*') || (*str == '-'))
                {
                    card = fcs_empty_card;
                }
                else
                {
                    card = fcs_card_user2perl(str);
                }

                fcs_put_card_in_freecell(ret, c, card);
            }

            while ((*str != '\n') && (*str != '\0'))
            {
                str++;
            }
            s--;
            continue;
        }

        prefixes = foundations_prefixes;
        prefix_found = 0;
        for(i=0;prefixes[i][0] != '\0'; i++)
        {
            if (!strncasecmp(str, prefixes[i], strlen(prefixes[i])))
            {
                prefix_found = 1;
                str += strlen(prefixes[i]);
                break;
            }
        }

        if (prefix_found)
        {
            int d;

            for(d=0;d<decks_num*4;d++)
            {
                fcs_set_foundation(ret, d, 0);
            }

            for(d=0;d<4;d++)
            {
                decks_index[d] = 0;
            }
            while (1)
            {
                while((*str == ' ') || (*str == '\t'))
                    str++;
                if ((*str == '\n') || (*str == '\r'))
                    break;
                d = fcs_u2p_suit(str);
                str++;
                while (*str == '-')
                    str++;
                c = fcs_u2p_card_number(str);
                while (
                        (*str != ' ') &&
                        (*str != '\t') &&
                        (*str != '\n') &&
                        (*str != '\r')
                      )
                {
                    str++;
                }

                fcs_set_foundation(ret, (decks_index[d]*4+d), c);
                decks_index[d]++;
                if (decks_index[d] >= decks_num)
                {
                    decks_index[d] = 0;
                }
            }
            s--;
            continue;
        }

#ifdef FCS_WITH_TALONS
        prefixes = talon_prefixes;
        prefix_found = 0;
        for(i=0;prefixes[i][0] != '\0'; i++)
        {
            if (!strncasecmp(str, prefixes[i], strlen(prefixes[i])))
            {
                prefix_found = 1;
                str += strlen(prefixes[i]);
                break;
            }
        }

        if (prefix_found)
        {
            /* Input the Talon */
            int talon_size;

            talon_size = MAX_NUM_DECKS*52+16;
            ret.talon = malloc(sizeof(fcs_card_t)*talon_size);
            fcs_talon_pos(ret) = 0;

            for(c=0 ; c < talon_size ; c++)
            {
                /* Move to the next card */
                if (c!=0)
                {
                    while(
                        ((*str) != ' ') &&
                        ((*str) != '\t') &&
                        ((*str) != '\n') &&
                        ((*str) != '\r')
                    )
                    {
                        str++;
                    }
                    if ((*str == '\n') || (*str == '\r'))
                    {
                        break;
                    }
                }

                while ((*str == ' ') || (*str == '\t'))
                {
                    str++;
                }

                if ((*str == '\n') || (*str == '\r'))
                {
                    break;
                }

                card = fcs_card_user2perl(str);

                fcs_put_card_in_talon(ret, c+(talon_type==FCS_TALON_KLONDIKE), card);
            }
            fcs_talon_len(ret) = c;

            if (talon_type == FCS_TALON_KLONDIKE)
            {
                int talon_len;

                talon_len = fcs_talon_len(ret);
                fcs_klondike_talon_len(ret) = talon_len;
                fcs_klondike_talon_stack_pos(ret) = -1;
                fcs_klondike_talon_queue_pos(ret) = 0;
            }

            s--;
            continue;
        }

        prefixes = num_redeals_prefixes;
        prefix_found = 0;
        for(i=0;prefixes[i][0] != '\0'; i++)
        {
            if (!strncasecmp(str, prefixes[i], strlen(prefixes[i])))
            {
                prefix_found = 1;
                str += strlen(prefixes[i]);
                break;
            }
        }

        if (prefix_found)
        {
            while ((*str < '0') && (*str > '9') && (*str != '\n'))
            {
                str++;
            }
            if (*str != '\n')
            {
                int num_redeals;

                num_redeals = atoi(str);
                if (talon_type == FCS_TALON_KLONDIKE)
                {
                    fcs_klondike_talon_num_redeals_left(ret) =
                        (num_redeals < 0) ?
                            (-1) :
                            ((num_redeals > 127) ? 127 : num_redeals)
                                ;
                }
            }
            s--;
            continue;
        }
#endif

        for(c=0 ; c < MAX_NUM_CARDS_IN_A_STACK ; c++)
        {
            /* Move to the next card */
            if (c!=0)
            {
                while(
                    ((*str) != ' ') &&
                    ((*str) != '\t') &&
                    ((*str) != '\n') &&
                    ((*str) != '\r')
                )
                {
                    str++;
                }
                if ((*str == '\n') || (*str == '\r'))
                {
                    break;
                }
            }

            while ((*str == ' ') || (*str == '\t'))
            {
                str++;
            }
            if ((*str == '\n') || (*str == '\r'))
            {
                break;
            }
            card = fcs_card_user2perl(str);

            fcs_push_card_into_stack(ret, s, card);
        }
    }

    return ret_with_locations;
}
示例#2
0
/*
 * This function performs a given move on a state
 */
void fc_solve_apply_move(
        fcs_state_extra_info_t * state_val,
        fcs_internal_move_t move,
        int freecells_num,
        int stacks_num,
        int decks_num GCC_UNUSED
        )
{
    fcs_card_t card;
    fcs_cards_column_t col;

    fcs_state_t * state_key = state_val->key;

    switch(fcs_int_move_get_type(move))
    {
        case FCS_MOVE_TYPE_STACK_TO_STACK:
        {
            fcs_cards_column_t dest_col;
            int i;

            col = fcs_state_get_col(*state_key, fcs_int_move_get_src_stack(move));
            dest_col = fcs_state_get_col(*state_key, fcs_int_move_get_dest_stack(move));
            for(i=0 ; i<fcs_int_move_get_num_cards_in_seq(move) ; i++)
            {
                fcs_col_push_col_card(
                    dest_col,
                    col, 
                    fcs_col_len(col) - fcs_int_move_get_num_cards_in_seq(move)+i
                );
            }
            for(i=0 ; i<fcs_int_move_get_num_cards_in_seq(move) ; i++)
            {
                fcs_col_pop_top(col);
            }
        }
        break;
        case FCS_MOVE_TYPE_FREECELL_TO_STACK:
        {
            col = fcs_state_get_col(*state_key, fcs_int_move_get_dest_stack(move));
            fcs_col_push_card(col, fcs_freecell_card(*state_key, fcs_int_move_get_src_freecell(move)));
            fcs_empty_freecell(*state_key, fcs_int_move_get_src_freecell(move));
        }
        break;
        case FCS_MOVE_TYPE_FREECELL_TO_FREECELL:
        {
            card = fcs_freecell_card(*state_key, fcs_int_move_get_src_freecell(move));
            fcs_put_card_in_freecell(*state_key, fcs_int_move_get_dest_freecell(move), card);
            fcs_empty_freecell(*state_key, fcs_int_move_get_src_freecell(move));
        }
        break;

        case FCS_MOVE_TYPE_STACK_TO_FREECELL:
        {
            col = fcs_state_get_col(*state_key, fcs_int_move_get_src_stack(move));
            fcs_col_pop_card(col, card);
            fcs_put_card_in_freecell(*state_key, fcs_int_move_get_dest_freecell(move), card);
        }
        break;

        case FCS_MOVE_TYPE_STACK_TO_FOUNDATION:
        {
            col = fcs_state_get_col(
                *state_key, 
                fcs_int_move_get_src_stack(move)
                );
            fcs_col_pop_top(col);
            fcs_increment_foundation(*state_key, fcs_int_move_get_foundation(move));
        }
        break;

        case FCS_MOVE_TYPE_FREECELL_TO_FOUNDATION:
        {
            fcs_empty_freecell(*state_key, fcs_int_move_get_src_freecell(move));
            fcs_increment_foundation(*state_key, fcs_int_move_get_foundation(move));
        }
        break;

        case FCS_MOVE_TYPE_SEQ_TO_FOUNDATION:
        {
            int i;

            col = fcs_state_get_col(*state_key, fcs_int_move_get_src_stack(move));
            for (i=0 ; i<13 ; i++)
            {
                fcs_col_pop_top(col);
                fcs_increment_foundation(*state_key, fcs_int_move_get_foundation(move));
            }
        }
        break;

#ifndef FCS_WITHOUT_CARD_FLIPPING
        case FCS_MOVE_TYPE_FLIP_CARD:
        {
            col = fcs_state_get_col(*state_key, fcs_int_move_get_src_stack(move));
            fcs_col_flip_card(col, fcs_col_len(col)-1);
        }
        break;
#endif

        case FCS_MOVE_TYPE_CANONIZE:
        {
            fc_solve_canonize_state(
                state_val,
                freecells_num, stacks_num
            );
        }
        break;

    }
}
示例#3
0
文件: move.c 项目: shlomif/fc-solve
/*
 * This function performs a given move on a state
 */
void fc_solve_apply_move(fcs_state *const ptr_state_key,
    fcs_state_locs_struct *const locs,
    const fcs_internal_move move FREECELLS_AND_STACKS_ARGS())
{
    fcs_cards_column col;
    const stack_i src = fcs_int_move_get_src(move);
    const stack_i dest = fcs_int_move_get_dest(move);

#define state_key (ptr_state_key)
    switch (fcs_int_move_get_type(move))
    {
    case FCS_MOVE_TYPE_STACK_TO_STACK:
    {
        fcs_col_transfer_cards(fcs_state_get_col(*state_key, dest),
            fcs_state_get_col(*state_key, src),
            fcs_int_move_get_num_cards_in_seq(move));
    }
    break;
#if MAX_NUM_FREECELLS > 0
    case FCS_MOVE_TYPE_FREECELL_TO_STACK:
        fcs_state_push(state_key, dest, fcs_freecell_card(*state_key, src));
        fcs_empty_freecell(*state_key, src);
        break;
    case FCS_MOVE_TYPE_FREECELL_TO_FREECELL:
    {
        fcs_card card = fcs_freecell_card(*state_key, src);
        fcs_put_card_in_freecell(*state_key, dest, card);
        fcs_empty_freecell(*state_key, src);
    }
    break;

    case FCS_MOVE_TYPE_STACK_TO_FREECELL:
    {
        col = fcs_state_get_col(*state_key, src);
        fcs_card card;
        fcs_col_pop_card(col, card);
        fcs_put_card_in_freecell(*state_key, dest, card);
    }
    break;
#endif
    case FCS_MOVE_TYPE_STACK_TO_FOUNDATION:
        col = fcs_state_get_col(*state_key, src);
        fcs_col_pop_top(col);
        fcs_increment_foundation(*state_key, dest);
        break;

#if MAX_NUM_FREECELLS > 0
    case FCS_MOVE_TYPE_FREECELL_TO_FOUNDATION:
        fcs_empty_freecell(*state_key, src);
        fcs_increment_foundation(*state_key, dest);
        break;
#endif

#ifndef FCS_FREECELL_ONLY
    case FCS_MOVE_TYPE_SEQ_TO_FOUNDATION:
        col = fcs_state_get_col(*state_key, src);
        for (int i = 0; i < 13; i++)
        {
            fcs_col_pop_top(col);
            fcs_increment_foundation(*state_key, dest);
        }
        break;
#endif

    case FCS_MOVE_TYPE_CANONIZE:
        if (locs)
        {
            fc_solve_canonize_state_with_locs(state_key,
                locs PASS_FREECELLS(freecells_num) PASS_STACKS(stacks_num));
        }
        else
        {
            fc_solve_canonize_state(state_key PASS_FREECELLS(freecells_num)
                    PASS_STACKS(stacks_num));
        }
        break;
    }
#undef state_key
}