static int fcs_card_compare(const void * card1, const void * card2) { const fcs_card_t * c1 = (const fcs_card_t *)card1; const fcs_card_t * c2 = (const fcs_card_t *)card2; if (fcs_card_card_num(*c1) > fcs_card_card_num(*c2)) { return 1; } else if (fcs_card_card_num(*c1) < fcs_card_card_num(*c2)) { return -1; } else { if (fcs_card_suit(*c1) > fcs_card_suit(*c2)) { return 1; } else if (fcs_card_suit(*c1) < fcs_card_suit(*c2)) { return -1; } else { return 0; } } }
static char * get_the_positions_by_rank_data__ss_generator( fc_solve_soft_thread_t * const soft_thread, const fcs_state_t * const the_state ) { fc_solve_instance_t * const instance = HT_INSTANCE(soft_thread->hard_thread); SET_GAME_PARAMS(); #define FCS_SS_POS_BY_RANK_WIDTH (13+1) #define FCS_POS_BY_RANK_LEN ( FCS_SS_POS_BY_RANK_WIDTH * 4 ) #define FCS_POS_BY_RANK_SIZE (sizeof(positions_by_rank[0]) * FCS_POS_BY_RANK_LEN) #define FCS_POS_IDX(rank, suit) ( (suit)*FCS_SS_POS_BY_RANK_WIDTH + (rank) ) pos_by_rank_t * const positions_by_rank = SMALLOC(positions_by_rank, FCS_POS_BY_RANK_LEN); memset(positions_by_rank, -1, FCS_POS_BY_RANK_SIZE); for (int ds = 0 ; ds < LOCAL_STACKS_NUM ; ds++) { const fcs_const_cards_column_t dest_col = fcs_state_get_col(*the_state, ds); const int dest_cards_num = fcs_col_len(dest_col); for (int dc = 0 ; dc < dest_cards_num ; dc++) { const fcs_card_t card = fcs_col_get_card(dest_col, dc); const int suit = fcs_card_suit(card); const int rank = fcs_card_rank(card); const pos_by_rank_t pos = {.col = ds, .height = dc}; positions_by_rank[FCS_POS_IDX(rank, suit)] = pos; } } return (char *)positions_by_rank; }
int freecell_solver_check_state_validity( fcs_state_with_locations_t * state_with_locations, int freecells_num, int stacks_num, int decks_num, #ifdef FCS_WITH_TALONS int talon_type, #endif fcs_card_t * misplaced_card) { int cards[4][14]; int c, s, d, f; fcs_state_t * state; state = (&(state_with_locations->s)); /* Initialize all cards to 0 */ for(d=0;d<4;d++) { for(c=1;c<=13;c++) { cards[d][c] = 0; } } /* Mark the cards in the decks */ for(d=0;d<decks_num*4;d++) { for(c=1;c<=fcs_foundation_value(*state, d);c++) { cards[d%4][c]++; } } /* Mark the cards in the freecells */ for(f=0;f<freecells_num;f++) { if (fcs_freecell_card_num(*state, f) != 0) { cards [fcs_freecell_card_suit(*state, f)] [fcs_freecell_card_num(*state, f)] ++; } } /* Mark the cards in the stacks */ for(s=0;s<stacks_num;s++) { for(c=0;c<fcs_stack_len(*state,s);c++) { if (fcs_stack_card_num(*state, s, c) == 0) { *misplaced_card = fcs_empty_card; return 3; } cards [fcs_stack_card_suit(*state, s, c)] [fcs_stack_card_num(*state, s, c)] ++; } } #ifdef FCS_WITH_TALONS /* Mark the cards in the (gypsy) talon */ if ((talon_type == FCS_TALON_GYPSY) || (talon_type == FCS_TALON_KLONDIKE)) { for(c = ((talon_type == FCS_TALON_GYPSY)?fcs_talon_pos(*state):1) ; c < ((talon_type==FCS_TALON_GYPSY) ? fcs_talon_len(*state) : (fcs_klondike_talon_len(*state)+1)) ; c++) { if (fcs_get_talon_card(*state,c) != fcs_empty_card) { cards [fcs_card_suit(fcs_get_talon_card(*state, c))] [fcs_card_card_num(fcs_get_talon_card(*state, c))] ++; } } } #endif /* Now check if there are extra or missing cards */ for(d=0;d<4;d++) { for(c=1;c<=13;c++) { if (cards[d][c] != decks_num) { *misplaced_card = fcs_empty_card; fcs_card_set_suit(*misplaced_card, d); fcs_card_set_num(*misplaced_card, c); return (cards[d][c] < decks_num) ? 1 : 2; } } } return 0; }
static GCC_INLINE const fcs_bool_t fcs_is_ss_suit_true(const fcs_card_t parent, const fcs_card_t child) { return (fcs_card_suit(parent) == fcs_card_suit(child)); }
static inline bool fcs_is_ss_suit_true( const fcs_card parent, const fcs_card child) { return (fcs_card_suit(parent) == fcs_card_suit(child)); }