Sync with trunk.
[reactos.git] / base / applications / games / solitaire / solgame.cpp
index b34dcc8..58ef8e2 100644 (file)
@@ -10,6 +10,7 @@ extern TCHAR MsgWin[128];
 extern TCHAR MsgDeal[128];
 
 CardStack activepile;
+int LastId;
 bool fGameStarted = false;
 
 void NewGame(void)
@@ -17,6 +18,33 @@ 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
@@ -52,7 +80,13 @@ void NewGame(void)
     SolWnd.Redraw();
 
     fGameStarted = false;
+
+    dwPrevMode = GetScoreMode();
+
+    UpdateStatusBar();
+
     TRACE("EXIT NewGame()\n");
+
 }
 
 //
@@ -69,6 +103,8 @@ bool CARDLIBPROC RowStackDragProc(CardRegion &stackobj, int iNumDragCards)
     int numfacedown;
     int numcards;
 
+    SetPlayTimer();
+
     stackobj.GetFaceDirection(&numfacedown);
 
     numcards = stackobj.NumCards();
@@ -90,6 +126,8 @@ 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)
     {
@@ -121,6 +159,27 @@ bool CARDLIBPROC RowStackDropProc(CardRegion &stackobj, CardStack &dragcards)
 
     fGameStarted = true;
 
+    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;
 }
@@ -136,6 +195,8 @@ bool CanDrop(CardRegion &stackobj, Card card)
 
     const CardStack &cardstack = stackobj.GetCardStack();
 
+    SetPlayTimer();
+
     if(cardstack.NumCards() > 0)
     {
         if(card.Suit() != cardstack[0].Suit())
@@ -168,6 +229,9 @@ bool CanDrop(CardRegion &stackobj, Card card)
 bool CARDLIBPROC SuitStackDropProc(CardRegion &stackobj, CardStack &dragcards)
 {
     TRACE("ENTER SuitStackDropProc()\n");
+
+    SetPlayTimer();
+
     //only drop 1 card at a time
     if(dragcards.NumCards() != 1)
     {
@@ -177,9 +241,41 @@ bool CARDLIBPROC SuitStackDropProc(CardRegion &stackobj, CardStack &dragcards)
 
     bool b = CanDrop(stackobj, dragcards[0]);
     TRACE("EXIT SuitStackDropProc()\n");
+
+    if (b)
+    {
+        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
@@ -197,7 +293,18 @@ void CARDLIBPROC RowStackClickProc(CardRegion &stackobj, int iNumClicked)
         if(numfacedown > 0) numfacedown--;
         stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown);
         stackobj.Redraw();
+
+        if (GetScoreMode() == SCORE_STD)
+        {
+            lScore = lScore + 5;
+            UpdateStatusBar();
+        }
     }
+
+    LastId = stackobj.Id();
+
+    fGameStarted = true;
+
     TRACE("EXIT RowStackClickProc()\n");
 }
 
@@ -207,6 +314,7 @@ void CARDLIBPROC RowStackClickProc(CardRegion &stackobj, int iNumClicked)
 CardRegion *FindSuitStackFromCard(Card card)
 {
     TRACE("ENTER FindSuitStackFromCard()\n");
+
     for(int i = 0; i < 4; i++)
     {
         if(CanDrop(*pSuitStack[i], card))
@@ -231,17 +339,30 @@ 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();
+
         MessageBox(SolWnd, MsgWin, szAppName, MB_OK | MB_ICONINFORMATION);
 
         for(int i = 0; i < 4; i++)
@@ -272,6 +393,9 @@ void CARDLIBPROC SuitStackAddProc(CardRegion &stackobj, const CardStack &added)
 void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked)
 {
     TRACE("ENTER RowStackDblClickProc()\n");
+
+    SetPlayTimer();
+
     //can only move 1 card at a time
     if(iNumClicked != 1)
     {
@@ -286,6 +410,7 @@ void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked)
     if(pDest != 0)
     {
         fGameStarted = true;
+        SetPlayTimer();
 
         //stackobj.MoveCards(pDest, 1, true);
         //use the SimulateDrag funcion, because we get the
@@ -295,12 +420,29 @@ void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked)
     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");
 }
@@ -311,6 +453,9 @@ void CARDLIBPROC PileDblClickProc(CardRegion &stackobj, int iNumClicked)
 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);
@@ -334,10 +479,14 @@ void CARDLIBPROC PileRemoveProc(CardRegion &stackobj, int iItems)
 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)
@@ -345,11 +494,45 @@ void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int iNumClicked)
 
     if(cardstack.NumCards() == 0)
     {
-        pile.Clear();
+        if (GetScoreMode() == SCORE_VEGAS)
+        {
+            if (dwWasteCount < dwWasteTreshold)
+            {
+                pile.Clear();
+
+                activepile.Reverse();
+                cardstack.Push(activepile);
+                activepile.Clear();
+            }
+        }
+        else if (GetScoreMode() == SCORE_STD)
+        {
+            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();
+
+            UpdateStatusBar();
+        }
+        else
+        {
+            pile.Clear();
+
+            activepile.Reverse();
+            cardstack.Push(activepile);
+            activepile.Clear();
+        }
 
-        activepile.Reverse();
-        cardstack.Push(activepile);
-        activepile.Clear();
+        dwWasteCount++;
     }
     else
     {