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