/*****************************************************************************/ /* */ /* */ /* X patience version 2 -- module r_MonteCarlo.c */ /* */ /* Characteristics of the ``Monte Carlo'' rules */ /* written by Michael Bischoff (mbi@mo.math.nat.tu-bs.de) */ /* 04-Apr-1994 */ /* see COPYRIGHT.xpat2 for Copyright details */ /* */ /* */ /*****************************************************************************/ #include "xpatgame.h" #define COLUMNS (rules.param[1]) #define MCDX 14 #define MCDY 4 static int MC_new_cards(void) { int i, hashole = 0; for (i = FIRST_SLOT; i <= LAST_SLOT; ++i) { switch (CARDS_ON_PILE(i)) { case 0: hashole = 1; break; case 1: if (hashole) /* 0 => 1 transition */ return 1; break; default: return 1; } } return 0; } static Move MC_deal_cards(void) { Pileindex rd, wr; int emptybefore, turned; int remember_count = game.n_moves; store_move(COMPOUND_BEGIN); for (wr = rd = FIRST_SLOT; rd <= LAST_SLOT; ++rd) { switch (CARDS_ON_PILE(rd)) { case 1: if (rd != wr) { /* shift cards to wr pile */ store_move(do_move(INDEX_OF_FIRST_CARD(rd), wr++)); } else ++wr; case 0: break; /* no action */ default: store_move(do_move(INDEX_OF_FIRST_CARD(rd), FIRST_STACK)); } } /* now fill with remaining cards */ emptybefore = EMPTY(IDECK); turned = 0; while (wr <= LAST_SLOT && !EMPTY(IDECK)) { store_move(do_move(INDEX_OF_LAST_CARD(IDECK), wr++)); ++turned; } if (turned) store_move(ADD_CHEAT | (Move)turned); if (EMPTY(IDECK) && !emptybefore) /* there are no more cards now */ draw_pileupdate(IDECK, 0); /* force deck to be redrawn */ game.n_moves = remember_count; return COMPOUND_END; /* this will do the increment */ } static int MC_move_valid(Cardindex src, Pileindex dstpile) { int i, thiscard, thatcard; Pileindex srcpile = getpile(src); if (CARDS_ON_PILE(srcpile) != 1 || CARDS_ON_PILE(dstpile) != 1) return 0; if (game.piletype[srcpile] != Slot || game.piletype[dstpile] != Slot) return 0; thiscard = game.cards[src]; thatcard = game.cards[INDEX_OF_LAST_CARD(dstpile)]; if (RANK(thiscard) != RANK(thatcard)) return 0; i = (srcpile-FIRST_SLOT) % COLUMNS - (dstpile-FIRST_SLOT) % COLUMNS; if (i < -1 || i > 1) return 0; i = (srcpile-FIRST_SLOT) / COLUMNS - (dstpile-FIRST_SLOT) / COLUMNS; if (i < -1 || i > 1) return 0; return 1; } static void MC_minwindow(int w, int h, int dx, int dy, int *x, int *y) { /* The deck, no stack, the slots */ *x = (w + dx + MCDX) * COLUMNS + 2 * dx + w; *y = (h + dy + MCDY) * ((rules.numslots+COLUMNS-1)/COLUMNS); } #include "xpatgeo.h" static int MC_Layout(void) { int i, y, x; struct pilegeometry *p = geo.pg; y = geo.dy; p = geo.pg+IDECK; p->x = geo.dx; p->y = y; p = geo.pg+FIRST_SLOT; x = geo.cw + 2 * geo.dx; for (i = 0; i < rules.numslots; ++i) { p->x = x + (i%5) * (geo.cw + geo.dx + MCDX); p->y = y + (i/5) * (geo.ch + geo.dy + MCDY); p->dx = MCDX; p->dy = MCDY; p->w = geo.cw + MCDX; p->h = geo.ch + MCDY; ++p; } return MONTECARLO_MAGIC; } struct rules MonteCarlo_rules = { "Monte Carlo",/* shortname */ NULL, /* longname */ "mc", /* abbrev */ 3, /* layout_hints */ HINTS_LESSER,/* variant */ 0, /* customizable */ 0, /* customized */ 52, /* numcards */ 4, /* numstacks */ 25, /* numslots */ 0, /* numtmps */ 1, /* numdecks */ 13, /* cards_per_color */ 0, /* numjokers */ {0, 5, 0, 0},/* param[0], param[1], param[2], param[3] */ 0, /* facedown */ 1, /* faceup */ SLOTS_SAME, /* newgame_bits */ NULL, /* new_game */ NULL, /* game_won */ MC_new_cards,/* new_cards */ ST_NONE|MG_NONE, /* move_bits */ MC_deal_cards, /* deal_cards */ NULL, /* undeal_cards */ NULL, /* stackable */ MC_move_valid, /* movevalid */ NULL, /* valid */ NULL, /* relaxed_valid */ NULL, /* good_hint */ NULL, /* automove */ NULL, /* score */ 0, /* maxscore */ {0, 0, 0, 0}, /* paramstring blocks */ 0, /* used */ NULL, /* initfunc */ NULL, /* local keyboard bindings */ MC_minwindow, MC_Layout /* minwindow routine */ };