/* * move.c - move and move stacks routines for Freecell Solver * * Written by Shlomi Fish (shlomif@vipe.technion.ac.il), 2000 * * This file is in the public domain (it's uncopyrighted). */ #include #include #include #include "move.h" #include "state.h" #ifdef DMALLOC #include "dmalloc.h" #endif #include "inline.h" #if 0 /* This variable was used for debugging. */ int msc_counter=0; #endif #if 0 /* This function allocates an empty move stack */ fcs_move_stack_t * fcs_move_stack_create(void) { fcs_move_stack_t * ret; /* Allocate the data structure itself */ ret = (fcs_move_stack_t *)malloc(sizeof(fcs_move_stack_t)); ret->max_num_moves = FCS_MOVE_STACK_GROW_BY; ret->num_moves = 0; /* Allocate some space for the moves */ ret->moves = (fcs_move_t *)malloc(sizeof(fcs_move_t)*ret->max_num_moves); return ret; } #endif #if 0 int fcs_move_stack_push(fcs_move_stack_t * stack, fcs_move_t move) { /* If all the moves inside the stack are taken then resize the move vector */ if (stack->num_moves == stack->max_num_moves) { int a, b; a = (stack->max_num_moves >> 3); b = FCS_MOVE_STACK_GROW_BY; stack->max_num_moves += max(a,b); stack->moves = realloc( stack->moves, stack->max_num_moves * sizeof(fcs_move_t) ); } stack->moves[stack->num_moves++] = move; return 0; } #endif int freecell_solver_move_stack_pop(fcs_move_stack_t * stack, fcs_move_t * move) { if (stack->num_moves > 0) { *move = stack->moves[--stack->num_moves]; return 0; } else { return 1; } } #if 0 void fcs_move_stack_destroy(fcs_move_stack_t * stack) { free(stack->moves); free(stack); } #endif void freecell_solver_move_stack_swallow_stack( fcs_move_stack_t * stack, fcs_move_stack_t * src_stack ) { fcs_move_t move; while (!fcs_move_stack_pop(src_stack, &move)) { fcs_move_stack_push(stack, move); } fcs_move_stack_destroy(src_stack); } #if 0 void fcs_move_stack_reset( fcs_move_stack_t * stack ) { stack->num_moves = 0; } #endif int freecell_solver_move_stack_get_num_moves( fcs_move_stack_t * stack ) { return stack->num_moves; } #if 0 /* This function duplicates a move stack */ fcs_move_stack_t * fcs_move_stack_duplicate( fcs_move_stack_t * stack ) { fcs_move_stack_t * ret; ret = (fcs_move_stack_t *)malloc(sizeof(fcs_move_stack_t)); ret->max_num_moves = stack->max_num_moves; ret->num_moves = stack->num_moves; ret->moves = (fcs_move_t *)malloc(sizeof(fcs_move_t) * ret->max_num_moves); memcpy(ret->moves, stack->moves, sizeof(fcs_move_t) * ret->max_num_moves); return ret; } #endif #if 0 extern void fcs_derived_states_list_add_state( fcs_derived_states_list_t * list, fcs_state_with_locations_t * state, fcs_move_stack_t * move_stack ) { if (list->num_states == list->max_num_states) { list->max_num_states += 16; list->states = realloc(list->states, sizeof(list->states[0]) * list->max_num_states); list->move_stacks = realloc(list->move_stacks, sizeof(list->move_stacks[0]) * list->max_num_states); } list->states[list->num_states] = state; list->move_stacks[list->num_states] = move_stack; list->num_states++; } #endif /* This function performs a given move on a state */ void freecell_solver_apply_move(fcs_state_with_locations_t * state_with_locations, fcs_move_t move, int freecells_num, int stacks_num, int decks_num) { fcs_state_t * state; fcs_card_t temp_card; int a; int src_stack, dest_stack; int src_freecell, dest_freecell; int src_stack_len; state = (&(state_with_locations->s)); dest_stack = fcs_move_get_dest_stack(move); src_stack = fcs_move_get_src_stack(move); dest_freecell = fcs_move_get_dest_freecell(move); src_freecell = fcs_move_get_src_freecell(move); switch(fcs_move_get_type(move)) { case FCS_MOVE_TYPE_STACK_TO_STACK: { src_stack_len = fcs_stack_len(*state, src_stack); for(a=0 ; a= 7) return (fcn+3); else return fcn; } char * freecell_solver_move_to_string(fcs_move_t move, int standard_notation) { return freecell_solver_move_to_string_w_state( NULL, 4, 8, 1, move, (standard_notation == 2)?1:standard_notation ); } char * freecell_solver_move_to_string_w_state(fcs_state_with_locations_t * state, int freecells_num, int stacks_num, int decks_num, fcs_move_t move, int standard_notation) { char string[256]; switch(fcs_move_get_type(move)) { case FCS_MOVE_TYPE_STACK_TO_STACK: if ((standard_notation == 2) && /* More than one card was moved */ (fcs_move_get_num_cards_in_seq(move) > 1) && /* It was a move to an empty stack */ (fcs_stack_len(state->s, fcs_move_get_dest_stack(move)) == fcs_move_get_num_cards_in_seq(move)) ) { sprintf(string, "%i%iv%x", 1+fcs_move_get_src_stack(move), 1+fcs_move_get_dest_stack(move), fcs_move_get_num_cards_in_seq(move) ); } else if (standard_notation) { sprintf(string, "%i%i", 1+fcs_move_get_src_stack(move), 1+fcs_move_get_dest_stack(move) ); } else { sprintf(string, "Move %i cards from stack %i to stack %i", fcs_move_get_num_cards_in_seq(move), fcs_move_get_src_stack(move), fcs_move_get_dest_stack(move) ); } break; case FCS_MOVE_TYPE_FREECELL_TO_STACK: if (standard_notation) { sprintf(string, "%c%i", ('a'+convert_freecell_num(fcs_move_get_src_freecell(move))), 1+fcs_move_get_dest_stack(move) ); } else { sprintf(string, "Move a card from freecell %i to stack %i", fcs_move_get_src_freecell(move), fcs_move_get_dest_stack(move) ); } break; case FCS_MOVE_TYPE_FREECELL_TO_FREECELL: if (standard_notation) { sprintf(string, "%c%c", ('a'+convert_freecell_num(fcs_move_get_src_freecell(move))), ('a'+convert_freecell_num(fcs_move_get_dest_freecell(move))) ); } else { sprintf(string, "Move a card from freecell %i to freecell %i", fcs_move_get_src_freecell(move), fcs_move_get_dest_freecell(move) ); } break; case FCS_MOVE_TYPE_STACK_TO_FREECELL: if (standard_notation) { sprintf(string, "%i%c", 1+fcs_move_get_src_stack(move), ('a'+convert_freecell_num(fcs_move_get_dest_freecell(move))) ); } else { sprintf(string, "Move a card from stack %i to freecell %i", fcs_move_get_src_stack(move), fcs_move_get_dest_freecell(move) ); } break; case FCS_MOVE_TYPE_STACK_TO_FOUNDATION: if (standard_notation) { sprintf(string, "%ih", 1+fcs_move_get_src_stack(move)); } else { sprintf(string, "Move a card from stack %i to the foundations", fcs_move_get_src_stack(move) ); } break; case FCS_MOVE_TYPE_FREECELL_TO_FOUNDATION: if (standard_notation) { sprintf(string, "%ch", ('a'+convert_freecell_num(fcs_move_get_src_freecell(move)))); } else { sprintf(string, "Move a card from freecell %i to the foundations", fcs_move_get_src_freecell(move) ); } break; case FCS_MOVE_TYPE_SEQ_TO_FOUNDATION: if (standard_notation) { sprintf(string, "%ih", fcs_move_get_src_stack(move)); } else { sprintf(string, "Move the sequence on top of Stack %i to the foundations", fcs_move_get_src_stack(move) ); } break; default: string[0] = '\0'; break; } return strdup(string); }