ReactOS  0.4.11-dev-765-g5e024bf
spigame.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: Spider Solitaire
3  * LICENSE: See COPYING in top level directory
4  * FILE: base/applications/games/spider/spigame.cpp
5  * PURPOSE: Spider Solitaire game functions
6  * PROGRAMMER: Gregor Schneider
7  */
8 
9 #include "spider.h"
10 
11 #define NUM_DECK_CARDS 5
12 #define NUM_SMALLER_STACKS 4
13 #define NUM_CARD_COLORS 4
14 #define NUM_ONECOLOR_CARDS 13
15 #define NUM_STD_CARDS 52
16 #define NUM_SPIDER_CARDS 104
17 
22 bool fGameStarted = false;
25 extern TCHAR MsgDeal[];
26 extern TCHAR MsgWin[];
27 
29 {
30  CardStack newStack;
31  int i, colors = 1, num = 0;
32 
33  switch (dwDifficulty)
34  {
35  case IDC_DIF_ONECOLOR:
36  colors = 1;
37  break;
38  case IDC_DIF_TWOCOLORS:
39  colors = 2;
40  break;
41  case IDC_DIF_FOURCOLORS:
42  colors = 4;
43  break;
44  }
45  for (i = 0; i < NUM_SPIDER_CARDS; i++)
46  {
47  num += NUM_CARD_COLORS / colors;
48  Card newCard(num % NUM_STD_CARDS);
49  newStack.Push(newCard);
50  }
51  return newStack;
52 }
53 
54 void NewGame(void)
55 {
56  int i, j;
57  /* First four stack with five, all other with 4 */
58  int covCards = 5;
59  CardStack fakeDeck, temp;
60 
62 
63  /* Create a new card-deck, fake deck */
64  deck = CreatePlayDeck();
65  deck.Shuffle();
66  fakeDeck.NewDeck();
67  fakeDeck.Shuffle();
68 
69  /* Reset progress value */
70  cardsFinished = 0;
71 
72  /* Deal to each stack */
73  for (i = 0; i < NUM_STACKS; i++)
74  {
75  temp.Clear();
76  if (i == NUM_SMALLER_STACKS)
77  {
78  covCards--;
79  }
80  for (j = 0; j <= covCards; j++)
81  {
82  temp.Push(deck.Pop(1));
83  }
84  pStack[i]->SetFaceDirection(CS_FACE_DOWNUP, covCards);
85  pStack[i]->SetCardStack(temp);
86  }
87  /* Deal five fake cards to the deck */
88  pDeck->SetCardStack(fakeDeck.Pop(5));
89 
90  SpiderWnd.Redraw();
91  fGameStarted = false;
92 }
93 
94 bool stackLookingGood(const CardStack &mystack, int numChecks)
95 {
96  int i;
97  for (i = 0; i < numChecks; i++)
98  {
99  if (mystack[i].LoVal() != mystack[i + 1].LoVal() - 1)
100  {
101  return false;
102  }
103  if (mystack[i].Suit() != mystack[i + 1].Suit())
104  {
105  return false;
106  }
107  }
108  return true;
109 }
110 
111 /* Card to be turned from a stack */
112 void TurnStackCard(CardRegion &stackobj)
113 {
114  int numfacedown;
115 
116  stackobj.GetFaceDirection(&numfacedown);
117  if (stackobj.NumCards() <= numfacedown)
118  {
119  if (numfacedown > 0) numfacedown--;
120  stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown);
121  stackobj.Redraw();
122  }
123 }
124 
125 /* Click on the deck */
126 void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int NumDragCards)
127 {
128  CardStack temp, fakeDeck = pDeck->GetCardStack();
129  fGameStarted = true;
130 
131  if (fakeDeck.NumCards() != 0 && deck.NumCards() != 0)
132  {
133  int i, facedown, faceup;
134  /* Add one card to every stack */
135  for (i = 0; i < NUM_STACKS; i++)
136  {
137  temp = pStack[i]->GetCardStack();
138  temp.Push(deck.Pop());
139 
140  /* Check if we accidentally finished a row */
141  pStack[i]->GetFaceDirection(&facedown);
142  faceup = temp.NumCards() - facedown;
143  if (faceup >= NUM_ONECOLOR_CARDS)
144  {
145  /* Check stack finished, remove cards if so */
146  if (stackLookingGood(temp, NUM_ONECOLOR_CARDS - 1))
147  {
148  int j;
149  for (j = 0; j < NUM_ONECOLOR_CARDS; j++)
150  {
151  temp.RemoveCard(0);
152  }
154  pStack[i]->SetCardStack(temp);
155  /* Turn now topmost card */
156  TurnStackCard(*pStack[i]);
157  }
158  }
159  pStack[i]->SetCardStack(temp);
160  }
161  /* Remove one card from the fake ones */
162  pDeck->SetCardStack(fakeDeck.Pop(fakeDeck.NumCards() - 1));
163  }
164  pDeck->Update();
165  SpiderWnd.Redraw();
166 }
167 
168 /* Cards dragged from a stack */
169 bool CARDLIBPROC StackDragProc(CardRegion &stackobj, int numDragCards)
170 {
171  int numfacedown, numcards;
172 
173  stackobj.GetFaceDirection(&numfacedown);
174  numcards = stackobj.NumCards();
175 
176  /* Only cards facing up */
177  if (numDragCards <= numcards - numfacedown)
178  {
179  const CardStack &mystack = stackobj.GetCardStack();
180  /* Don't allow to drag unsuited cards */
181  if (!stackLookingGood(mystack, numDragCards - 1))
182  {
183  return false;
184  }
185  /* Remember where the cards come from */
186  from = &stackobj;
187  return true;
188  }
189  else
190  {
191  return false;
192  }
193 }
194 
195 /* Game finished successfully */
197 {
199 
202  {
203  NewGame();
204  }
205  else
206  {
207  fGameStarted = false;
208  }
209 }
210 
211 /* Card added, check for win situation */
212 void CARDLIBPROC StackAddProc(CardRegion &stackobj, const CardStack &added)
213 {
215  {
216  GameFinished();
217  }
218 }
219 
220 /* Cards dropped to a stack */
221 bool CARDLIBPROC StackDropProc(CardRegion &stackobj, CardStack &dragcards)
222 {
223  Card dragcard = dragcards[dragcards.NumCards() - 1];
224  int faceup, facedown;
225 
226  /* Only drop our cards on other stacks */
227  if (stackobj.Id() == from->Id())
228  {
229  return false;
230  }
231 
232  /* If stack is empty, everything can be dropped */
233  if (stackobj.NumCards() != 0)
234  {
235  const CardStack &mystack = stackobj.GetCardStack();
236 
237  /* Can only drop if card is 1 less */
238  if (mystack[0].LoVal() != dragcard.LoVal() + 1)
239  {
240  return false;
241  }
242 
243  /* Check if stack complete */
244  stackobj.GetFaceDirection(&facedown);
245  faceup = stackobj.NumCards() - facedown;
246 
247  if (faceup + dragcards.NumCards() >= NUM_ONECOLOR_CARDS)
248  {
249  int i, max = NUM_ONECOLOR_CARDS - dragcards.NumCards() - 1;
250 
251  /* Dragged cards have been checked to be in order, check stack cards */
252  if (mystack[0].Suit() == dragcard.Suit() &&
253  stackLookingGood(mystack, max))
254  {
255  CardStack s = stackobj.GetCardStack();
256  CardStack f;
257 
258  /* Remove from card stack */
259  for (i = 0; i < max + 1; i++)
260  {
261  s.RemoveCard(0);
262  }
263  /* Remove dragged cards */
264  dragcards = f;
265  stackobj.SetCardStack(s);
267  /* Flip top card of the dest stack */
268  TurnStackCard(stackobj);
269  }
270  }
271  }
272  /* Flip the top card of the source stack */
273  TurnStackCard(*from);
274  fGameStarted = true;
275  return true;
276 }
277 
278 /* Create card regions */
280 {
281  int i, pos;
282 
283  /* Compute the value for yRowStackCardOffset based on the height of the card, so the card number and suite isn't hidden on larger cards except Ace */
285 
286  pDeck = SpiderWnd.CreateRegion(0, true, 0, 0, -15, 0);
287  pDeck->SetFaceDirection(CS_FACE_DOWN, 0);
288  pDeck->SetEmptyImage(CS_EI_CIRC);
290  pDeck->SetDragRule(CS_DRAG_NONE, 0);
291  pDeck->SetDropRule(CS_DROP_NONE, 0);
293 
294  /* Create the row stacks */
295  for (i = 0; i < NUM_STACKS; i++)
296  {
297  pStack[i] = SpiderWnd.CreateRegion(NUM_STACKS+i, true, 0, Y_BORDER, 0, yRowStackCardOffset);
298  pStack[i]->SetFaceDirection(CS_FACE_DOWN, 0);
299  pos = i - NUM_STACKS/2;
300  pStack[i]->SetPlacement(CS_XJUST_CENTER, 0,
301  pos * (__cardwidth + X_BORDER) + 6 * (X_BORDER + 1) + 3, 0);
302  pStack[i]->SetEmptyImage(CS_EI_SUNK);
305  pStack[i]->SetAddCardProc(StackAddProc);
306  }
307 }
308 
#define Y_BORDER
Definition: solitaire.h:53
#define max(a, b)
Definition: svc.c:63
void NewGame(void)
Definition: spigame.cpp:54
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
void SetFaceDirection(UINT uDirType, int nOption)
Definition: cardregion.cpp:258
CardRegion * pDeck
Definition: spigame.cpp:20
CardWindow SpiderWnd
Definition: spider.cpp:27
#define IDYES
Definition: winuser.h:829
#define X_BORDER
Definition: solitaire.h:49
#define NUM_SMALLER_STACKS
Definition: spigame.cpp:12
const CardStack & GetCardStack()
Definition: cardregion.cpp:399
void SetClickReleaseProc(pClickProc proc)
Definition: cardregion.cpp:187
#define CS_XJUST_RIGHT
Definition: cardlib.h:38
void EmptyStacks(void)
Definition: cardwindow.cpp:607
int NumCards() const
Definition: cardregion.cpp:544
#define CS_DRAG_NONE
Definition: cardlib.h:28
#define CS_DRAG_CALLBACK
Definition: cardlib.h:31
#define CS_EI_SUNK
Definition: cardlib.h:19
void Clear()
Definition: cardstack.cpp:37
void Push(const Card card)
Definition: cardstack.cpp:83
void SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)
Definition: cardregion.cpp:250
Card RemoveCard(size_t index)
Definition: cardstack.cpp:172
void TurnStackCard(CardRegion &stackobj)
Definition: spigame.cpp:112
int cardsFinished
Definition: spigame.cpp:24
void CARDLIBPROC StackAddProc(CardRegion &stackobj, const CardStack &added)
Definition: spigame.cpp:212
void Redraw()
int Suit() const
Definition: card.h:54
CardStack CreatePlayDeck()
Definition: spigame.cpp:28
void Redraw(void)
Definition: cardwindow.cpp:553
void SetEmptyImage(UINT uImage)
Definition: cardregion.cpp:366
void NewDeck()
Definition: cardstack.cpp:42
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define CS_EI_CIRC
Definition: cardlib.h:20
#define NUM_SPIDER_CARDS
Definition: spigame.cpp:16
#define MB_YESNO
Definition: winuser.h:811
void Update()
Definition: cardregion.cpp:207
TCHAR MsgWin[]
Definition: solitaire.cpp:21
bool CARDLIBPROC StackDragProc(CardRegion &stackobj, int numDragCards)
Definition: spigame.cpp:169
#define MB_ICONQUESTION
Definition: winuser.h:783
bool SetDragRule(UINT uDragType, pCanDragProc proc=0)
Definition: cardregion.cpp:146
#define NUM_CARD_COLORS
Definition: spigame.cpp:13
#define CS_XJUST_CENTER
Definition: cardlib.h:39
void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int NumDragCards)
Definition: spigame.cpp:126
#define NUM_STD_CARDS
Definition: spigame.cpp:15
char TCHAR
Definition: xmlstorage.h:189
#define CS_FACE_DOWN
Definition: cardlib.h:52
int NumCards() const
Definition: cardstack.h:14
void Shuffle()
Definition: cardstack.cpp:50
#define CS_DROP_NONE
Definition: cardlib.h:33
void CreateSpider()
Definition: spigame.cpp:279
CardRegion * CreateRegion(int id, bool fVisible, int x, int y, int xoffset, int yoffset)
Definition: cardregion.cpp:104
bool CARDLIBPROC StackDropProc(CardRegion &stackobj, CardStack &dragcards)
Definition: spigame.cpp:221
Card Pop()
Definition: cardstack.cpp:127
GLuint GLuint num
Definition: glext.h:9618
#define MB_ICONINFORMATION
Definition: winuser.h:796
GLdouble s
Definition: gl.h:2039
#define MessageBox
Definition: winuser.h:5688
static stack_node_t temp
Definition: rpn.c:18
DWORD dwDifficulty
Definition: spider.cpp:25
void SetCardStack(const CardStack &cs)
Definition: cardregion.cpp:390
int __cardwidth
Definition: cardlib.cpp:25
TCHAR szAppName[128]
Definition: solitaire.cpp:16
#define IDC_DIF_ONECOLOR
Definition: resource.h:32
Definition: card.h:27
#define CS_DROP_CALLBACK
Definition: cardlib.h:35
#define CS_YJUST_BOTTOM
Definition: cardlib.h:42
#define IDC_DIF_TWOCOLORS
Definition: resource.h:33
#define f
Definition: ke_i.h:83
bool fGameStarted
Definition: spigame.cpp:22
TCHAR MsgDeal[]
Definition: solitaire.cpp:22
int yRowStackCardOffset
Definition: spigame.cpp:23
#define CS_FACE_DOWNUP
Definition: cardlib.h:53
CardStack deck
Definition: spigame.cpp:18
CardRegion * pStack[NUM_STACKS]
Definition: spigame.cpp:21
#define MB_OK
Definition: winuser.h:784
void SetAddCardProc(pAddProc proc)
Definition: cardregion.cpp:197
int LoVal() const
Definition: card.h:59
bool SetDropRule(UINT uDropType, pCanDropProc proc=0)
Definition: cardregion.cpp:164
int __cardheight
Definition: cardlib.cpp:26
bool stackLookingGood(const CardStack &mystack, int numChecks)
Definition: spigame.cpp:94
#define CARDLIBPROC
Definition: cardlib.h:13
UINT GetFaceDirection(int *pnOption)
Definition: cardregion.cpp:273
#define IDC_DIF_FOURCOLORS
Definition: resource.h:34
#define NUM_STACKS
Definition: spider.h:21
#define NUM_ONECOLOR_CARDS
Definition: spigame.cpp:14
CardRegion * from
Definition: spigame.cpp:19
void GameFinished()
Definition: spigame.cpp:196
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29