1 /*****************************************************************************/
2 /*									     */
3 /*									     */
4 /*	X patience version 2 -- module r_MonteCarlo.c			     */
5 /*									     */
6 /*	Characteristics of the ``Monte Carlo'' rules			     */
7 /*	written by Michael Bischoff (mbi@mo.math.nat.tu-bs.de)		     */
8 /*	04-Apr-1994							     */
9 /*	see COPYRIGHT.xpat2 for Copyright details			     */
10 /*									     */
11 /*									     */
12 /*****************************************************************************/
13 #include "xpatgame.h"
14 
15 #define COLUMNS	(rules.param[1])
16 
17 #define MCDX 14
18 #define MCDY 4
19 
MC_new_cards(void)20 static int MC_new_cards(void) {
21     int i, hashole = 0;
22     for (i = FIRST_SLOT; i <= LAST_SLOT; ++i) {
23 	switch (CARDS_ON_PILE(i)) {
24 	case 0:
25 	    hashole = 1;
26 	    break;
27 	case 1:
28 	    if (hashole)	/* 0 => 1 transition */
29 		return 1;
30 	    break;
31 	default:
32 	    return 1;
33 	}
34     }
35     return 0;
36 }
37 
MC_deal_cards(void)38 static Move MC_deal_cards(void) {
39     Pileindex rd, wr;
40     int emptybefore, turned;
41     int remember_count = game.n_moves;
42     store_move(COMPOUND_BEGIN);
43     for (wr = rd = FIRST_SLOT; rd <= LAST_SLOT; ++rd) {
44 	switch (CARDS_ON_PILE(rd)) {
45 	case 1:
46 	    if (rd != wr) {
47 		/* shift cards to wr pile */
48 		store_move(do_move(INDEX_OF_FIRST_CARD(rd), wr++));
49 	    } else
50 		++wr;
51 	case 0:
52 	    break;	/* no action */
53 	default:
54 	    store_move(do_move(INDEX_OF_FIRST_CARD(rd), FIRST_STACK));
55 	}
56     }
57     /* now fill with remaining cards */
58     emptybefore = EMPTY(IDECK);
59     turned = 0;
60     while (wr <= LAST_SLOT && !EMPTY(IDECK)) {
61 	store_move(do_move(INDEX_OF_LAST_CARD(IDECK), wr++));
62 	++turned;
63     }
64     if (turned)
65 	store_move(ADD_CHEAT | (Move)turned);
66 
67     if (EMPTY(IDECK) && !emptybefore)	/* there are no more cards now */
68 	draw_pileupdate(IDECK, 0);	/* force deck to be redrawn */
69 
70     game.n_moves = remember_count;
71     return COMPOUND_END;	/* this will do the increment */
72 }
73 
MC_move_valid(Cardindex src,Pileindex dstpile)74 static int MC_move_valid(Cardindex src, Pileindex dstpile) {
75     int i, thiscard, thatcard;
76     Pileindex srcpile = getpile(src);
77 
78     if (CARDS_ON_PILE(srcpile) != 1 || CARDS_ON_PILE(dstpile) != 1)
79 	return 0;
80     if (game.piletype[srcpile] != Slot || game.piletype[dstpile] != Slot)
81 	return 0;
82     thiscard = game.cards[src];
83     thatcard = game.cards[INDEX_OF_LAST_CARD(dstpile)];
84 
85     if (RANK(thiscard) != RANK(thatcard))
86 	return 0;
87 
88     i = (srcpile-FIRST_SLOT) % COLUMNS - (dstpile-FIRST_SLOT) % COLUMNS;
89     if (i < -1 || i > 1)
90 	return 0;
91     i = (srcpile-FIRST_SLOT) / COLUMNS - (dstpile-FIRST_SLOT) / COLUMNS;
92     if (i < -1 || i > 1)
93 	return 0;
94     return 1;
95 }
96 
MC_minwindow(int w,int h,int dx,int dy,int * x,int * y)97 static void MC_minwindow(int w, int h, int dx, int dy, int *x, int *y) {
98     /* The deck, no stack, the slots */
99     *x = (w + dx + MCDX) * COLUMNS + 2 * dx + w;
100     *y = (h + dy + MCDY) * ((rules.numslots+COLUMNS-1)/COLUMNS);
101 }
102 
103 #include "xpatgeo.h"
104 
MC_Layout(void)105 static int MC_Layout(void) {
106     int i, y, x;
107     struct pilegeometry *p = geo.pg;
108 
109     y = geo.dy;
110     p = geo.pg+IDECK;
111     p->x = geo.dx;
112     p->y = y;
113 
114     p = geo.pg+FIRST_SLOT;
115     x = geo.cw + 2 * geo.dx;
116     for (i = 0; i < rules.numslots; ++i) {
117 	p->x = x + (i%5) * (geo.cw + geo.dx + MCDX);
118 	p->y = y + (i/5) * (geo.ch + geo.dy + MCDY);
119 	p->dx = MCDX;
120 	p->dy = MCDY;
121 	p->w = geo.cw + MCDX;
122 	p->h = geo.ch + MCDY;
123 	++p;
124     }
125     return MONTECARLO_MAGIC;
126 }
127 
128 struct rules MonteCarlo_rules = {
129     "Monte Carlo",/* shortname */
130     NULL,	/* longname */
131     "mc",       /* abbrev */
132     3,		/* layout_hints */
133     HINTS_LESSER,/* variant */
134     0,		/* customizable */
135     0,		/* customized */
136     52,		/* numcards */
137     4,		/* numstacks */
138     25,		/* numslots */
139     0,		/* numtmps */
140     1,		/* numdecks */
141     13,		/* cards_per_color */
142     0,		/* numjokers */
143     {0, 5, 0, 0},/* param[0], param[1], param[2], param[3] */
144     0,		/* facedown */
145     1,		/* faceup */
146     SLOTS_SAME,	/* newgame_bits */
147     NULL,	/* new_game */
148     NULL,	/* game_won */
149     MC_new_cards,/* new_cards */
150     ST_NONE|MG_NONE,	/* move_bits */
151     MC_deal_cards,	/* deal_cards */
152     NULL,	/* undeal_cards */
153     NULL,	/* stackable */
154     MC_move_valid,	/* movevalid */
155     NULL,	/* valid */
156     NULL,	/* relaxed_valid */
157     NULL,	/* good_hint */
158     NULL,	/* automove */
159     NULL,	/* score */
160     0,		/* maxscore */
161     {0, 0, 0, 0}, /* paramstring blocks */
162     0,		/* used */
163     NULL,	/* initfunc */
164     NULL,	/* local keyboard bindings */
165     MC_minwindow, MC_Layout	/* minwindow routine */
166 };
167