/*****************************************************************************/ /* */ /* */ /* X patience version 2 -- module r_Spider.c */ /* */ /* Characteristics of the ``Spider'' rules */ /* written by Heiko Eissfeldt and Michael Bischoff */ /* see COPYRIGHT.xpat2 for Copyright details */ /* */ /* */ /*****************************************************************************/ #include "xpatgame.h" /* you win by completing all suits, either on the stacks */ /* or (for more points, see Spider_score) in the slots */ static int Spider_won(void) { Pileindex i; Cardindex k; /* all slots must be empty or contain complete suits */ for (i = FIRST_SLOT; i <= LAST_SLOT; i++) { if (!EMPTY(i)) { if (CARDS_ON_PILE(i) != 13) return 0; k = INDEX_OF_LAST_CARD(i); if (!game.visible[k-12]) return 0; if (complete_suit(i, k) == -1) return 0; } } return 1; } /* calculate score according to Spider documentation */ static int Spider_score(void) { Pileindex i; Cardindex j; int score; int total_visible; int resolved_suits_in_slots=0; int resolved_suits_in_stacks=0; /* set score to the maximum of facedown cards turned */ score = ((rules.numcards % rules.numslots) + rules.numslots * rules.facedown) * 10; for (i = FIRST_SLOT; i <= LAST_SLOT; i++) { total_visible = 1; for (j = game.ind[i]; j < INDEX_OF_LAST_CARD(i); j++) { if (game.visible[j] && in_strong_sequence(game.cards[j+1], game.cards[j])) { /* visible combined cards give 2 Points */ score += 2; } if (!game.visible[j]) { /* each of the unvisible cards at start got 10 Points at first. Now clear the points for each yet invisible card. */ score -= 10; total_visible = 0; /* something is hidden in this slot */ } } /* 15 points for each fully visible slot */ score += total_visible * 15; /* check for completed suits (even if stacked on each other) */ if (!EMPTY(i)) { /* each full sequence gets 50 points total (12 * 2 points are already there) so add 26 points. */ Cardindex k; for (k = INDEX_OF_LAST_CARD(i); k >= game.ind[i] + 12; --k) { if (game.visible[k-12] && complete_suit(i, k) != -1) { score += 26; ++resolved_suits_in_slots; } } } } /* check the stacks for complete sequences */ for (i = 0; i < rules.numstacks; ++i) if (!EMPTY(STACK(i))) { score += 50; /* each completed sequence got 50 points */ resolved_suits_in_stacks ++; } if ((resolved_suits_in_slots + resolved_suits_in_stacks) / 4 /*suits*/ == rules.numdecks) { resolved_suits_in_slots -= 3; if (resolved_suits_in_slots > 0) score += resolved_suits_in_slots * 2; } return score; } static void Spider_init(void) { switch (rules.param[0]) { case 0: rules.move_bits |= DC_NOEMPTY; /* std. Spider rules */ break; case 1: rules.move_bits |= DC_STRONGOK; /* Heiko's variant */ break; case 2: rules.move_bits |= DC_RELAXEDOK; /* Heiko's variant */ break; default: fprintf(stderr, "Spider: option to -relaxed may be 0, 1, or 2. Found %d\n", rules.param[0]); exit(1); } } struct rules Spider_rules = { "Spider", /* shortname */ NULL, /* longname */ NULL, /* abbrev */ 0, /* layout_hints */ 0, /* variant */ CUSTOM_STD|CUSTOM_PARAM0, /* customizable */ 0, /* customized */ 104, /* numcards */ 8, /* numstacks */ 10, /* numslots */ 0, /* numtmps */ 2, /* numdecks */ 13, /* cards_per_color */ 0, /* numjokers */ {0, 0, 0, 0},/* param[0], param[1], param[2], param[3] */ 4, /* facedown */ 1, /* faceup */ 0, /* newgame_bits */ NULL, /* new_game */ Spider_won, /* game_won */ NULL, /* new_cards */ ES_ALL|US_R|MG_RS|ST_13, /* move_bits */ NULL, /* deal_cards */ NULL, /* undeal_cards */ NULL, /* stackable */ NULL, /* movevalid */ NULL, /* valid */ NULL, /* relaxed_valid */ std_good_hint, /* good_hint */ NULL, /* automove */ Spider_score,/* score */ 1000, /* maxscore */ {0, 0, 0, 0}, /* paramstring blocks */ 0, /* used */ Spider_init, /* initfunc */ NULL, /* local keyboard bindings */ };