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