Originally Posted by
crypticgeek
Certainly another way to do it. For convenience sake I was going to store them in a pair<int, int> for passing around and such.
It doesn't make sense to me to be passing around a pair when you can pass around a single char...
Originally Posted by
crypticgeek
It's a toss up really. Do you use one int (really could be a char if we were concerned that much about memory use) and take the processing time to do the mods and divides every time you need to evaluate the card? Or do you use twice as much memory but avoid the computations?
...when was a char only half the size of an int? ...in the days of DOS?
Originally Posted by
crypticgeek
If we were talking about anything larger it might be a genuine debate, but really who cares if you use 52 bytes of memory vs 104 bytes of memory...or if you do a couple of mods and divides or not?
Imagine the additional cycles required for creating pair<int, int> for every value that could more easily be a single char? Compare that with the execution requirements for the mods and division.
Originally Posted by
crypticgeek
Just because I'm lazy, I think I'll store them separately. Seems like kind of a pain to have to calculate out the values everytime you want to use them.
Whose pain? Yours or the processor? Let's say that you have a really incredibly massively slow, 1 MHz PC. How many instructions can it execute in just the time that it takes you to press and release one key on the keyboard? ...even if you were typing 120 WPM? How fast would you have to be able to type to keep up with a 1 GHz PC if you could type a character as fast as it executes a single-cycle instruction? ...or even the most-cycles instruction?
You only need a single char for storage. Who really cares if you use twice as much memory? Anyone who is a worthwhile programmer should care. Besides, two ints is 8 bytes on a 32-bit machine and 16 bytes on a 64-bit machine, a single char is 1 byte whether the machine is 32 or 64 bits. Not exactly twice, huh?
Note that you are NOT creating a "Card" class, even though that has been offered here by others. A Card is not necessarily a Playing Card, which is what is used for Texas Hold'em. A Hallmark birthday card is a kind of card as is any of one of the members of a deck of Old Maid or Pinnocle cards. We should understand the difference and CARE about these important differences.
Here is a very quick hack of a (probably too) simple "PlayingCard" class implementation. Note that I tossed everything into a single file for simplicity and brevity:
Code:
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;
const static char FACE_VALUES[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const static char* FACE_NAMES[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
const static char SUIT_VALUES[] = { 0x10, 0x20, 0x30, 0x40 };
const static char* SUIT_NAMES[] = { "Spades", "Hearts", "Clubs", "Diamonds" };
const static char MIN_CARD_VALUE = 1 | 0x10;
const static char MAX_CARD_VALUE = 13 | 0x40;
class PlayingCard
{
public:
const static char SPADES = 0x10;
const static char HEARTS = 0x20;
const static char CLUBS = 0x30;
const static char DIAMONDS = 0x40;
PlayingCard() : m_value( 0 ){}
PlayingCard( const char value ) : m_value( value ){}
PlayingCard( PlayingCard const& rhs ){ m_value = rhs.m_value; }
const char getValue() const { return m_value; }
void setValue( const char value ){ m_value = validateValue( value ) ? value : m_value; }
std::string toString()
{
std::string value;
if( validateValue( m_value ) )
{
std::string face( FACE_NAMES[ (m_value % 0x10) -1 ] );
std::string suit( SUIT_NAMES[ (m_value / 0x10) -1 ] );
value = face;
value += " ";
value += suit;
}
else
{
value = "Invalid Playing Card!";
}
return value;
}
const char getFaceValue() const { return FACE_VALUES[ (m_value % 0x10) -1 ]; }
const char getSuitValue() const { return SUIT_VALUES[ (m_value / 0x10) -1 ]; }
static char makeValue( const char face, const char suit ) { return validateValue( face | suit ) ? ( face | suit ) : 0; }
private:
char m_value;
static bool validateValue( const char value )
{
bool bIsValid = false;
if( value >= MIN_CARD_VALUE && value <= MAX_CARD_VALUE )
{
bIsValid = true;
}
return bIsValid;
}
};
typedef std::vector<PlayingCard> vPlayingCardDeck;
void spew_deck( vPlayingCardDeck& v )
{
vPlayingCardDeck::iterator it;
for( it = v.begin(); it != v.end(); it++ )
{
cout << (*it).toString() << endl;
}
}
int main()
{
vPlayingCardDeck v;
for( int i = 0x10; i < 0x50; i += 0x10 )
{
for( int j = 1; j < 14; j++ )
{
PlayingCard card( i | j );
v.push_back( card );
}
}
spew_deck( v );
PlayingCard card;
cout << card.toString() << endl;
card.setValue( 12 | PlayingCard::SPADES );
cout << card.toString() << endl;
cout << "\t" << static_cast<int>( card.getFaceValue() ) << endl;
cout << setfill( '0' ) << showbase << hex << internal;
cout << "\t" << static_cast<int>( card.getSuitValue() ) << endl;
card.setValue( PlayingCard::makeValue( 11, PlayingCard::DIAMONDS ) );
cout << card.toString() << endl;
return 0;
}
Output:
Code:
A Spades
2 Spades
3 Spades
4 Spades
5 Spades
6 Spades
7 Spades
8 Spades
9 Spades
10 Spades
J Spades
Q Spades
K Spades
A Hearts
2 Hearts
3 Hearts
4 Hearts
5 Hearts
6 Hearts
7 Hearts
8 Hearts
9 Hearts
10 Hearts
J Hearts
Q Hearts
K Hearts
A Clubs
2 Clubs
3 Clubs
4 Clubs
5 Clubs
6 Clubs
7 Clubs
8 Clubs
9 Clubs
10 Clubs
J Clubs
Q Clubs
K Clubs
A Diamonds
2 Diamonds
3 Diamonds
4 Diamonds
5 Diamonds
6 Diamonds
7 Diamonds
8 Diamonds
9 Diamonds
10 Diamonds
J Diamonds
Q Diamonds
K Diamonds
Invalid Playing Card!
Q Spades
12
0x10
J Diamonds
:davis: