pile.cpp 8.3 KB

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