-#include <windows.h>\r
-#include <commctrl.h>\r
-#include <tchar.h>\r
-#include <stdio.h>\r
-#include "resource.h"\r
-#include "cardlib/cardlib.h"\r
-//#include "../catch22lib/trace.h"\r
-#include "solitaire.h"\r
-\r
-#if 1\r
-#define TRACE(s)\r
-#else\r
-#define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)\r
-#endif\r
-\r
-CardStack activepile;\r
-bool fGameStarted = false;\r
-\r
-void NewGame(void)\r
-{\r
- TRACE("ENTER NewGame()\n");\r
- int i, j;\r
-\r
- SolWnd.EmptyStacks();\r
- \r
- //create a new card-stack\r
- CardStack deck;\r
- deck.NewDeck();\r
- deck.Shuffle();\r
- activepile.Clear();\r
-\r
- //deal to each row stack..\r
- for(i = 0; i < NUM_ROW_STACKS; i++)\r
- {\r
- CardStack temp;\r
- temp.Clear();\r
-\r
- pRowStack[i]->SetFaceDirection(CS_FACE_DOWNUP, i);\r
-\r
- for(j = 0; j <= i; j++)\r
- {\r
- temp.Push(deck.Pop());\r
- }\r
-\r
- pRowStack[i]->SetCardStack(temp);\r
- }\r
-\r
- //put the other cards onto the deck\r
- pDeck->SetCardStack(deck);\r
- pDeck->Update();\r
- \r
- SolWnd.Redraw();\r
-\r
- fGameStarted = false;\r
- TRACE("EXIT NewGame()\n");\r
-}\r
-\r
-//\r
-// Now follow the stack callback functions. This is where we\r
-// provide the game functionality and rules\r
-//\r
-\r
-//\r
-// Can only drag face-up cards\r
-//\r
-bool CARDLIBPROC RowStackDragProc(CardRegion &stackobj, int iNumDragCards)\r
-{\r
- TRACE("ENTER RowStackDragProc()\n");\r
- int numfacedown;\r
- int numcards;\r
-\r
- stackobj.GetFaceDirection(&numfacedown);\r
-\r
- numcards = stackobj.NumCards();\r
-\r
- TRACE("EXIT RowStackDragProc()\n");\r
- if(iNumDragCards <= numcards-numfacedown)\r
- return true;\r
- else\r
- return false;\r
-\r
-}\r
-\r
-//\r
-// Row a row-stack, we can only drop cards \r
-// that are lower / different colour\r
-//\r
-bool CARDLIBPROC RowStackDropProc(CardRegion &stackobj, const CardStack &dragcards)\r
-{\r
- TRACE("ENTER RowStackDropProc()\n");\r
- Card dragcard = dragcards[dragcards.NumCards() - 1];\r
-\r
- //if we are empty, can only drop a stack with a King at bottom\r
- if(stackobj.NumCards() == 0)\r
- {\r
- if(dragcard.LoVal() != 13)\r
- {\r
- TRACE("EXIT RowStackDropProc(false)\n");\r
- return false;\r
- }\r
- }\r
- else\r
- {\r
- const CardStack &mystack = stackobj.GetCardStack();\r
- \r
- //can only drop if card is 1 less\r
- if(mystack[0].LoVal() != dragcard.LoVal() + 1)\r
- {\r
- TRACE("EXIT RowStackDropProc(false)\n");\r
- return false;\r
- }\r
-\r
- //can only drop if card is different colour\r
- if( mystack[0].IsBlack() && !dragcard.IsRed() ||\r
- !mystack[0].IsBlack() && dragcard.IsRed() )\r
- {\r
- TRACE("EXIT RowStackDropProc(false)\n");\r
- return false;\r
- }\r
- }\r
-\r
- TRACE("EXIT RowStackDropProc(true)\n");\r
- return true;\r
-}\r
-\r
-//\r
-// Can only drop a card onto a suit-stack if the\r
-// card is 1 higher, and is the same suit\r
-//\r
-bool CanDrop(CardRegion &stackobj, Card card)\r
-{\r
- TRACE("ENTER CanDrop()\n");\r
- int topval;\r
-\r
- const CardStack &cardstack = stackobj.GetCardStack();\r
-\r
- if(cardstack.NumCards() > 0)\r
- {\r
- if(card.Suit() != cardstack[0].Suit())\r
- {\r
- TRACE("EXIT CanDrop()\n");\r
- return false;\r
- }\r
-\r
- topval = cardstack[0].LoVal();\r
- }\r
- else\r
- {\r
- topval = 0;\r
- }\r
-\r
- //make sure 1 higher\r
- if(card.LoVal() != (topval + 1))\r
- {\r
- TRACE("EXIT CanDrop()\n");\r
- return false;\r
- }\r
-\r
- TRACE("EXIT CanDrop()\n");\r
- return true;\r
-}\r
-\r
-//\r
-// Can only drop a card onto suit stack if it is same suit, and 1 higher\r
-//\r
-bool CARDLIBPROC SuitStackDropProc(CardRegion &stackobj, const CardStack &dragcards)\r
-{\r
- TRACE("ENTER SuitStackDropProc()\n");\r
- //only drop 1 card at a time\r
- if(dragcards.NumCards() != 1)\r
- {\r
- TRACE("EXIT SuitStackDropProc()\n");\r
- return false;\r
- }\r
-\r
- bool b = CanDrop(stackobj, dragcards[0]);\r
- TRACE("EXIT SuitStackDropProc()\n");\r
- return b;\r
-}\r
-\r
-//\r
-// Single-click on one of the row-stacks\r
-// Turn the top-card over if they are all face-down\r
-//\r
-void CARDLIBPROC RowStackClickProc(CardRegion &stackobj, int iNumClicked)\r
-{\r
- TRACE("ENTER RowStackClickProc()\n");\r
- int numfacedown;\r
- \r
- stackobj.GetFaceDirection(&numfacedown);\r
-\r
- //if all face-down, then make top card face-up\r
- if(stackobj.NumCards() == numfacedown)\r
- {\r
- if(numfacedown > 0) numfacedown--;\r
- stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown);\r
- stackobj.Redraw();\r
- }\r
- TRACE("EXIT RowStackClickProc()\n");\r
-}\r
-\r
-//\r
-// Find the suit-stack that can accept the specified card\r
-//\r
-CardRegion *FindSuitStackFromCard(Card card)\r
-{\r
- TRACE("ENTER FindSuitStackFromCard()\n");\r
- for(int i = 0; i < 4; i++)\r
- {\r
- if(CanDrop(*pSuitStack[i], card))\r
- {\r
- TRACE("EXIT FindSuitStackFromCard()\n");\r
- return pSuitStack[i];\r
- }\r
- }\r
-\r
- TRACE("EXIT FindSuitStackFromCard()\n");\r
- return 0;\r
-}\r
-\r
-//\r
-// What happens when we add a card to one of the suit stacks?\r
-// Well, nothing (it is already added), but we need to\r
-// check all four stacks (not just this one) to see if\r
-// the game has finished.\r
-//\r
-void CARDLIBPROC SuitStackAddProc(CardRegion &stackobj, const CardStack &added)\r
-{\r
- TRACE("ENTER SuitStackAddProc()\n");\r
- bool fGameOver = true;\r
-\r
- for(int i = 0; i < 4; i++)\r
- {\r
- if(pSuitStack[i]->NumCards() != 13)\r
- {\r
- fGameOver = false;\r
- break;\r
- }\r
- }\r
-\r
- if(fGameOver)\r
- {\r
- MessageBox(SolWnd, _T("Congratulations, you win!!"), szAppName, MB_OK | MB_ICONINFORMATION);\r
- \r
- for(int i = 0; i < 4; i++)\r
- {\r
- pSuitStack[i]->Flash(11, 100);\r
- }\r
- }\r
- TRACE("EXIT SuitStackAddProc()\n");\r
-}\r
-\r
-//\r
-// Double-click on one of the row stacks\r
-// The aim is to find a suit-stack to move the\r
-// double-clicked card to.\r
-//\r
-void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked)\r
-{\r
- TRACE("ENTER RowStackDblClickProc()\n");\r
- //can only move 1 card at a time\r
- if(iNumClicked != 1)\r
- {\r
- TRACE("EXIT RowStackDblClickProc()\n");\r
- return;\r
- }\r
-\r
- //find a suit-stack to move the card to...\r
- const CardStack &cardstack = stackobj.GetCardStack();\r
- CardRegion *pDest = FindSuitStackFromCard(cardstack[0]);\r
- \r
- if(pDest != 0)\r
- {\r
- //stackobj.MoveCards(pDest, 1, true);\r
- //use the SimulateDrag funcion, because we get the\r
- //AddProc callbacks called for us on the destination stacks...\r
- stackobj.SimulateDrag(pDest, 1, true);\r
- }\r
- TRACE("EXIT RowStackDblClickProc()\n");\r
-}\r
-\r
-//\r
-// Face-up pile double-click\r
-//\r
-void CARDLIBPROC PileDblClickProc(CardRegion &stackobj, int iNumClicked)\r
-{\r
- TRACE("ENTER PileDblClickProc()\n");\r
- RowStackDblClickProc(stackobj, iNumClicked);\r
- TRACE("EXIT PileDblClickProc()\n");\r
-}\r
-\r
-//\r
-// What happens when a card is removed from face-up pile?\r
-//\r
-void CARDLIBPROC PileRemoveProc(CardRegion &stackobj, int iItems)\r
-{\r
- TRACE("ENTER PileRemoveProc()\n");\r
- //modify our "virtual" pile by removing the same card\r
- //that was removed from the physical card stack\r
- activepile.Pop(iItems);\r
-\r
- //if there is just 1 card left, then modify the\r
- //stack to contain ALL the face-up cards..the effect\r
- //will be, the next time a card is dragged, all the\r
- //previous card-triplets will be available underneath\r
- if(stackobj.NumCards() == 1)\r
- {\r
- stackobj.SetOffsets(0,0);\r
- stackobj.SetCardStack(activepile);\r
- }\r
- TRACE("EXIT PileRemoveProc()\n");\r
-}\r
-\r
-//\r
-// Double-click on the deck\r
-// Move 3 cards to the face-up pile\r
-//\r
-void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int iNumClicked)\r
-{\r
- TRACE("ENTER DeckClickProc()\n");\r
- CardStack cardstack = stackobj.GetCardStack();\r
- CardStack pile = pPile->GetCardStack();\r
-\r
- fGameStarted = true;\r
-\r
- //reset the face-up pile to represent 3 cards\r
- pPile->SetOffsets(CS_DEFXOFF, 1);\r
-\r
- if(cardstack.NumCards() == 0)\r
- {\r
- pile.Clear();\r
-\r
- activepile.Reverse();\r
- cardstack.Push(activepile);\r
- activepile.Clear();\r
- }\r
- else\r
- {\r
- int numcards = min(3, cardstack.NumCards());\r
- \r
- //make a "visible" copy of these cards\r
- CardStack temp;\r
- temp = cardstack.Pop(numcards);\r
- temp.Reverse();\r
-\r
- pile.Clear();\r
- pile.Push(temp);\r
-\r
- //remove the top 3 from deck\r
- activepile.Push(temp);\r
- }\r
-\r
- activepile.Print();\r
-\r
- pDeck->SetCardStack(cardstack);\r
- pPile->SetCardStack(pile);\r
-\r
- SolWnd.Redraw();\r
- TRACE("EXIT DeckClickProc()\n");\r
-}\r
+#include <windows.h>
+#include <commctrl.h>
+#include <tchar.h>
+#include <stdio.h>
+#include "resource.h"
+#include "cardlib/cardlib.h"
+//#include "../catch22lib/trace.h"
+#include "solitaire.h"
+
+#if 1
+#define TRACE(s)
+#else
+#define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)
+#endif
+
+CardStack activepile;
+bool fGameStarted = false;
+
+void NewGame(void)
+{
+ TRACE("ENTER NewGame()\n");
+ int i, j;
+
+ SolWnd.EmptyStacks();
+
+ //create a new card-stack
+ CardStack deck;
+ deck.NewDeck();
+ deck.Shuffle();
+ activepile.Clear();
+
+ //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();
+
+ SolWnd.Redraw();
+
+ fGameStarted = false;
+ 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;
+
+ 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, const CardStack &dragcards)
+{
+ TRACE("ENTER RowStackDropProc()\n");
+ Card dragcard = dragcards[dragcards.NumCards() - 1];
+
+ //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;
+ }
+ }
+
+ 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();
+
+ 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, const CardStack &dragcards)
+{
+ TRACE("ENTER SuitStackDropProc()\n");
+ //only drop 1 card at a time
+ if(dragcards.NumCards() != 1)
+ {
+ TRACE("EXIT SuitStackDropProc()\n");
+ return false;
+ }
+
+ bool b = CanDrop(stackobj, dragcards[0]);
+ TRACE("EXIT SuitStackDropProc()\n");
+ return b;
+}
+
+//
+// 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();
+ }
+ 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;
+
+ for(int i = 0; i < 4; i++)
+ {
+ if(pSuitStack[i]->NumCards() != 13)
+ {
+ fGameOver = false;
+ break;
+ }
+ }
+
+ if(fGameOver)
+ {
+ MessageBox(SolWnd, _T("Congratulations, you win!!"), szAppName, MB_OK | MB_ICONINFORMATION);
+
+ for(int i = 0; i < 4; i++)
+ {
+ pSuitStack[i]->Flash(11, 100);
+ }
+ }
+ 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");
+ //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)
+ {
+ //stackobj.MoveCards(pDest, 1, true);
+ //use the SimulateDrag funcion, because we get the
+ //AddProc callbacks called for us on the destination stacks...
+ stackobj.SimulateDrag(pDest, 1, true);
+ }
+ TRACE("EXIT RowStackDblClickProc()\n");
+}
+
+//
+// Face-up pile double-click
+//
+void CARDLIBPROC PileDblClickProc(CardRegion &stackobj, int iNumClicked)
+{
+ TRACE("ENTER PileDblClickProc()\n");
+ RowStackDblClickProc(stackobj, iNumClicked);
+ TRACE("EXIT PileDblClickProc()\n");
+}
+
+//
+// What happens when a card is removed from face-up pile?
+//
+void CARDLIBPROC PileRemoveProc(CardRegion &stackobj, int iItems)
+{
+ TRACE("ENTER PileRemoveProc()\n");
+ //modify our "virtual" pile by removing the same card
+ //that was removed from the physical card stack
+ activepile.Pop(iItems);
+
+ //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(stackobj.NumCards() == 1)
+ {
+ stackobj.SetOffsets(0,0);
+ stackobj.SetCardStack(activepile);
+ }
+ 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");
+ CardStack cardstack = stackobj.GetCardStack();
+ CardStack pile = pPile->GetCardStack();
+
+ fGameStarted = true;
+
+ //reset the face-up pile to represent 3 cards
+ pPile->SetOffsets(CS_DEFXOFF, 1);
+
+ if(cardstack.NumCards() == 0)
+ {
+ pile.Clear();
+
+ activepile.Reverse();
+ cardstack.Push(activepile);
+ activepile.Clear();
+ }
+ else
+ {
+ int numcards = min(3, cardstack.NumCards());
+
+ //make a "visible" copy of these cards
+ CardStack temp;
+ temp = cardstack.Pop(numcards);
+ temp.Reverse();
+
+ pile.Clear();
+ pile.Push(temp);
+
+ //remove the top 3 from deck
+ activepile.Push(temp);
+ }
+
+ activepile.Print();
+
+ pDeck->SetCardStack(cardstack);
+ pPile->SetCardStack(pile);
+
+ SolWnd.Redraw();
+ TRACE("EXIT DeckClickProc()\n");
+}