// card.cpp -- Implementation of the card class #include #include "boolean.h" #include "card.h" // The default constructor: you can always recognize the // implementation of a constructor by noticing that the class // name is used on both sides of the :: operator. The default // constructor takes no parameters. // // A general note: constructors create an object (instance of // a class), but do not explicitly return a value. // // We need to have some dummy value for the default when // a card object is first created, so let's just arbitrarily // set the default card to be the queen of hearts. card::card() { denom = 12; suit = 'h'; } // Initial-value constructor. The main program may call // this constructor with a particular character abstractly // representing some denomination, and another character // representing the suit. The main program doesn't know // nor care that we implement the denomination as an integer // in the range 2..14. // However, we do assume that the denom_char will be // one character among: A 2 3 4 5 6 7 8 9 T J Q K // The I/O is simpler to implement if we make all the denominations // one character -- this is why we use the letter 'T' for ten. card::card(const char denom_char, const char suit_char) { switch(denom_char) { case 'T' : denom = 10; break; case 'J' : denom = 11; break; case 'Q' : denom = 12; break; case 'K' : denom = 13; break; case 'A' : denom = 14; break; default : denom = denom_char - '0'; } suit = suit_char; } // Copy constructor -- here we copy the parameter c's fields // denom and suit into the corresponding fields of the new object. card::card(const card &c) { denom = c.denom; suit = c.suit; } // Equality operator -- we say that two cards have the same // value if their denominations are the same. Suit does not matter. boolean card::operator == (const card &c) { return denom == c.denom; } // Other comparisons are analogous. boolean card::operator != (const card &c) { return denom != c.denom; } boolean card::operator < (const card &c) { return denom < c.denom; } boolean card::operator > (const card &c) { return denom > c.denom; } boolean card::operator <= (const card &c) { return denom <= c.denom; } boolean card::operator >= (const card &c) { return denom >= c.denom; } // This special operator ^ is being used to tell if two cards have // the same suit -- useful for finding a flush. boolean card::operator ^ (const card &c) { return suit == c.suit; } // Another special operator for cards: the % // We use this to determine if the card on the left of the % // is one denomination higher than the card on the right, // for example an eight and a seven. boolean card::operator % (const card &c) { return denom == c.denom + 1; } boolean card::operator * (const card &c) { return denom == c.denom + 2; } // Our I/O operations are also adapted from what we did with the // string class. But this time we would like to enter and print // both a character and a suit. // Recall that the >> is called the input extractor, // and the << is called the output inserter. // // Note that the >> and << operators are being used as friends // to the istream and ostream classes, so they do not really // belong to the card class, so we don't put "card::" before // the word operator as we did above for == , < and >. // And we also have to specify that denom is a field of c. // This fact has to be made explicit in a friend function. istream& operator >> (istream &is, card &c) { char hyphen; // We're going to discard the hyphen // between the denom and suit. char denom_char; is >> denom_char >> hyphen >> c.suit; switch(denom_char) { case 'T' : c.denom = 10; break; case 'J' : c.denom = 11; break; case 'Q' : c.denom = 12; break; case 'K' : c.denom = 13; break; case 'A' : c.denom = 14; break; default : c.denom = denom_char - '0'; } return is; } ostream& operator << (ostream &os, const card &c) { char denom_char; switch (c.denom) { case 10: denom_char = 'T'; break; case 11: denom_char = 'J'; break; case 12: denom_char = 'Q'; break; case 13: denom_char = 'K'; break; case 14: denom_char = 'A'; break; default: denom_char = c.denom + '0'; } os << denom_char << '-' << c.suit; return os; } void card::name() { switch(denom) { case 2 : cout << "two of "; break; case 3 : cout << "three of "; break; case 4 : cout << "four of "; break; case 5 : cout << "five of "; break; case 6 : cout << "six of "; break; case 7 : cout << "seven of "; break; case 8 : cout << "eight of "; break; case 9 : cout << "nine of "; break; case 10: cout << "ten of "; break; case 11: cout << "jack of "; break; case 12: cout << "queen of "; break; case 13: cout << "king of "; break; case 14: cout << "ace of "; break; } switch(suit) { case 'c': cout << "clubs"; break; case 'd': cout << "diamonds"; break; case 'h': cout << "hearts"; break; case 's': cout << "spades"; break; } }