Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600#include "solitaire.h"
#if 1#define TRACE(s)#else#define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)#endif
extern TCHAR MsgWin[128];extern TCHAR MsgDeal[128];
CardStack activepile;int VisiblePileCards;int LastId;bool fGameStarted = false;bool bAutoroute = false;
void NewGame(void){ TRACE("ENTER NewGame()\n"); int i, j;
if (GetScoreMode() == SCORE_VEGAS) { if ((dwOptions & OPTION_KEEP_SCORE) && (dwPrevMode == SCORE_VEGAS)) lScore = lScore - 52; else lScore = -52;
if (dwOptions & OPTION_THREE_CARDS) dwWasteTreshold = 2; else dwWasteTreshold = 0;
} else { if (dwOptions & OPTION_THREE_CARDS) dwWasteTreshold = 3; else dwWasteTreshold = 0;
lScore = 0; }
dwTime = 0; dwWasteCount = 0; LastId = 0;
SolWnd.EmptyStacks();
//create a new card-stack CardStack deck; deck.NewDeck(); deck.Shuffle(); activepile.Clear(); VisiblePileCards = 0;
//deal to each row stack.. for(i = 0; i < NUM_ROW_STACKS; i++) { CardStack temp; temp.Clear();
pRowStack[i]->SetFaceDirection(CS_FACE_DOWNUP, i);
for(j = 0; j <= i; j++) { temp.Push(deck.Pop()); }
pRowStack[i]->SetCardStack(temp); }
//put the other cards onto the deck pDeck->SetCardStack(deck); pDeck->Update();
// For the 1-card-mode, all cards need to be completely overlapped if(!(dwOptions & OPTION_THREE_CARDS)) pPile->SetOffsets(0, 0);
SolWnd.Redraw();
fGameStarted = false;
dwPrevMode = GetScoreMode();
UpdateStatusBar(); ClearUndo();
TRACE("EXIT NewGame()\n");
}
//// Now follow the stack callback functions. This is where we// provide the game functionality and rules//
//// Can only drag face-up cards//bool CARDLIBPROC RowStackDragProc(CardRegion &stackobj, int iNumDragCards){ TRACE("ENTER RowStackDragProc()\n"); int numfacedown; int numcards;
SetPlayTimer();
stackobj.GetFaceDirection(&numfacedown);
numcards = stackobj.NumCards();
TRACE("EXIT RowStackDragProc()\n"); if(iNumDragCards <= numcards-numfacedown) return true; else return false;
}
//// Row a row-stack, we can only drop cards// that are lower / different colour//bool CARDLIBPROC RowStackDropProc(CardRegion &stackobj, CardStack &dragcards){ TRACE("ENTER RowStackDropProc()\n"); Card dragcard = dragcards[dragcards.NumCards() - 1];
SetPlayTimer();
//if we are empty, can only drop a stack with a King at bottom if(stackobj.NumCards() == 0) { if(dragcard.LoVal() != 13) { TRACE("EXIT RowStackDropProc(false)\n"); return false; } } else { const CardStack &mystack = stackobj.GetCardStack();
//can only drop if card is 1 less if(mystack[0].LoVal() != dragcard.LoVal() + 1) { TRACE("EXIT RowStackDropProc(false)\n"); return false; }
//can only drop if card is different colour if( (mystack[0].IsBlack() && !dragcard.IsRed()) || (!mystack[0].IsBlack() && dragcard.IsRed()) ) { TRACE("EXIT RowStackDropProc(false)\n"); return false; } }
fGameStarted = true;
SetUndo(LastId, stackobj.Id(), dragcards.NumCards(), lScore, VisiblePileCards);
if (LastId == PILE_ID) { if (GetScoreMode() == SCORE_STD) { lScore = lScore + 5; } } else if ((LastId >= SUIT_ID) && (LastId <= SUIT_ID + 3)) { if (GetScoreMode() == SCORE_STD) { lScore = lScore >= 15 ? lScore - 15 : 0; } else if (GetScoreMode() == SCORE_VEGAS) { lScore = lScore >= -47 ? lScore - 5 : -52; } }
UpdateStatusBar();
TRACE("EXIT RowStackDropProc(true)\n"); return true;}
//// Can only drop a card onto a suit-stack if the// card is 1 higher, and is the same suit//bool CanDrop(CardRegion &stackobj, Card card){ TRACE("ENTER CanDrop()\n"); int topval;
const CardStack &cardstack = stackobj.GetCardStack();
SetPlayTimer();
if(cardstack.NumCards() > 0) { if(card.Suit() != cardstack[0].Suit()) { TRACE("EXIT CanDrop()\n"); return false; }
topval = cardstack[0].LoVal(); } else { topval = 0; }
//make sure 1 higher if(card.LoVal() != (topval + 1)) { TRACE("EXIT CanDrop()\n"); return false; }
TRACE("EXIT CanDrop()\n"); return true;}
//// Can only drop a card onto suit stack if it is same suit, and 1 higher//bool CARDLIBPROC SuitStackDropProc(CardRegion &stackobj, CardStack &dragcards){ TRACE("ENTER SuitStackDropProc()\n");
SetPlayTimer();
//only drop 1 card at a time if (!bAutoroute && dragcards.NumCards() != 1) { TRACE("EXIT SuitStackDropProc()\n"); return false; }
bool b = CanDrop(stackobj, dragcards[0]); TRACE("EXIT SuitStackDropProc()\n");
if (b) { SetUndo(LastId, stackobj.Id(), 1, lScore, VisiblePileCards);
if ((LastId == PILE_ID) || (LastId >= ROW_ID)) { if (GetScoreMode() == SCORE_VEGAS) { lScore = lScore + 5; } else if (GetScoreMode() == SCORE_STD) { lScore = lScore + 10; }
UpdateStatusBar(); } }
return b;}
//// Single-click on one of the suit-stacks//void CARDLIBPROC SuitStackClickProc(CardRegion &stackobj, int iNumClicked){ TRACE("ENTER SuitStackClickProc()\n");
fGameStarted = true;
LastId = stackobj.Id();
TRACE("EXIT SuitStackClickProc()\n");}
//// Single-click on one of the row-stacks// Turn the top-card over if they are all face-down//void CARDLIBPROC RowStackClickProc(CardRegion &stackobj, int iNumClicked){ TRACE("ENTER RowStackClickProc()\n"); int numfacedown;
stackobj.GetFaceDirection(&numfacedown);
//if all face-down, then make top card face-up if(stackobj.NumCards() == numfacedown) { if(numfacedown > 0) numfacedown--; stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown); stackobj.Redraw();
if (GetScoreMode() == SCORE_STD) { lScore = lScore + 5; UpdateStatusBar(); } ClearUndo(); }
LastId = stackobj.Id();
fGameStarted = true;
TRACE("EXIT RowStackClickProc()\n");}
//// Find the suit-stack that can accept the specified card//CardRegion *FindSuitStackFromCard(Card card){ TRACE("ENTER FindSuitStackFromCard()\n");
for(int i = 0; i < 4; i++) { if(CanDrop(*pSuitStack[i], card)) { TRACE("EXIT FindSuitStackFromCard()\n"); return pSuitStack[i]; } }
TRACE("EXIT FindSuitStackFromCard()\n"); return 0;}
//// What happens when we add a card to one of the suit stacks?// Well, nothing (it is already added), but we need to// check all four stacks (not just this one) to see if// the game has finished.//void CARDLIBPROC SuitStackAddProc(CardRegion &stackobj, const CardStack &added){ TRACE("ENTER SuitStackAddProc()\n"); bool fGameOver = true;
SetPlayTimer();
for(int i = 0; i < 4; i++) { if(pSuitStack[i]->NumCards() != 13) { fGameOver = false;
break; } }
if(fGameOver) { KillTimer(hwndMain, IDT_PLAYTIMER); PlayTimer = 0;
if ((dwOptions & OPTION_SHOW_TIME) && (GetScoreMode() == SCORE_STD)) { lScore = lScore + (700000 / dwTime); }
UpdateStatusBar(); ClearUndo();
MessageBox(SolWnd, MsgWin, szAppName, MB_OK | MB_ICONINFORMATION);
for(int i = 0; i < 4; i++) { pSuitStack[i]->Flash(11, 100); }
if( IDYES == MessageBox(SolWnd, MsgDeal, szAppName, MB_YESNO | MB_ICONQUESTION) ) { NewGame(); } else { SolWnd.EmptyStacks();
fGameStarted = false; } }
TRACE("EXIT SuitStackAddProc()\n");}
//// Double-click on one of the row stacks// The aim is to find a suit-stack to move the// double-clicked card to.//void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked){ TRACE("ENTER RowStackDblClickProc()\n");
SetPlayTimer();
//can only move 1 card at a time if(iNumClicked != 1) { TRACE("EXIT RowStackDblClickProc()\n"); return; }
//find a suit-stack to move the card to... const CardStack &cardstack = stackobj.GetCardStack(); CardRegion *pDest = FindSuitStackFromCard(cardstack[0]);
if(pDest != 0) { fGameStarted = true; SetPlayTimer();
//stackobj.MoveCards(pDest, 1, true); //use the SimulateDrag function, because we get the //AddProc callbacks called for us on the destination stacks... bAutoroute = true; stackobj.SimulateDrag(pDest, 1, true); bAutoroute = false; } TRACE("EXIT RowStackDblClickProc()\n");}
//// Face-up pile single-click//void CARDLIBPROC PileClickProc(CardRegion &stackobj, int iNumClicked){ TRACE("ENTER SuitStackClickProc()\n");
fGameStarted = true;
LastId = stackobj.Id();
TRACE("EXIT SuitStackClickProc()\n");}
//// Face-up pile double-click//void CARDLIBPROC PileDblClickProc(CardRegion &stackobj, int iNumClicked){ TRACE("ENTER PileDblClickProc()\n");
SetPlayTimer();
RowStackDblClickProc(stackobj, iNumClicked); TRACE("EXIT PileDblClickProc()\n");}
//// Fix for the 3-card play when only 1 card left on the pile.//void FixIfOneCardLeft(void){ // If there is just 1 card left, then modify the // stack to contain ALL the face-up cards. The effect // will be, the next time a card is dragged, all the // previous card-triplets will be available underneath. if ((dwOptions & OPTION_THREE_CARDS) && pPile->NumCards() == 1) { pPile->SetOffsets(0, 0); pPile->SetCardStack(activepile); }}
//// What happens when a card is removed from face-up pile?//void CARDLIBPROC PileRemoveProc(CardRegion &stackobj, int iItems){ TRACE("ENTER PileRemoveProc()\n");
SetPlayTimer();
//modify our "virtual" pile by removing the same card //that was removed from the physical card stack activepile.Pop(iItems); if ((dwOptions & OPTION_THREE_CARDS) && (VisiblePileCards > 1)) { --VisiblePileCards; }
FixIfOneCardLeft();
TRACE("EXIT PileRemoveProc()\n");}
//// Double-click on the deck// Move 3 cards to the face-up pile//void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int iNumClicked){ TRACE("ENTER DeckClickProc()\n");
SetPlayTimer();
CardStack cardstack = stackobj.GetCardStack(); CardStack pile = pPile->GetCardStack();
fGameStarted = true; SetPlayTimer();
//reset the face-up pile to represent 3 cards if(dwOptions & OPTION_THREE_CARDS) pPile->SetOffsets(CS_DEFXOFF, 1);
if(cardstack.NumCards() == 0) { if (GetScoreMode() == SCORE_VEGAS) { if (dwWasteCount < dwWasteTreshold) { pile.Clear();
activepile.Reverse(); cardstack.Push(activepile); activepile.Clear(); SetUndo(PILE_ID, DECK_ID, cardstack.NumCards(), lScore, VisiblePileCards); VisiblePileCards = 0; } } else if (GetScoreMode() == SCORE_STD) { SetUndo(PILE_ID, DECK_ID, activepile.NumCards(), lScore, VisiblePileCards); if ((dwWasteCount >= dwWasteTreshold) && (activepile.NumCards() != 0)) { if (dwOptions & OPTION_THREE_CARDS) lScore = lScore >= 20 ? lScore - 20 : 0; else lScore = lScore >= 100 ? lScore - 100 : 0; }
pile.Clear();
activepile.Reverse(); cardstack.Push(activepile); activepile.Clear(); VisiblePileCards = 0;
UpdateStatusBar(); } else { pile.Clear();
activepile.Reverse(); cardstack.Push(activepile); activepile.Clear(); SetUndo(PILE_ID, DECK_ID, cardstack.NumCards(), lScore, VisiblePileCards); VisiblePileCards = 0; }
dwWasteCount++; } else { int numcards = min((dwOptions & OPTION_THREE_CARDS) ? 3 : 1, cardstack.NumCards());
SetUndo(DECK_ID, PILE_ID, numcards, lScore, VisiblePileCards);
//make a "visible" copy of these cards CardStack temp; temp = cardstack.Pop(numcards); temp.Reverse();
if(dwOptions & OPTION_THREE_CARDS) pile.Clear();
pile.Push(temp);
//remove the top 3 from deck activepile.Push(temp);
VisiblePileCards = numcards; }
activepile.Print();
pDeck->SetCardStack(cardstack); pPile->SetCardStack(pile);
FixIfOneCardLeft();
SolWnd.Redraw(); TRACE("EXIT DeckClickProc()\n");}