Hello Shlomi,
I'm sorry to say that I couldn't follow your routine. What I saw was numerous calls to external routines/def's for data structures that were unfamiliar. In particular, I didn't notice anything similar to the calculations/tests that I perform.
In my solver, I perform a move and pass the data structure to either my Horne() routine or my WKR() routine. They performs all automoves appropriate for the routine called, and then return the data structure. I then check to see if the deal/game is solved or if I need to perform another move.
Note: my WKR() routine is written as a super-set of the Horne() routine, so I don't need to make a separate call for those automoves.
I have a terrible memory anymore, but I seem to recall that my solver ran slightly faster with WKR() over Horne() because the former routine advanced the solution faster because I needed to perform fewer manual moves.
Regards, Danny
--- In fc-solve-discuss_at_yahoogroups.com, Shlomi Fish <shlomif_at_...> wrote:
>
<snip>
>
> [CODE]
>
> extern int fc_solve_sfs_raymond_prune(
> fc_solve_soft_thread_t * soft_thread,
> fcs_kv_state_t * raw_ptr_state_raw,
> fcs_collectible_state_t * * ptr_next_state_val
> )
> {
> tests_define_accessors();
> #ifndef HARD_CODED_NUM_STACKS
> SET_GAME_PARAMS();
> #endif
>
> fcs_derived_states_list_t derived_states_list_struct;
> derived_states_list_struct.states = NULL;
> derived_states_list_struct.num_states = 0;
>
> sfs_check_state_begin();
>
> int num_total_cards_moved = 0;
> int num_cards_moved = 0;
> do {
> num_cards_moved = 0;
> for ( int stack_idx=0 ; stack_idx < LOCAL_STACKS_NUM ; stack_idx++)
> {
> fcs_cards_column_t col = fcs_state_get_col(new_state, stack_idx);
> const int cards_num = fcs_col_len(col);
>
> if (cards_num)
> {
> /* Get the top card in the stack */
> const fcs_card_t card = fcs_col_get_card(col, cards_num-1);
>
> const int dest_foundation = CALC_FOUNDATION_TO_PUT_CARD_ON();
> if (dest_foundation >= 0)
> {
> /* We can safely move it. */
> num_cards_moved++;
>
> my_copy_stack(stack_idx);
> {
> fcs_cards_column_t new_temp_col;
> new_temp_col = fcs_state_get_col(new_state, stack_idx);
> fcs_col_pop_top(new_temp_col);
> }
>
> fcs_increment_foundation(new_state, dest_foundation);
>
> fcs_internal_move_t temp_move;
> fcs_int_move_set_type(temp_move,FCS_MOVE_TYPE_STACK_TO_FOUNDATION);
> fcs_int_move_set_src_stack(temp_move,stack_idx);
> fcs_int_move_set_foundation(temp_move,dest_foundation);
>
> fcs_move_stack_push(moves, temp_move);
>
> fcs_flip_top_card(stack_idx);
> }
> }
> }
>
> /* Now check the same for the free cells */
> for ( int fc=0 ; fc < LOCAL_FREECELLS_NUM ; fc++)
> {
> const fcs_card_t card = fcs_freecell_card(new_state, fc);
> if (fcs_card_is_valid(card))
> {
> const int dest_foundation = CALC_FOUNDATION_TO_PUT_CARD_ON();
> if (dest_foundation >= 0)
> {
> num_cards_moved++;
>
> /* We can put it there */
>
> fcs_empty_freecell(new_state, fc);
>
> fcs_internal_move_t temp_move;
> fcs_increment_foundation(new_state, dest_foundation);
>
> fcs_int_move_set_type(temp_move,FCS_MOVE_TYPE_FREECELL_TO_FOUNDATION);
> fcs_int_move_set_src_freecell(temp_move,fc);
> fcs_int_move_set_foundation(temp_move,dest_foundation);
>
> fcs_move_stack_push(moves, temp_move);
> }
> }
> }
> num_total_cards_moved += num_cards_moved;
> } while (num_cards_moved);
>
> #define derived_states_list (&derived_states_list_struct)
> sfs_check_state_end();
> #undef derived_states_list
>
> {
> register int ret_code;
>
> if (num_total_cards_moved)
> {
> register fcs_collectible_state_t * ptr_next_state;
>
> *ptr_next_state_val
> = ptr_next_state
> = derived_states_list_struct.states[0].state_ptr;
>
> /*
> * Set the GENERATED_BY_PRUNING flag uncondtionally. It won't
> * hurt if it's already there, and if it's a state that was
> * found by other means, we still shouldn't prune it, because
> * it is already "prune-perfect".
> * */
> FCS_S_VISITED(ptr_next_state) |= FCS_VISITED_GENERATED_BY_PRUNING;
>
> ret_code = PRUNE_RET_FOLLOW_STATE;
> }
> else
> {
> *ptr_next_state_val = NULL;
> ret_code = PRUNE_RET_NOT_FOUND;
> }
>
> free(derived_states_list_struct.states);
>
> return ret_code;
> }
> }
>
> [/CODE]
>
> Now, not only implementing it instead of my previous prune broke the tests
> (which is expected because some of them check for exact output), it also made
> performance worse - the MS 32k deals ran at 30 seconds instead of 20 seconds
> using the "-l as" preset. Perhaps I need to recalibrate the switch tasking,
> but I don't think it will make much difference.
>
> Anyway, do you see any obvious bug in my code and the interpretation of the
> Raymond prune based on your Cish pseudocode? I guess I can implement it in the
> other places where it exists (duplicate code for-the-win) assuming it does not
> yield false negatives, though.
>
Received on Mon Dec 24 2012 - 16:23:21 IST