| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /////////////////////////////////////////////////////////////////////////////
- // Name: pile.cpp
- // Purpose: Forty Thieves patience game
- // Author: Chris Breeze
- // Modified by:
- // Created: 21/07/97
- // Copyright: (c) 1993-1998 Chris Breeze
- // Licence: wxWindows licence
- //---------------------------------------------------------------------------
- // Last modified: 22nd July 1998 - ported to wxWidgets 2.0
- /////////////////////////////////////////////////////////////////////////////
- //+-------------------------------------------------------------+
- //| Description: |
- //| The base class for holding piles of playing cards. |
- //+-------------------------------------------------------------+
- // For compilers that support precompilation, includes "wx/wx.h".
- #include "wx/wxprec.h"
- #ifdef __BORLANDC__
- #pragma hdrstop
- #endif
- #ifndef WX_PRECOMP
- #include "wx/wx.h"
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #include <string.h>
- #include "card.h"
- #include "pile.h"
- #include "forty.h"
- #include "canvas.h"
- #include "wx/app.h"
- //+-------------------------------------------------------------+
- //| Pile::Pile() |
- //+-------------------------------------------------------------+
- //| Description: |
- //| Initialise the pile to be empty of cards. |
- //+-------------------------------------------------------------+
- Pile::Pile(int x, int y, int dx, int dy)
- {
- m_x = x;
- m_y = y;
- m_dx = dx;
- m_dy = dy;
- for (m_topCard = 0; m_topCard < NumCards; m_topCard++)
- {
- m_cards[m_topCard] = 0;
- }
- m_topCard = -1; // i.e. empty
- }
- //+-------------------------------------------------------------+
- //| Pile::Redraw() |
- //+-------------------------------------------------------------+
- //| Description: |
- //| Redraw the pile on the screen. If the pile is empty |
- //| just draw a NULL card as a place holder for the pile. |
- //| Otherwise draw the pile from the bottom up, starting |
- //| at the origin of the pile, shifting each subsequent |
- //| card by the pile's x and y offsets. |
- //+-------------------------------------------------------------+
- void Pile::Redraw(wxDC& dc )
- {
- FortyFrame *frame = (FortyFrame*) wxTheApp->GetTopWindow();
- wxWindow *canvas = (wxWindow *) NULL;
- if (frame)
- {
- canvas = frame->GetCanvas();
- }
- if (m_topCard >= 0)
- {
- if (m_dx == 0 && m_dy == 0)
- {
- if ((canvas) && (canvas->IsExposed(m_x,m_y,(int)(Card::GetScale()*60),(int)(Card::GetScale()*200))))
- m_cards[m_topCard]->Draw(dc, m_x, m_y);
- }
- else
- {
- int x = m_x;
- int y = m_y;
- for (int i = 0; i <= m_topCard; i++)
- {
- if ((canvas) && (canvas->IsExposed(x,y,(int)(Card::GetScale()*60),(int)(Card::GetScale()*200))))
- m_cards[i]->Draw(dc, x, y);
- x += (int)Card::GetScale()*m_dx;
- y += (int)Card::GetScale()*m_dy;
- }
- }
- }
- else
- {
- if ((canvas) && (canvas->IsExposed(m_x,m_y,(int)(Card::GetScale()*60),(int)(Card::GetScale()*200))))
- Card::DrawNullCard(dc, m_x, m_y);
- }
- }
- //+-------------------------------------------------------------+
- //| Pile::GetTopCard() |
- //+-------------------------------------------------------------+
- //| Description: |
- //| Return a pointer to the top card in the pile or NULL |
- //| if the pile is empty. |
- //| NB: Gets a copy of the card without removing it from the |
- //| pile. |
- //+-------------------------------------------------------------+
- Card* Pile::GetTopCard()
- {
- Card* card = 0;
- if (m_topCard >= 0)
- {
- card = m_cards[m_topCard];
- }
- return card;
- }
- //+-------------------------------------------------------------+
- //| Pile::RemoveTopCard() |
- //+-------------------------------------------------------------+
- //| Description: |
- //| If the pile is not empty, remove the top card from the |
- //| pile and return the pointer to the removed card. |
- //| If the pile is empty return a NULL pointer. |
- //+-------------------------------------------------------------+
- Card* Pile::RemoveTopCard()
- {
- Card* card = 0;
- if (m_topCard >= 0)
- {
- card = m_cards[m_topCard--];
- }
- return card;
- }
- //+-------------------------------------------------------------+
- //| Pile::RemoveTopCard() |
- //+-------------------------------------------------------------+
- //| Description: |
- //| As RemoveTopCard() but also redraw the top of the pile |
- //| after the card has been removed. |
- //| NB: the offset allows for the redrawn area to be in a |
- //| bitmap ready for 'dragging' cards acrosss the screen. |
- //+-------------------------------------------------------------+
- Card* Pile::RemoveTopCard(wxDC& dc, int xOffset, int yOffset)
- {
- int topX, topY, x, y;
- GetTopCardPos(topX, topY);
- Card* card = RemoveTopCard();
- if (card)
- {
- card->Erase(dc, topX - xOffset, topY - yOffset);
- GetTopCardPos(x, y);
- if (m_topCard < 0)
- {
- Card::DrawNullCard(dc, x - xOffset, y - yOffset);
- }
- else
- {
- m_cards[m_topCard]->Draw(dc, x - xOffset, y - yOffset);
- }
- }
- return card;
- }
- void Pile::GetTopCardPos(int& x, int& y)
- {
- if (m_topCard < 0)
- {
- x = m_x;
- y = m_y;
- }
- else
- {
- x = m_x + (int)Card::GetScale()*m_dx * m_topCard;
- y = m_y + (int)Card::GetScale()*m_dy * m_topCard;
- }
- }
- void Pile::AddCard(Card* card)
- {
- if (m_topCard < -1) m_topCard = -1;
- m_cards[++m_topCard] = card;
- }
- void Pile::AddCard(wxDC& dc, Card* card)
- {
- AddCard(card);
- int x, y;
- GetTopCardPos(x, y);
- card->Draw(dc, x, y);
- }
- // Can the card leave this pile.
- // If it is a member of the pile then the answer is yes.
- // Derived classes may override this behaviour to incorporate
- // the rules of the game
- bool Pile::CanCardLeave(Card* card)
- {
- for (int i = 0; i <= m_topCard; i++)
- {
- if (card == m_cards[i]) return true;
- }
- return false;
- }
- // Calculate how far x, y is from top card in the pile
- // Returns the square of the distance
- int Pile::CalcDistance(int x, int y)
- {
- int cx, cy;
- GetTopCardPos(cx, cy);
- return ((cx - x) * (cx - x) + (cy - y) * (cy - y));
- }
- // Return the card at x, y. Check the top card first, then
- // work down the pile. If a card is found then return a pointer
- // to the card, otherwise return NULL
- Card* Pile::GetCard(int x, int y)
- {
- int cardX;
- int cardY;
- GetTopCardPos(cardX, cardY);
- for (int i = m_topCard; i >= 0; i--)
- {
- if (x >= cardX && x <= cardX + Card::GetWidth() &&
- y >= cardY && y <= cardY + Card::GetHeight())
- {
- return m_cards[i];
- }
- cardX -= (int)Card::GetScale()*m_dx;
- cardY -= (int)Card::GetScale()*m_dy;
- }
- return 0;
- }
- // Return the position of the given card. If it is not a member of this pile
- // return the origin of the pile.
- void Pile::GetCardPos(Card* card, int& x, int& y)
- {
- x = m_x;
- y = m_y;
- for (int i = 0; i <= m_topCard; i++)
- {
- if (card == m_cards[i])
- {
- return;
- }
- x += (int)Card::GetScale()*m_dx;
- y += (int)Card::GetScale()*m_dy;
- }
- // card not found in pile, return origin of pile
- x = m_x;
- y = m_y;
- }
- bool Pile::Overlap(int x, int y)
- {
- int cardX;
- int cardY;
- GetTopCardPos(cardX, cardY);
- if (x >= cardX - Card::GetWidth() && x <= cardX + Card::GetWidth() &&
- y >= cardY - Card::GetHeight() && y <= cardY + Card::GetHeight())
- {
- return true;
- }
- return false;
- }
|