/*****************************************************************************/ /* */ /* */ /* X patience version 2 -- module r_Seahaven.c */ /* */ /* Characteristics of the ``Seahaven Towers'' rules */ /* written by Michael Bischoff */ /* see COPYRIGHT.xpat2 for Copyright details */ /* */ /* */ /*****************************************************************************/ #include "xpatgame.h" static int count_free_slots(Pileindex avoid) { Pileindex i; int empty_slots = 0; for (i = FIRST_SLOT; i <= LAST_SLOT; ++i) if (i != avoid && EMPTY(i)) ++empty_slots; return empty_slots; } static int Seahaven_valid(Cardindex src, Pileindex dstpile) { Pileindex srcpile; if (!default_movevalid(src, dstpile)) return 0; /* move is not valid */ /* if we use relaxed rules, the move is valid */ if (rules.param[0]) return 1; /* relaxed rules */ /* strict rules: for slot to slot moves, there must be a sufficient number of tmps free */ srcpile = getpile(src); if (game.piletype[srcpile] == Slot && game.piletype[dstpile] == Slot) { int freetmps, freeslots = 0, cardsmoved; if ((rules.move_bits & ES_MASK) == ES_ALL) { /* may use empty slots also */ /* this doubles the number of movable cards with every free slot => power of two */ freeslots = count_free_slots(dstpile); } cardsmoved = INDEX_OF_LAST_CARD(srcpile) + 1 - src; freetmps = rules.numtmps - (INDEX_OF_FIRST_CARD( LAST_SLOT+1+rules.numtmps) - INDEX_OF_FIRST_CARD(LAST_SLOT+1)); if (cardsmoved > (freetmps + 1) * (1 << freeslots)) return 0; } return 1; } struct rules Seahaven_rules = { /* Seahaven */ "Seahaven", /* shortname */ "Seahaven Towers", /* longname */ "st", /* abbrev */ 1, /* layout_hints */ NODEAL, /* variant */ CUSTOM_STD|CUSTOM_PARAM0, /* customizable */ 0, /* customized */ 52, /* numcards */ 4, /* numstacks */ 10, /* numslots */ 4, /* numtmps */ 1, /* numdecks */ 13, /* cards_per_color */ 0, /* numjokers */ {0, 0, 0, 0},/* param[0], param[1], param[2], param[3] */ 0, /* facedown */ 5, /* faceup */ 0, /* newgame_bits */ NULL, /* new_game */ NULL, /* game_won */ NULL, /* new_cards */ ES_KINGS|US_RS|MG_RS|DC_ALWAYS|ST_ONE|STACK_SOURCE, /* move_bits */ NULL, /* deal_cards */ NULL, /* undeal_cards */ NULL, /* stackable */ Seahaven_valid, /* movevalid */ NULL, /* valid */ NULL, /* relaxed_valid */ std_good_hint,/* good_hint */ NULL, /* automove */ NULL, /* score */ 0, /* maxscore */ {0, 0, 0, 0}, /* paramstring blocks */ 0, /* used */ NULL, /* initfunc */ NULL, /* local keyboard bindings */ }; struct rules FreeCell_rules = { /* FreeCell */ "Free Cell",/* shortname */ NULL, /* longname */ "fc", /* abbrev */ 1, /* layout_hints */ NODEAL, /* variant */ CUSTOM_STD|CUSTOM_PARAM0, /* customizable */ 0, /* customized */ 52, /* numcards */ 4, /* numstacks */ 8, /* numslots */ 4, /* numtmps */ 1, /* numdecks */ 13, /* cards_per_color */ 0, /* numjokers */ {0, 0, 0, 0},/* param[0], param[1], param[2], param[3] */ 0, /* facedown */ 6, /* faceup */ FORCE_SLOTS,/* newgame_bits */ NULL, /* new_game */ NULL, /* game_won */ NULL, /* new_cards */ ES_ALL|US_RA|MG_RA|DC_ALWAYS|ST_ONE|STACK_SOURCE, /* move_bits */ NULL, /* deal_cards */ NULL, /* undeal_cards */ NULL, /* stackable */ Seahaven_valid, /* movevalid */ NULL, /* valid */ NULL, /* relaxed_valid */ std_good_hint,/* good_hint */ NULL, /* automove */ NULL, /* score */ 0, /* maxscore */ {0, 0, 0, 0}, /* paramstring blocks */ 0, /* used */ NULL, /* initfunc */ NULL, /* local keyboard bindings */ };