diff options
Diffstat (limited to 'kpat/freecell-solver/card.c')
-rw-r--r-- | kpat/freecell-solver/card.c | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/kpat/freecell-solver/card.c b/kpat/freecell-solver/card.c new file mode 100644 index 00000000..d4df80f7 --- /dev/null +++ b/kpat/freecell-solver/card.c @@ -0,0 +1,286 @@ +/* + * card.c - functions to convert cards and card components to and from + * its user representation. + * + * Written by Shlomi Fish (shlomif@vipe.technion.ac.il), 2000 + * + * This file is in the public domain (it's uncopyrighted). + */ + +#include <string.h> + +#include "card.h" + +#ifdef DMALLOC +#include "dmalloc.h" +#endif + + +#define uc(c) ( (((c)>='a') && ((c)<='z')) ? ((c)+'A'-'a') : (c)) + +/* + * This function converts a card number from its user representation + * (e.g: "A", "K", "9") to its card number that can be used by + * the program. + * */ +int freecell_solver_u2p_card_number(const char * string) +{ + char rest; + + while (1) + { + rest = uc(*string); + + if ((rest == '\0') || (rest == ' ') || (rest == '\t')) + { + return 0; + } + if (rest == 'A') + { + return 1; + } + else if (rest =='J') + { + return 11; + } + else if (rest == 'Q') + { + return 12; + } + else if (rest == 'K') + { + return 13; + } + else if (rest == '1') + { + return (*(string+1) == '0')?10:1; + } + else if ((rest == '0') || (rest == 'T')) + { + return 10; + } + else if ((rest >= '2') && (rest <= '9')) + { + return (rest-'0'); + } + else + { + string++; + } + } +} + + +/* + * This function converts a string containing a suit letter (that is + * one of H,S,D,C) into its suit ID. + * + * The suit letter may come somewhat after the beginning of the string. + * + * */ +int freecell_solver_u2p_suit(const char * suit) +{ + char c; + + c = uc(*suit); + while ( + (c != 'H') && + (c != 'S') && + (c != 'D') && + (c != 'C') && + (c != ' ') && + (c != '\0')) + { + suit++; + c = uc(*suit); + } + + if (c == 'H') + return 0; + else if (c == 'C') + return 1; + else if (c == 'D') + return 2; + else if (c == 'S') + return 3; + else + return 0; +} + +static int fcs_u2p_flipped_status(const char * str) +{ + while (*str != '\0') + { + if ((*str != ' ') && (*str != '\t')) + { + return (*str == '<'); + } + str++; + } + return 0; +} +/* + * This function converts an entire card from its string representations + * (e.g: "AH", "KS", "8D"), to a fcs_card_t data type. + * */ +fcs_card_t freecell_solver_card_user2perl(const char * str) +{ + fcs_card_t card; +#if defined(COMPACT_STATES)||defined(INDIRECT_STACK_STATES) + card = 0; +#endif + fcs_card_set_flipped(card, fcs_u2p_flipped_status(str)); + fcs_card_set_num(card, fcs_u2p_card_number(str)); + fcs_card_set_suit(card, fcs_u2p_suit(str)); + + return card; +} + + +/* + * Those strings contain the string representations of the different cards. + * If CARD_DEBUG_PRES is defined then an asterisk is printed as an empty card. + * + * Notice that there are two of them: one prints 10 and one prints T for the + * 10 card. + * + * */ +#ifdef CARD_DEBUG_PRES +static char card_map_3_10[14][4] = { "*", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; + +static char card_map_3_T[14][4] = { "*", "A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K" }; + +#else +static char card_map_3_10[14][4] = { " ", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; + +static char card_map_3_T[14][4] = { " ", "A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K" }; + +#endif + +/* + * Converts a card_number from its internal representation to a string. + * + * num - the card number + * str - the string to output to. + * card_num_is_null - a pointer to a bool that indicates whether + * the card number is out of range or equal to zero + * t - whether 10 should be printed as T or not. + * flipped - whether the card is face down + * */ +char * freecell_solver_p2u_card_number( + int num, + char * str, + int * card_num_is_null, + int t, + int flipped) +{ + char (*card_map_3) [4] = card_map_3_10; + if (t) + { + card_map_3 = card_map_3_T; + } +#ifdef CARD_DEBUG_PRES + if (0) + { + } +#else + if (flipped) + { + strncpy(str, "*", 2); + *card_num_is_null = 0; + } +#endif + else + { + if ((num >= 0) && (num <= 13)) + { + strncpy(str, card_map_3[num], strlen(card_map_3[num])+1); + *card_num_is_null = (num == 0); + } + else + { + strncpy(str, card_map_3[0], strlen(card_map_3[0])+1); + *card_num_is_null = 1; + } + } + return str; +} + +/* + * Converts a suit to its user representation. + * + * */ +char * freecell_solver_p2u_suit(int suit, char * str, int card_num_is_null, int flipped) +{ +#ifndef CARD_DEBUG_PRES + if (flipped) + { + strncpy(str, "*", 2); + } + else +#endif + if (suit == 0) + { + if (card_num_is_null) +#ifdef CARD_DEBUG_PRES + strncpy(str, "*", 2); +#else + strncpy(str, " ", 2); +#endif + else + strncpy(str, "H", 2); + } + else if (suit == 1) + strncpy(str, "C", 2); + else if (suit == 2) + strncpy(str, "D", 2); + else if (suit == 3) + strncpy(str, "S", 2); + else + strncpy(str, " ", 2); + return str; +} + +/* + * Convert an entire card to its user representation. + * + * */ +char * freecell_solver_card_perl2user(fcs_card_t card, char * str, int t) +{ + int card_num_is_null; +#ifdef CARD_DEBUG_PRES + if (fcs_card_get_flipped(card)) + { + *str = '<'; + str++; + } +#endif + + fcs_p2u_card_number( + fcs_card_card_num(card), + str, + &card_num_is_null, + t, + fcs_card_get_flipped(card) + ); + /* + * Notice that if card_num_is_null is found to be true + * it will affect the output of the suit too. + * + * */ + fcs_p2u_suit( + fcs_card_suit(card), + str+strlen(str), + card_num_is_null, + fcs_card_get_flipped(card) + ); + +#ifdef CARD_DEBUG_PRES + if (fcs_card_get_flipped(card)) + { + strcat(str, ">"); + } +#endif + + return str; +} |