///////////////////////////////////////////////////////////////////////////// // Name: cards.cpp // tag: classes to deal with stacks and stuff of cards // Author: Chris Breeze // Modified by: David Roundy // Created: 21/07/97 // Copyright: (c) 1993-1998 Chris Breeze, 2001,2002 David Roundy // Licence: GPL /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes . #include #ifndef WX_PRECOMP #include #endif #include #include #include #include #include "colors.h" #include "cards.h" #include "gameevent.h" const double root2 = 1.41421356237309504880168; BEGIN_EVENT_TABLE(Hand, wxControl) EVT_SIZE (Hand::HandleResize) EVT_LEFT_DOWN(Hand::OnClick) EVT_PAINT (Hand::DoPaint) END_EVENT_TABLE() //---------------------------------------// // The Hand class: holds cards in a hand // //---------------------------------------// Hand::Hand(int is_vertical, wxWindow* parent, const wxPoint& pos, const wxSize& size) : wxControl(parent,-1,pos, (size==wxDefaultSize)?((is_vertical)?wxSize(50,300):wxSize(295,73)) :size) { SetBackgroundColour(aBridgeBackgroundColour()); the_cards = NULL; m_vertical = is_vertical; } wxString Hand::GetString(const wxString &sep, const wxString &end) { Card *p = the_cards; wxString handstring = ""; while (p) { handstring << p->GetString(); if (p->next) handstring << sep; p = p->next; } handstring << end; return handstring; } void Hand::PlayCard(const Card &card) { // Remove card if (the_cards && (*the_cards == card || the_cards->IsFaceDown())) { Card *old = the_cards; the_cards = the_cards->next; old->next = NULL; delete old; } else { Card *p = the_cards; while (p) { if (p->next && *(p->next) == card) { Card *old = p->next; p->next = p->next->next; old->next = NULL; delete old; return; } p = p->next; } } wxSizeEvent dummy; HandleResize(dummy); } int Hand::GetNumCards() const { Card *p = the_cards; int numcards = 0; while (p) { numcards++; p = p->next; } return numcards; } void Hand::TurnCards(WayUp wayup) { Card *p = the_cards; while (p) { p->TurnCard(wayup); p = p->next; } Refresh(); } static inline int pt_in_rect(const wxPoint &p, const wxRect &r) { return p.x > r.GetLeft() && p.x < r.GetRight() && p.y > r.GetTop() && p.y < r.GetBottom(); } void Hand::OnClick(wxMouseEvent& event) { Card *p = the_cards; Card *clicked_card = NULL; wxPoint mp = event.GetPosition(); int x,y,dx,dy,w,h; GetDeltaSize(&x, &y, &dx, &dy, &w, &h); while (p) { if (pt_in_rect(mp, wxRect(x,y,w,h)) && !clicked_card) clicked_card = p; x += dx; y += dy; p = p->next; } event.m_altDown = true; if (clicked_card) { GameEvent my_event( this, "CARDCLICKED", clicked_card->GetString()); Command(my_event); } } wxSize Hand::GetBestSize() const { if (m_vertical) { return wxSize(50, (int) (73*(1+0.2*12))); } else { return wxSize((int) (50*(1+0.3*12)), 73); } } static inline Card *get_nth_card(Card *p, int n) { while (n>0 && p) { n--; p = p->next; } return p; } void Hand::DoPaint(wxPaintEvent& event) { wxPaintDC dc(this); int x,y,dx,dy,w,h; GetDeltaSize(&x, &y, &dx, &dy, &w, &h); int numcards = GetNumCards(); x += (numcards-1)*dx; y += (numcards-1)*dy; for (int i=numcards-1;i>=0;i--) { get_nth_card(the_cards,i)->Draw(dc,x,y,w,h); x -= dx; y -= dy; } } void Hand::GetDeltaSize(int *x, int *y, int *dx, int *dy, int *w, int *h) const { if (the_cards) { int width, height; GetClientSize(&width, &height); int numcards = GetNumCards(); if (width > height) { int cardwidth = (int) (height/root2 + 0.5); int delta = 0; if (numcards>1) delta = -(width - cardwidth)/(numcards-1); if (abs(delta) > cardwidth/3+1) delta = -cardwidth/3-1; int xloc = (width - cardwidth)/2 - delta*(numcards-1)/2; *x = xloc; *y = 0; *dx = delta; *dy = 0; *w = cardwidth; *h = height; } else { int cardheight = (int) (width*root2 + 0.5); int delta = 0; if (numcards>1) delta = -(height - cardheight)/(numcards-1); if (abs(delta) > cardheight/3+1) delta = -cardheight/3-1; int yloc = (height - cardheight)/2 - delta*(numcards-1)/2; *x = 0; *y = yloc; *dx = 0; *dy = delta; *w = width; *h = cardheight; } } else { *x = *y = *dx = *dy = 0; *w = *h = 50; } } void Hand::HandleResize(wxSizeEvent& event) { Refresh(); } void Hand::ResetHand() { delete the_cards; the_cards = NULL; Refresh(); } void Hand::AddCard(const Card &card) { Card *my_copy = new Card(card); my_copy->next = the_cards; the_cards = my_copy; Card *p = the_cards; while (p && p->next) { if (*p > *(p->next)) { Card tmp; tmp.SetSameAs(*p); p->SetSameAs(*p->next); p->next->SetSameAs(tmp); } p = p->next; } wxSizeEvent tmp; } bool Hand::HasCard(const Card &card) const { Card *p = the_cards; while (p) { if (*p == card) return true; p = p->next; } return false; } bool Hand::HasSuit(Suit suit) const { Card *p = the_cards; while (p) { if (p->GetSuit() == suit) return true; p = p->next; } return false; } Hand::~Hand() { }