12 #define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)
15 extern TCHAR MsgWin
[128];
16 extern TCHAR MsgDeal
[128];
19 bool fGameStarted
= false;
23 TRACE("ENTER NewGame()\n");
28 //create a new card-stack
34 //deal to each row stack..
35 for(i
= 0; i
< NUM_ROW_STACKS
; i
++)
40 pRowStack
[i
]->SetFaceDirection(CS_FACE_DOWNUP
, i
);
42 for(j
= 0; j
<= i
; j
++)
44 temp
.Push(deck
.Pop());
47 pRowStack
[i
]->SetCardStack(temp
);
50 //put the other cards onto the deck
51 pDeck
->SetCardStack(deck
);
54 // For the 1-card-mode, all cards need to be completely overlapped
55 if(!(dwOptions
& OPTION_THREE_CARDS
))
56 pPile
->SetOffsets(0, 0);
61 TRACE("EXIT NewGame()\n");
65 // Now follow the stack callback functions. This is where we
66 // provide the game functionality and rules
70 // Can only drag face-up cards
72 bool CARDLIBPROC
RowStackDragProc(CardRegion
&stackobj
, int iNumDragCards
)
74 TRACE("ENTER RowStackDragProc()\n");
78 stackobj
.GetFaceDirection(&numfacedown
);
80 numcards
= stackobj
.NumCards();
82 TRACE("EXIT RowStackDragProc()\n");
83 if(iNumDragCards
<= numcards
-numfacedown
)
91 // Row a row-stack, we can only drop cards
92 // that are lower / different colour
94 bool CARDLIBPROC
RowStackDropProc(CardRegion
&stackobj
, CardStack
&dragcards
)
96 TRACE("ENTER RowStackDropProc()\n");
97 Card dragcard
= dragcards
[dragcards
.NumCards() - 1];
99 //if we are empty, can only drop a stack with a King at bottom
100 if(stackobj
.NumCards() == 0)
102 if(dragcard
.LoVal() != 13)
104 TRACE("EXIT RowStackDropProc(false)\n");
110 const CardStack
&mystack
= stackobj
.GetCardStack();
112 //can only drop if card is 1 less
113 if(mystack
[0].LoVal() != dragcard
.LoVal() + 1)
115 TRACE("EXIT RowStackDropProc(false)\n");
119 //can only drop if card is different colour
120 if( (mystack
[0].IsBlack() && !dragcard
.IsRed()) ||
121 (!mystack
[0].IsBlack() && dragcard
.IsRed()) )
123 TRACE("EXIT RowStackDropProc(false)\n");
130 TRACE("EXIT RowStackDropProc(true)\n");
135 // Can only drop a card onto a suit-stack if the
136 // card is 1 higher, and is the same suit
138 bool CanDrop(CardRegion
&stackobj
, Card card
)
140 TRACE("ENTER CanDrop()\n");
143 const CardStack
&cardstack
= stackobj
.GetCardStack();
145 if(cardstack
.NumCards() > 0)
147 if(card
.Suit() != cardstack
[0].Suit())
149 TRACE("EXIT CanDrop()\n");
153 topval
= cardstack
[0].LoVal();
161 if(card
.LoVal() != (topval
+ 1))
163 TRACE("EXIT CanDrop()\n");
167 TRACE("EXIT CanDrop()\n");
172 // Can only drop a card onto suit stack if it is same suit, and 1 higher
174 bool CARDLIBPROC
SuitStackDropProc(CardRegion
&stackobj
, CardStack
&dragcards
)
176 TRACE("ENTER SuitStackDropProc()\n");
177 //only drop 1 card at a time
178 if(dragcards
.NumCards() != 1)
180 TRACE("EXIT SuitStackDropProc()\n");
184 bool b
= CanDrop(stackobj
, dragcards
[0]);
185 TRACE("EXIT SuitStackDropProc()\n");
190 // Single-click on one of the row-stacks
191 // Turn the top-card over if they are all face-down
193 void CARDLIBPROC
RowStackClickProc(CardRegion
&stackobj
, int iNumClicked
)
195 TRACE("ENTER RowStackClickProc()\n");
198 stackobj
.GetFaceDirection(&numfacedown
);
200 //if all face-down, then make top card face-up
201 if(stackobj
.NumCards() == numfacedown
)
203 if(numfacedown
> 0) numfacedown
--;
204 stackobj
.SetFaceDirection(CS_FACE_DOWNUP
, numfacedown
);
207 TRACE("EXIT RowStackClickProc()\n");
211 // Find the suit-stack that can accept the specified card
213 CardRegion
*FindSuitStackFromCard(Card card
)
215 TRACE("ENTER FindSuitStackFromCard()\n");
216 for(int i
= 0; i
< 4; i
++)
218 if(CanDrop(*pSuitStack
[i
], card
))
220 TRACE("EXIT FindSuitStackFromCard()\n");
221 return pSuitStack
[i
];
225 TRACE("EXIT FindSuitStackFromCard()\n");
230 // What happens when we add a card to one of the suit stacks?
231 // Well, nothing (it is already added), but we need to
232 // check all four stacks (not just this one) to see if
233 // the game has finished.
235 void CARDLIBPROC
SuitStackAddProc(CardRegion
&stackobj
, const CardStack
&added
)
237 TRACE("ENTER SuitStackAddProc()\n");
238 bool fGameOver
= true;
240 for(int i
= 0; i
< 4; i
++)
242 if(pSuitStack
[i
]->NumCards() != 13)
251 MessageBox(SolWnd
, MsgWin
, szAppName
, MB_OK
| MB_ICONINFORMATION
);
253 for(int i
= 0; i
< 4; i
++)
255 pSuitStack
[i
]->Flash(11, 100);
258 if( IDYES
== MessageBox(SolWnd
, MsgDeal
, szAppName
, MB_YESNO
| MB_ICONQUESTION
) )
264 SolWnd
.EmptyStacks();
266 fGameStarted
= false;
270 TRACE("EXIT SuitStackAddProc()\n");
274 // Double-click on one of the row stacks
275 // The aim is to find a suit-stack to move the
276 // double-clicked card to.
278 void CARDLIBPROC
RowStackDblClickProc(CardRegion
&stackobj
, int iNumClicked
)
280 TRACE("ENTER RowStackDblClickProc()\n");
281 //can only move 1 card at a time
284 TRACE("EXIT RowStackDblClickProc()\n");
288 //find a suit-stack to move the card to...
289 const CardStack
&cardstack
= stackobj
.GetCardStack();
290 CardRegion
*pDest
= FindSuitStackFromCard(cardstack
[0]);
296 //stackobj.MoveCards(pDest, 1, true);
297 //use the SimulateDrag funcion, because we get the
298 //AddProc callbacks called for us on the destination stacks...
299 stackobj
.SimulateDrag(pDest
, 1, true);
301 TRACE("EXIT RowStackDblClickProc()\n");
305 // Face-up pile double-click
307 void CARDLIBPROC
PileDblClickProc(CardRegion
&stackobj
, int iNumClicked
)
309 TRACE("ENTER PileDblClickProc()\n");
310 RowStackDblClickProc(stackobj
, iNumClicked
);
311 TRACE("EXIT PileDblClickProc()\n");
315 // What happens when a card is removed from face-up pile?
317 void CARDLIBPROC
PileRemoveProc(CardRegion
&stackobj
, int iItems
)
319 TRACE("ENTER PileRemoveProc()\n");
320 //modify our "virtual" pile by removing the same card
321 //that was removed from the physical card stack
322 activepile
.Pop(iItems
);
324 //if there is just 1 card left, then modify the
325 //stack to contain ALL the face-up cards..the effect
326 //will be, the next time a card is dragged, all the
327 //previous card-triplets will be available underneath
328 if(stackobj
.NumCards() == 1)
330 stackobj
.SetOffsets(0,0);
331 stackobj
.SetCardStack(activepile
);
333 TRACE("EXIT PileRemoveProc()\n");
337 // Double-click on the deck
338 // Move 3 cards to the face-up pile
340 void CARDLIBPROC
DeckClickProc(CardRegion
&stackobj
, int iNumClicked
)
342 TRACE("ENTER DeckClickProc()\n");
343 CardStack cardstack
= stackobj
.GetCardStack();
344 CardStack pile
= pPile
->GetCardStack();
348 //reset the face-up pile to represent 3 cards
349 if(dwOptions
& OPTION_THREE_CARDS
)
350 pPile
->SetOffsets(CS_DEFXOFF
, 1);
352 if(cardstack
.NumCards() == 0)
356 activepile
.Reverse();
357 cardstack
.Push(activepile
);
362 int numcards
= min((dwOptions
& OPTION_THREE_CARDS
) ? 3 : 1, cardstack
.NumCards());
364 //make a "visible" copy of these cards
366 temp
= cardstack
.Pop(numcards
);
369 if(dwOptions
& OPTION_THREE_CARDS
)
374 //remove the top 3 from deck
375 activepile
.Push(temp
);
380 pDeck
->SetCardStack(cardstack
);
381 pPile
->SetCardStack(pile
);
384 TRACE("EXIT DeckClickProc()\n");