]> git.saurik.com Git - wxWidgets.git/blob - samples/forty/pile.cpp
Corrected some problems
[wxWidgets.git] / samples / forty / pile.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: pile.cpp
3 // Purpose: Forty Thieves patience game
4 // Author: Chris Breeze
5 // Modified by:
6 // Created: 21/07/97
7 // RCS-ID: $Id$
8 // Copyright: (c) 1993-1998 Chris Breeze
9 // Licence: wxWindows licence
10 //---------------------------------------------------------------------------
11 // Last modified: 22nd July 1998 - ported to wxWindows 2.0
12 /////////////////////////////////////////////////////////////////////////////
13 //+-------------------------------------------------------------+
14 //| Description: |
15 //| The base class for holding piles of playing cards. |
16 //+-------------------------------------------------------------+
17
18 #ifdef __GNUG__
19 #pragma implementation
20 #pragma interface
21 #endif
22
23 // For compilers that support precompilation, includes "wx/wx.h".
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #ifndef WX_PRECOMP
31 #include "wx/wx.h"
32 #endif
33 #ifdef __GNUG__
34 #pragma implementation
35 #endif
36
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <time.h>
40 #include <string.h>
41 #include "card.h"
42 #include "pile.h"
43
44
45 //+-------------------------------------------------------------+
46 //| Pile::Pile() |
47 //+-------------------------------------------------------------+
48 //| Description: |
49 //| Initialise the pile to be empty of cards. |
50 //+-------------------------------------------------------------+
51 Pile::Pile(int x, int y, int dx, int dy)
52 {
53 m_x = x;
54 m_y = y;
55 m_dx = dx;
56 m_dy = dy;
57 for (m_topCard = 0; m_topCard < NumCards; m_topCard++)
58 {
59 m_cards[m_topCard] = 0;
60 }
61 m_topCard = -1; // i.e. empty
62 }
63
64
65 //+-------------------------------------------------------------+
66 //| Pile::Redraw() |
67 //+-------------------------------------------------------------+
68 //| Description: |
69 //| Redraw the pile on the screen. If the pile is empty |
70 //| just draw a NULL card as a place holder for the pile. |
71 //| Otherwise draw the pile from the bottom up, starting |
72 //| at the origin of the pile, shifting each subsequent |
73 //| card by the pile's x and y offsets. |
74 //+-------------------------------------------------------------+
75 void Pile::Redraw(wxDC& dc)
76 {
77 if (m_topCard >= 0)
78 {
79 if (m_dx == 0 && m_dy == 0)
80 {
81 m_cards[m_topCard]->Draw(dc, m_x, m_y);
82 }
83 else
84 {
85 int x = m_x;
86 int y = m_y;
87 for (int i = 0; i <= m_topCard; i++)
88 {
89 m_cards[i]->Draw(dc, x, y);
90 x += m_dx;
91 y += m_dy;
92 }
93 }
94 }
95 else
96 {
97 Card::DrawNullCard(dc, m_x, m_y);
98 }
99 }
100
101
102 //+-------------------------------------------------------------+
103 //| Pile::GetTopCard() |
104 //+-------------------------------------------------------------+
105 //| Description: |
106 //| Return a pointer to the top card in the pile or NULL |
107 //| if the pile is empty. |
108 //| NB: Gets a copy of the card without removing it from the |
109 //| pile. |
110 //+-------------------------------------------------------------+
111 Card* Pile::GetTopCard()
112 {
113 Card* card = 0;
114
115 if (m_topCard >= 0)
116 {
117 card = m_cards[m_topCard];
118 }
119 return card;
120 }
121
122
123 //+-------------------------------------------------------------+
124 //| Pile::RemoveTopCard() |
125 //+-------------------------------------------------------------+
126 //| Description: |
127 //| If the pile is not empty, remove the top card from the |
128 //| pile and return the pointer to the removed card. |
129 //| If the pile is empty return a NULL pointer. |
130 //+-------------------------------------------------------------+
131 Card* Pile::RemoveTopCard()
132 {
133 Card* card = 0;
134
135 if (m_topCard >= 0)
136 {
137 card = m_cards[m_topCard--];
138 }
139 return card;
140 }
141
142
143 //+-------------------------------------------------------------+
144 //| Pile::RemoveTopCard() |
145 //+-------------------------------------------------------------+
146 //| Description: |
147 //| As RemoveTopCard() but also redraw the top of the pile |
148 //| after the card has been removed. |
149 //| NB: the offset allows for the redrawn area to be in a |
150 //| bitmap ready for 'dragging' cards acrosss the screen. |
151 //+-------------------------------------------------------------+
152 Card* Pile::RemoveTopCard(wxDC& dc, int xOffset, int yOffset)
153 {
154 int topX, topY, x, y;
155
156 GetTopCardPos(topX, topY);
157 Card* card = RemoveTopCard();
158
159 if (card)
160 {
161 card->Erase(dc, topX - xOffset, topY - yOffset);
162 GetTopCardPos(x, y);
163 if (m_topCard < 0)
164 {
165 Card::DrawNullCard(dc, x - xOffset, y - yOffset);
166 }
167 else
168 {
169 m_cards[m_topCard]->Draw(dc, x - xOffset, y - yOffset);
170 }
171 }
172
173 return card;
174 }
175
176
177 void Pile::GetTopCardPos(int& x, int& y)
178 {
179 if (m_topCard < 0)
180 {
181 x = m_x;
182 y = m_y;
183 }
184 else
185 {
186 x = m_x + m_dx * m_topCard;
187 y = m_y + m_dy * m_topCard;
188 }
189 }
190
191 void Pile::AddCard(Card* card)
192 {
193 if (m_topCard < -1) m_topCard = -1;
194
195 m_cards[++m_topCard] = card;
196 }
197
198 void Pile::AddCard(wxDC& dc, Card* card)
199 {
200 AddCard(card);
201 int x, y;
202 GetTopCardPos(x, y);
203 card->Draw(dc, x, y);
204 }
205
206 // Can the card leave this pile.
207 // If it is a member of the pile then the answer is yes.
208 // Derived classes may override this behaviour to incorporate
209 // the rules of the game
210 bool Pile::CanCardLeave(Card* card)
211 {
212 for (int i = 0; i <= m_topCard; i++)
213 {
214 if (card == m_cards[i]) return TRUE;
215 }
216 return FALSE;
217 }
218
219 // Calculate how far x, y is from top card in the pile
220 // Returns the square of the distance
221 int Pile::CalcDistance(int x, int y)
222 {
223 int cx, cy;
224 GetTopCardPos(cx, cy);
225 return ((cx - x) * (cx - x) + (cy - y) * (cy - y));
226 }
227
228
229 // Return the card at x, y. Check the top card first, then
230 // work down the pile. If a card is found then return a pointer
231 // to the card, otherwise return NULL
232 Card* Pile::GetCard(int x, int y)
233 {
234 int cardX;
235 int cardY;
236 GetTopCardPos(cardX, cardY);
237
238 for (int i = m_topCard; i >= 0; i--)
239 {
240 if (x >= cardX && x <= cardX + CardWidth &&
241 y >= cardY && y <= cardY + CardHeight)
242 {
243 return m_cards[i];
244 }
245 cardX -= m_dx;
246 cardY -= m_dy;
247 }
248 return 0;
249 }
250
251
252 // Return the position of the given card. If it is not a member of this pile
253 // return the origin of the pile.
254 void Pile::GetCardPos(Card* card, int& x, int& y)
255 {
256 x = m_x;
257 y = m_y;
258
259 for (int i = 0; i <= m_topCard; i++)
260 {
261 if (card == m_cards[i])
262 {
263 return;
264 }
265 x += m_dx;
266 y += m_dy;
267 }
268
269 // card not found in pile, return origin of pile
270 x = m_x;
271 y = m_y;
272 }
273
274
275 bool Pile::Overlap(int x, int y)
276 {
277 int cardX;
278 int cardY;
279 GetTopCardPos(cardX, cardY);
280
281 if (x >= cardX - CardWidth && x <= cardX + CardWidth &&
282 y >= cardY - CardHeight && y <= cardY + CardHeight)
283 {
284 return TRUE;
285 }
286 return FALSE;
287 }
288
289
290 Pile::~Pile()
291 {
292 // nothing special at the moment
293 }