Hi Danny,
see below for my response:
On Mon, 10 Dec 2012 19:38:37 -0000
"dannyjones183" <dannyjones183_at_yahoo.com> wrote:
> --- In fc-solve-discuss_at_yahoogroups.com, Shlomi Fish <shlomif_at_...>
> wrote:
> >
> > Hi Danny,
> >
> > trying to understand your logic I ran into what appears to be a bug:
> >
>
> <snip>
>
> > >
> > > Automove logic for Keith's first scenario. Braces contain actual
> values
> > > assigned.
> > >
> > >
> > > /* Foundation: 5C 4D 3S 4H */
> > > /* Card in Question: 6C */
> > >
> > > int Test_1, Test_2, Test_3, Test_4, val_1[4], val_2[4];
> > >
> > > val_1[C] = {6} = RANK( 5C ) + 1;
> > > val_1[D] = {5} = RANK( 4D ) + 1;
> > > val_1[S] = {4} = RANK( 3S ) + 1;
> > > val_1[H] = {5} = RANK( 4H ) + 1;
> > >
> > > val_2[C] = val_2[S] = {6} = MIN( val_1[D] , val_1[H] ) + 1;
> > > val_2[D] = val_2[H] = {5} = MIN( val_1[C] , val_1[S] ) + 1;
> > >
> > > Test_1 = {T} = ( RANK( 6C ) == val_1[C] );
> > > Test_2 = {F} = ( RANK( 6C ) < val_2[C] );
> > > Test_3 = {T} = ( ( RANK( 6C ) == val_2[C] ) && ( RANK( 6C ) <= (
> > > val_1[S] + 2 ) ) );
> > > Test_4 = {F} = ( Test_3 && ( RANK( 6C ) == 2 ) );
> >
> > Are you sure that it should be RANK( 6C ) == 2 (with a constant of
> 2.)? 6C can
> > never have such a rank so the test will almost always fail. Of can you
> only
> > play cards with a rank of 2 this way?
> >
>
> I placed MK's actual cards into the logic used by my solver. The "Card
> in Question" was the 6C. The reason for the test ( RANK(card) == 2 ) is
> to allow the Horne automove logic to perform a WKR automove for 2's.
> There's actually two groups of logic in a Horne automove!
>
> <snip>
>
> Regards, Danny
>
Trying to implement Raymond's play properly, I've written this code (hope it
is easy to understand):
[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.
Regards,
Shlomi Fish
--
-----------------------------------------------------------------
Shlomi Fish http://www.shlomifish.org/
My Aphorisms - http://www.shlomifish.org/humour.html
Do not meddle in the affairs of Dragons, for you are crunchy and taste good
with ketchup. — Unknown source.
Please reply to list if it's a mailing list post - http://shlom.in/reply .
Received on Mon Dec 24 2012 - 13:17:29 IST