33
Hand
- #if !defined( _HAND_H )
- #define _HAND_H
- #include <assert.h>
- #include "Card.h"
- #include "debug.h"
- enum hand
- {
- NOTHING, ONEPAIR, TWOPAIRS, THREEOFKIND, STRAIGHT, FLUSH, FULLHOUSE, FOUROFKIND, STRAIGHTFLUSH
- };
- class Hand
- {
- public:
- ~Hand( )
- {
- ONDEBUG9( cout << "\t~Hand( )\n"; );
- delete [] _cards;
- }
- Hand( unsigned n=5, Card *s=0 ) : _size( n )
- {
- ONDEBUG8( cout << "\tHand( unsigned=" << n << ", Cards *s=0x" << s << " )\n"; );
- _cards = new Card[ n ];
- if ( s != 0 )
- for ( int i = 0; i < n; i++ )
- _cards[ i ] = s[ i ];
- }
- Card &operator[]( int i )
- {
- assert( i < _size );
- return _cards[ i ];
- }
- unsigned size( ) { return _size; }
- void print( bool =false );
- hand eval();
- void reorder();
- private:
- unsigned _size;
- Card *_cards;
- bool isOnePair();
- bool isTwoPairs();
- bool isThreeOfKind();
- bool isStraight();
- bool isFlush();
- bool isFullHouse();
- bool isFourOfKind();
- bool isStraightFlush();
- };
- #endif
- #include "Hand.h"
- #include <iostream>
- #include <assert.h>
- void Hand::print( bool full )
- {
- static const char* hand_text[ ] =
- {
- " NOTHING ",
- " ONEPAIR ",
- " TWOPAIRS ",
- " THREEOFKIND ",
- " STRAIGHT ",
- " FLUSH ",
- " FULLHOUSE ",
- " FOUROFKIND ",
- " STRAIGHTFLUSH "
- };
- cout << "<<";
- for ( int i = 0; i < _size; i++ )
- std::cout << " " << _cards[ i ];
- cout << " >>\n";
- if ( full )
- cout << ">>" << hand_text[ eval() ] << "<<\n";
- }
- bool Hand::isOnePair( )
- { // aabcd abbcd abccd abcdd
- rank r1 = _cards[ 0 ]._rank;
- rank r2 = _cards[ 1 ]._rank;
- rank r3 = _cards[ 2 ]._rank;
- rank r4 = _cards[ 3 ]._rank;
- rank r5 = _cards[ 4 ]._rank;
- if (r1 == r2 && r2 != r3 && r3 != r4 && r4 != r5)
- return true;
- if (r1 != r2 && r2 == r3 && r3 != r4 && r4 != r5)
- return true;
- if (r1 != r2 && r2 != r3 && r3 == r4 && r4 != r5)
- return true;
- if (r1 != r2 && r2 != r3 && r3 != r4 && r4 == r5)
- return true;
- return false;
- }
- bool Hand::isTwoPairs( )
- { // aabbc aabcc abbcc
- rank r1 = _cards[ 0 ]._rank;
- rank r2 = _cards[ 1 ]._rank;
- rank r3 = _cards[ 2 ]._rank;
- rank r4 = _cards[ 3 ]._rank;
- rank r5 = _cards[ 4 ]._rank;
- if (r1 == r2 && r2 != r3 && r3 == r4 && r4 != r5)
- return true;
- if (r1 == r2 && r2 != r3 && r3 != r4 && r4 == r5)
- return true;
- if (r1 != r2 && r2 == r3 && r3 != r4 && r4 == r5)
- return true;
- return false;
- }
- bool Hand::isThreeOfKind( )
- { // aaabc abbbc abccc
- rank r1 = _cards[ 0 ]._rank;
- rank r2 = _cards[ 1 ]._rank;
- rank r3 = _cards[ 2 ]._rank;
- rank r4 = _cards[ 3 ]._rank;
- rank r5 = _cards[ 4 ]._rank;
- if (r1 == r2 && r2 == r3 && r3 != r4 && r4 != r5)
- return true;
- if (r1 != r2 && r2 == r3 && r3 == r4 && r4 != r5)
- return true;
- if (r1 != r2 && r2 != r3 && r3 == r4 && r4 == r5)
- return true;
- return false;
- }
- bool Hand::isStraight( )
- { // a(a+1)(a+2)(a+3)(a+4)
- rank r1 = _cards[ 0 ]._rank;
- rank r2 = _cards[ 1 ]._rank;
- rank r3 = _cards[ 2 ]._rank;
- rank r4 = _cards[ 3 ]._rank;
- rank r5 = _cards[ 4 ]._rank;
- if (r5 == r4+1 && r4 == r3+1 && r3 == r2+1 && r2 == r1+1)
- return true; // could be a straight flush
- return false;
- }
- bool Hand::isFlush( )
- {
- suit s1 = _cards[ 0 ]._suit;
- suit s2 = _cards[ 1 ]._suit;
- suit s3 = _cards[ 2 ]._suit;
- suit s4 = _cards[ 3 ]._suit;
- suit s5 = _cards[ 4 ]._suit;
- if (s1 == s2 && s2 == s3 && s3 == s4 && s4 == s5)
- return true; // could be a straight flush
- return false;
- }
- bool Hand::isFullHouse( )
- { // aaabb aabbb
- rank r1 = _cards[ 0 ]._rank;
- rank r2 = _cards[ 1 ]._rank;
- rank r3 = _cards[ 2 ]._rank;
- rank r4 = _cards[ 3 ]._rank;
- rank r5 = _cards[ 4 ]._rank;
- if (r1 == r2 && r2 == r3 && r3 != r4 && r4 == r5)
- return true;
- if (r1 == r2 && r2 != r3 && r3 == r4 && r4 == r5)
- return true;
- return false;
- }
- bool Hand::isFourOfKind( )
- { // aaaab abbbb
- rank r1 = _cards[ 0 ]._rank;
- rank r2 = _cards[ 1 ]._rank;
- rank r3 = _cards[ 2 ]._rank;
- rank r4 = _cards[ 3 ]._rank;
- rank r5 = _cards[ 4 ]._rank;
- if (r1 == r2 && r2 == r3 && r3 == r4)
- return true;
- if (r2 == r3 && r3 == r4 && r4 == r5)
- return true;
- return false;
- }
- bool Hand::isStraightFlush( )
- { // a(a+1)(a+2)(a+3)(a+4)
- if (isStraight() && isFlush())
- return true;
- return false;
- }
- hand Hand::eval()
- { // sort or nothing works!
- Hand h = Hand( _size, _cards );
- h.reorder();
- // DON'T change order
- if (h.isStraightFlush())
- return STRAIGHTFLUSH;
- if (h.isFourOfKind())
- return FOUROFKIND;
- if (h.isFullHouse())
- return FULLHOUSE;
- if (h.isFlush())
- return FLUSH;
- if (h.isStraight())
- return STRAIGHT;
- if (h.isThreeOfKind())
- return THREEOFKIND;
- if (h.isTwoPairs())
- return TWOPAIRS;
- if (h.isOnePair())
- return ONEPAIR;
- return NOTHING;
- }
- inline void swap( Card &c1, Card &c2 )
- {
- Card c = c1;
- c1 = c2;
- c2 = c;
- }
- void Hand::reorder( )
- { // bubble sort
- ONDEBUG7( cout << "Hand::reorder()\n"; );
- for ( int i=_size-1; i > 0; i-- ) {
- for ( int j=0; j < i; j++ )
- if ( _cards[j]._rank > _cards[j+1]._rank )
- swap( _cards[j], _cards[j+1] );
- }
- }
- #if defined( STANDALONE )
- #include <cstring>
- #include <cstdlib>
- #ifdef DEBUG
- int debug = 1; // 0 - off, 1 - on, 2 - more, 3 - even more... 9 - all
- #endif
- main( int argc, char **argv )
- {
- using namespace std;
- if ( argc > 1 && strncmp( argv[ 1 ], "-D", 2 ) == 0 )
- {
- if ( argc > 2 )
- debug = atoi( argv[ 2 ] );
- else if ( strlen( argv[ 1 ] ) > 2 )
- debug = atoi( argv[ 1 ]+2 );
- else
- debug = 9; // level max
- }
- Card cards[ 5 ] =
- {
- Card( ACE, SPADES),
- Card( THREE, CLUBS ),
- Card( FOUR, DIAMONDS ),
- Card( THREE, HEARTS ),
- Card( SIX, SPADES ),
- };
- Hand hand = Hand( 5, cards );
- hand.print();
- hand.reorder();
- hand.print();
- Card c1 = Card( THREE, SPADES );
- cout << "hand[ 3 ] = " << hand[ 3 ] << endl;
- hand[ 3 ] = c1;
- cout << "hand[ 3 ] = " << hand[ 3 ] << endl;
- hand.print( true );
- cout << endl;
- const int NHANDS = 9;
- int test_set[NHANDS][5][2] =
- { // NOTHING
- {JACK, SPADES, KING, HEARTS, ACE, DIAMONDS, TWO, CLUBS, FIVE, SPADES},
- // ONEPAIR
- {ACE, SPADES, THREE, CLUBS, FOUR, DIAMONDS, THREE, HEARTS, SIX, SPADES},
- // TWOPAIRS
- {SEVEN, SPADES, KING, HEARTS, SEVEN, DIAMONDS, JACK, CLUBS, JACK, SPADES},
- // THREEOFKIND
- {FOUR, SPADES, TEN, HEARTS, TEN, DIAMONDS, EIGHT, CLUBS, TEN, SPADES},
- // STRAIGHT
- {KING, HEARTS, JACK, DIAMONDS, QUEEN, CLUBS, TEN, SPADES, ACE, DIAMONDS},
- // FLUSH
- {FOUR, HEARTS, NINE, HEARTS, ACE, HEARTS, SEVEN, HEARTS, QUEEN, HEARTS},
- // FULLHOUSE
- {FOUR, SPADES, TEN, HEARTS, TEN, DIAMONDS, FOUR, CLUBS, TEN, SPADES},
- // FOUROFKIND
- {ACE, CLUBS, NINE, HEARTS, NINE, DIAMONDS, NINE, CLUBS, NINE, SPADES},
- // STRAIGHTFLUSH
- {KING, DIAMONDS, JACK, DIAMONDS, QUEEN, DIAMONDS, TEN, DIAMONDS, ACE, DIAMONDS},
- };
- for ( int i = 0; i < NHANDS; i++ )
- {
- Card cards[ 5 ] =
- {
- Card( rank(test_set[ i ][0][0]), suit(test_set[ i ][0][1]) ),
- Card( rank(test_set[ i ][1][0]), suit(test_set[ i ][1][1]) ),
- Card( rank(test_set[ i ][2][0]), suit(test_set[ i ][2][1]) ),
- Card( rank(test_set[ i ][3][0]), suit(test_set[ i ][3][1]) ),
- Card( rank(test_set[ i ][4][0]), suit(test_set[ i ][4][1]) ),
- };
- Hand hand = Hand( 5, cards );
- hand.print( true );
- }
- }
- #endif
$ make thand
g++ -DDEBUG -g -c -o Card.o Card.cpp
g++ -DDEBUG -g -DSTANDALONE -DDEBUG Hand.cpp Card.o -o thand
$ thand
<< As 3c 4d 3h 6s >>
<< 3c 3h 4d 6s As >>
hand[ 3 ] = 6s
hand[ 3 ] = 3s
<< 3c 3h 4d 3s As >>
>> THREEOFKIND <<
<< Js Kh Ad 2c 5s >>
>> NOTHING <<
<< As 3c 4d 3h 6s >>
>> ONEPAIR <<
<< 7s Kh 7d Jc Js >>
>> TWOPAIRS <<
<< 4s Th Td 8c Ts >>
>> THREEOFKIND <<
<< Kh Jd Qc Ts Ad >>
>> STRAIGHT <<
<< 4h 9h Ah 7h Qh >>
>> FLUSH <<
<< 4s Th Td 4c Ts >>
>> FULLHOUSE <<
<< Ac 9h 9d 9c 9s >>
>> FOUROFKIND <<
<< Kd Jd Qd Td Ad >>
>> STRAIGHTFLUSH <<
Comments