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