6 #define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)
9 extern TCHAR MsgWin
[128];
10 extern TCHAR MsgDeal
[128];
14 bool fGameStarted
= false;
15 bool bAutoroute
= false;
19 TRACE("ENTER NewGame()\n");
22 if (GetScoreMode() == SCORE_VEGAS
)
24 if ((dwOptions
& OPTION_KEEP_SCORE
) && (dwPrevMode
== SCORE_VEGAS
))
29 if (dwOptions
& OPTION_THREE_CARDS
)
37 if (dwOptions
& OPTION_THREE_CARDS
)
51 //create a new card-stack
57 //deal to each row stack..
58 for(i
= 0; i
< NUM_ROW_STACKS
; i
++)
63 pRowStack
[i
]->SetFaceDirection(CS_FACE_DOWNUP
, i
);
65 for(j
= 0; j
<= i
; j
++)
67 temp
.Push(deck
.Pop());
70 pRowStack
[i
]->SetCardStack(temp
);
73 //put the other cards onto the deck
74 pDeck
->SetCardStack(deck
);
77 // For the 1-card-mode, all cards need to be completely overlapped
78 if(!(dwOptions
& OPTION_THREE_CARDS
))
79 pPile
->SetOffsets(0, 0);
85 dwPrevMode
= GetScoreMode();
89 TRACE("EXIT NewGame()\n");
94 // Now follow the stack callback functions. This is where we
95 // provide the game functionality and rules
99 // Can only drag face-up cards
101 bool CARDLIBPROC
RowStackDragProc(CardRegion
&stackobj
, int iNumDragCards
)
103 TRACE("ENTER RowStackDragProc()\n");
109 stackobj
.GetFaceDirection(&numfacedown
);
111 numcards
= stackobj
.NumCards();
113 TRACE("EXIT RowStackDragProc()\n");
114 if(iNumDragCards
<= numcards
-numfacedown
)
122 // Row a row-stack, we can only drop cards
123 // that are lower / different colour
125 bool CARDLIBPROC
RowStackDropProc(CardRegion
&stackobj
, CardStack
&dragcards
)
127 TRACE("ENTER RowStackDropProc()\n");
128 Card dragcard
= dragcards
[dragcards
.NumCards() - 1];
132 //if we are empty, can only drop a stack with a King at bottom
133 if(stackobj
.NumCards() == 0)
135 if(dragcard
.LoVal() != 13)
137 TRACE("EXIT RowStackDropProc(false)\n");
143 const CardStack
&mystack
= stackobj
.GetCardStack();
145 //can only drop if card is 1 less
146 if(mystack
[0].LoVal() != dragcard
.LoVal() + 1)
148 TRACE("EXIT RowStackDropProc(false)\n");
152 //can only drop if card is different colour
153 if( (mystack
[0].IsBlack() && !dragcard
.IsRed()) ||
154 (!mystack
[0].IsBlack() && dragcard
.IsRed()) )
156 TRACE("EXIT RowStackDropProc(false)\n");
163 if (LastId
== PILE_ID
)
165 if (GetScoreMode() == SCORE_STD
)
170 else if ((LastId
>= SUIT_ID
) && (LastId
<= SUIT_ID
+ 3))
172 if (GetScoreMode() == SCORE_STD
)
174 lScore
= lScore
>= 15 ? lScore
- 15 : 0;
176 else if (GetScoreMode() == SCORE_VEGAS
)
178 lScore
= lScore
>= -47 ? lScore
- 5 : -52;
184 TRACE("EXIT RowStackDropProc(true)\n");
189 // Can only drop a card onto a suit-stack if the
190 // card is 1 higher, and is the same suit
192 bool CanDrop(CardRegion
&stackobj
, Card card
)
194 TRACE("ENTER CanDrop()\n");
197 const CardStack
&cardstack
= stackobj
.GetCardStack();
201 if(cardstack
.NumCards() > 0)
203 if(card
.Suit() != cardstack
[0].Suit())
205 TRACE("EXIT CanDrop()\n");
209 topval
= cardstack
[0].LoVal();
217 if(card
.LoVal() != (topval
+ 1))
219 TRACE("EXIT CanDrop()\n");
223 TRACE("EXIT CanDrop()\n");
228 // Can only drop a card onto suit stack if it is same suit, and 1 higher
230 bool CARDLIBPROC
SuitStackDropProc(CardRegion
&stackobj
, CardStack
&dragcards
)
232 TRACE("ENTER SuitStackDropProc()\n");
236 //only drop 1 card at a time
237 if (!bAutoroute
&& dragcards
.NumCards() != 1)
239 TRACE("EXIT SuitStackDropProc()\n");
243 bool b
= CanDrop(stackobj
, dragcards
[0]);
244 TRACE("EXIT SuitStackDropProc()\n");
248 if ((LastId
== PILE_ID
) || (LastId
>= ROW_ID
))
250 if (GetScoreMode() == SCORE_VEGAS
)
254 else if (GetScoreMode() == SCORE_STD
)
256 lScore
= lScore
+ 10;
267 // Single-click on one of the suit-stacks
269 void CARDLIBPROC
SuitStackClickProc(CardRegion
&stackobj
, int iNumClicked
)
271 TRACE("ENTER SuitStackClickProc()\n");
275 LastId
= stackobj
.Id();
277 TRACE("EXIT SuitStackClickProc()\n");
281 // Single-click on one of the row-stacks
282 // Turn the top-card over if they are all face-down
284 void CARDLIBPROC
RowStackClickProc(CardRegion
&stackobj
, int iNumClicked
)
286 TRACE("ENTER RowStackClickProc()\n");
289 stackobj
.GetFaceDirection(&numfacedown
);
291 //if all face-down, then make top card face-up
292 if(stackobj
.NumCards() == numfacedown
)
294 if(numfacedown
> 0) numfacedown
--;
295 stackobj
.SetFaceDirection(CS_FACE_DOWNUP
, numfacedown
);
298 if (GetScoreMode() == SCORE_STD
)
305 LastId
= stackobj
.Id();
309 TRACE("EXIT RowStackClickProc()\n");
313 // Find the suit-stack that can accept the specified card
315 CardRegion
*FindSuitStackFromCard(Card card
)
317 TRACE("ENTER FindSuitStackFromCard()\n");
319 for(int i
= 0; i
< 4; i
++)
321 if(CanDrop(*pSuitStack
[i
], card
))
323 TRACE("EXIT FindSuitStackFromCard()\n");
324 return pSuitStack
[i
];
328 TRACE("EXIT FindSuitStackFromCard()\n");
333 // What happens when we add a card to one of the suit stacks?
334 // Well, nothing (it is already added), but we need to
335 // check all four stacks (not just this one) to see if
336 // the game has finished.
338 void CARDLIBPROC
SuitStackAddProc(CardRegion
&stackobj
, const CardStack
&added
)
340 TRACE("ENTER SuitStackAddProc()\n");
341 bool fGameOver
= true;
345 for(int i
= 0; i
< 4; i
++)
347 if(pSuitStack
[i
]->NumCards() != 13)
357 KillTimer(hwndMain
, IDT_PLAYTIMER
);
360 if ((dwOptions
& OPTION_SHOW_TIME
) && (GetScoreMode() == SCORE_STD
))
362 lScore
= lScore
+ (700000 / dwTime
);
367 MessageBox(SolWnd
, MsgWin
, szAppName
, MB_OK
| MB_ICONINFORMATION
);
369 for(int i
= 0; i
< 4; i
++)
371 pSuitStack
[i
]->Flash(11, 100);
374 if( IDYES
== MessageBox(SolWnd
, MsgDeal
, szAppName
, MB_YESNO
| MB_ICONQUESTION
) )
380 SolWnd
.EmptyStacks();
382 fGameStarted
= false;
386 TRACE("EXIT SuitStackAddProc()\n");
390 // Double-click on one of the row stacks
391 // The aim is to find a suit-stack to move the
392 // double-clicked card to.
394 void CARDLIBPROC
RowStackDblClickProc(CardRegion
&stackobj
, int iNumClicked
)
396 TRACE("ENTER RowStackDblClickProc()\n");
400 //can only move 1 card at a time
403 TRACE("EXIT RowStackDblClickProc()\n");
407 //find a suit-stack to move the card to...
408 const CardStack
&cardstack
= stackobj
.GetCardStack();
409 CardRegion
*pDest
= FindSuitStackFromCard(cardstack
[0]);
416 //stackobj.MoveCards(pDest, 1, true);
417 //use the SimulateDrag function, because we get the
418 //AddProc callbacks called for us on the destination stacks...
420 stackobj
.SimulateDrag(pDest
, 1, true);
423 TRACE("EXIT RowStackDblClickProc()\n");
427 // Face-up pile single-click
429 void CARDLIBPROC
PileClickProc(CardRegion
&stackobj
, int iNumClicked
)
431 TRACE("ENTER SuitStackClickProc()\n");
435 LastId
= stackobj
.Id();
437 TRACE("EXIT SuitStackClickProc()\n");
441 // Face-up pile double-click
443 void CARDLIBPROC
PileDblClickProc(CardRegion
&stackobj
, int iNumClicked
)
445 TRACE("ENTER PileDblClickProc()\n");
449 RowStackDblClickProc(stackobj
, iNumClicked
);
450 TRACE("EXIT PileDblClickProc()\n");
454 // What happens when a card is removed from face-up pile?
456 void CARDLIBPROC
PileRemoveProc(CardRegion
&stackobj
, int iItems
)
458 TRACE("ENTER PileRemoveProc()\n");
462 //modify our "virtual" pile by removing the same card
463 //that was removed from the physical card stack
464 activepile
.Pop(iItems
);
466 //if there is just 1 card left, then modify the
467 //stack to contain ALL the face-up cards..the effect
468 //will be, the next time a card is dragged, all the
469 //previous card-triplets will be available underneath
470 if(stackobj
.NumCards() == 1)
472 stackobj
.SetOffsets(0,0);
473 stackobj
.SetCardStack(activepile
);
475 TRACE("EXIT PileRemoveProc()\n");
479 // Double-click on the deck
480 // Move 3 cards to the face-up pile
482 void CARDLIBPROC
DeckClickProc(CardRegion
&stackobj
, int iNumClicked
)
484 TRACE("ENTER DeckClickProc()\n");
488 CardStack cardstack
= stackobj
.GetCardStack();
489 CardStack pile
= pPile
->GetCardStack();
494 //reset the face-up pile to represent 3 cards
495 if(dwOptions
& OPTION_THREE_CARDS
)
496 pPile
->SetOffsets(CS_DEFXOFF
, 1);
498 if(cardstack
.NumCards() == 0)
500 if (GetScoreMode() == SCORE_VEGAS
)
502 if (dwWasteCount
< dwWasteTreshold
)
506 activepile
.Reverse();
507 cardstack
.Push(activepile
);
511 else if (GetScoreMode() == SCORE_STD
)
513 if ((dwWasteCount
>= dwWasteTreshold
) && (activepile
.NumCards() != 0))
515 if (dwOptions
& OPTION_THREE_CARDS
)
516 lScore
= lScore
>= 20 ? lScore
- 20 : 0;
518 lScore
= lScore
>= 100 ? lScore
- 100 : 0;
523 activepile
.Reverse();
524 cardstack
.Push(activepile
);
533 activepile
.Reverse();
534 cardstack
.Push(activepile
);
542 int numcards
= min((dwOptions
& OPTION_THREE_CARDS
) ? 3 : 1, cardstack
.NumCards());
544 //make a "visible" copy of these cards
546 temp
= cardstack
.Pop(numcards
);
549 if(dwOptions
& OPTION_THREE_CARDS
)
554 //remove the top 3 from deck
555 activepile
.Push(temp
);
560 pDeck
->SetCardStack(cardstack
);
561 pPile
->SetCardStack(pile
);
564 TRACE("EXIT DeckClickProc()\n");