char * freecell_solver_state_as_string( fcs_state_with_locations_t * state_with_locations, int freecells_num, int stacks_num, int decks_num, int parseable_output, int canonized_order_output, int display_10_as_t ) { fcs_state_t * state; char freecell[10], decks[MAX_NUM_DECKS*4][10], stack_card_[10]; int a, card_num_is_null, b; int max_num_cards, s, card_num, len; char str2[128], str3[128], * str2_ptr, * str3_ptr; freecell_solver_append_string_t * app_str; int stack_locs[MAX_NUM_STACKS]; int freecell_locs[MAX_NUM_FREECELLS]; state = (&(state_with_locations->s)); if (canonized_order_output) { for(a=0;a<stacks_num;a++) { stack_locs[a] = a; } for(a=0;a<freecells_num;a++) { freecell_locs[a] = a; } } else { for(a=0;a<stacks_num;a++) { stack_locs[(int)(state_with_locations->stack_locs[a])] = a; } for(a=0;a<freecells_num;a++) { freecell_locs[(int)(state_with_locations->fc_locs[a])] = a; } } for(a=0;a<decks_num*4;a++) { fcs_p2u_card_number( fcs_foundation_value(*state, a), decks[a], &card_num_is_null, display_10_as_t, 0 ); if (decks[a][0] == ' ') decks[a][0] = '0'; } app_str = freecell_solver_append_string_alloc(512); if(!parseable_output) { for(a=0;a<((freecells_num/4)+((freecells_num%4==0)?0:1));a++) { str2_ptr = str2; str3_ptr = str3; for(b=0;b<min(freecells_num-a*4, 4);b++) { str2_ptr += sprintf(str2_ptr, "%3s ", fcs_card_perl2user( fcs_freecell_card( *state, freecell_locs[a*4+b] ), freecell, display_10_as_t ) ); str3_ptr += sprintf(str3_ptr, "--- "); } if (a < decks_num) { freecell_solver_append_string_sprintf( app_str, "%-16s H-%1s C-%1s D-%1s S-%1s\n", str2, decks[a*4], decks[a*4+1], decks[a*4+2], decks[a*4+3] ); } else { freecell_solver_append_string_sprintf( app_str, "%s\n", str2 ); } freecell_solver_append_string_sprintf( app_str, "%s\n", str3 ); } for(;a<decks_num;a++) { freecell_solver_append_string_sprintf( app_str, "%-16s H-%1s C-%1s D-%1s S-%1s\n", "", decks[a*4], decks[a*4+1], decks[a*4+2], decks[a*4+3] ); } freecell_solver_append_string_sprintf( app_str, "%s", "\n\n" ); for(s=0;s<stacks_num;s++) { freecell_solver_append_string_sprintf(app_str, "%s", " -- "); } freecell_solver_append_string_sprintf( app_str, "%s", "\n" ); max_num_cards = 0; for(s=0;s<stacks_num;s++) { if (fcs_stack_len(*state, stack_locs[s]) > max_num_cards) { max_num_cards = fcs_stack_len(*state, stack_locs[s]); } } for(card_num=0;card_num<max_num_cards;card_num++) { for(s = 0; s<stacks_num; s++) { if (card_num >= fcs_stack_len(*state, stack_locs[s])) { freecell_solver_append_string_sprintf( app_str, " " ); } else { freecell_solver_append_string_sprintf( app_str, "%3s ", fcs_card_perl2user( fcs_stack_card( *state, stack_locs[s], card_num), stack_card_, display_10_as_t ) ); } } freecell_solver_append_string_sprintf(app_str, "%s", "\n"); } } else { freecell_solver_append_string_sprintf(app_str, "%s", "Foundations: "); for(a=0;a<decks_num;a++) { freecell_solver_append_string_sprintf( app_str, "H-%s C-%s D-%s S-%s ", decks[a*4], decks[a*4+1], decks[a*4+2], decks[a*4+3] ); } freecell_solver_append_string_sprintf(app_str, "%s", "\nFreecells: "); for(a=0;a<freecells_num;a++) { freecell_solver_append_string_sprintf( app_str, "%3s", fcs_card_perl2user( fcs_freecell_card( *state, freecell_locs[a] ), freecell, display_10_as_t ) ); if (a < freecells_num-1) { freecell_solver_append_string_sprintf(app_str, "%s", " "); } } freecell_solver_append_string_sprintf(app_str, "%s", "\n"); for(s=0;s<stacks_num;s++) { freecell_solver_append_string_sprintf(app_str, "%s", ": "); len = fcs_stack_len(*state, stack_locs[s]); for(card_num=0;card_num<len;card_num++) { fcs_card_perl2user( fcs_stack_card( *state, stack_locs[s], card_num ), stack_card_, display_10_as_t ); freecell_solver_append_string_sprintf(app_str, "%s", stack_card_); if (card_num < len-1) { freecell_solver_append_string_sprintf(app_str, "%s", " "); } } freecell_solver_append_string_sprintf(app_str, "%s", "\n"); } } return freecell_solver_append_string_finalize(app_str); }
/* * 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; } }
/* * 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 }