20

Hand

  1. #if !defined( _HAND_H )
  2. #define _HAND_H
  3.  
  4. #include <assert.h>
  5.  
  6. #include "Card.h"
  7.  
  8. #include "debug.h"
  9.  
  10. enum hand
  11. {
  12.     NOTHING, ONEPAIR, TWOPAIRS, THREEOFKIND, STRAIGHT, FLUSH, FULLHOUSE, FOUROFKIND, STRAIGHTFLUSH
  13. };
  14.  
  15. class Hand
  16. {
  17. public:
  18.     ~Hand( )
  19.     {
  20.         ONDEBUG9( cout << "\t~Hand( )\n"; );
  21.         delete [] _cards;
  22.     }
  23.     Hand( unsigned n=5, Card *s=0 ) : _size( n )
  24.     {
  25.         ONDEBUG8( cout << "\tHand( unsigned=" << n << ", Cards *s=0x" << s << " )\n"; );
  26.         _cards = new Card[ n ];
  27.         if ( s != 0 )
  28.             for ( int i = 0; i < n; i++ )
  29.                 _cards[ i ] = s[ i ];
  30.     }
  31.  
  32.     Card &operator[]( int i )
  33.     {
  34.         assert( i < _size );
  35.         return _cards[ i ];
  36.     }
  37.  
  38.     unsigned size( ) { return _size; }
  39.  
  40.     void print( bool =false );
  41.     hand eval();
  42.     void reorder();
  43.  
  44. private:
  45.     unsigned _size;
  46.     Card *_cards;
  47.  
  48.     bool isOnePair();
  49.     bool isTwoPairs();
  50.     bool isThreeOfKind();
  51.     bool isStraight();
  52.     bool isFlush();
  53.     bool isFullHouse();
  54.     bool isFourOfKind();
  55.     bool isStraightFlush();
  56. };
  57.  
  58. #endif
  1. #include "Hand.h"
  2.  
  3. #include <iostream>
  4.  
  5. #include <assert.h>
  6.  
  7. void Hand::print( bool full )
  8. {
  9.     static const char* hand_text[ ] =
  10.     {
  11.         "    NOTHING     ",
  12.         "    ONEPAIR     ",
  13.         "    TWOPAIRS    ",
  14.         "   THREEOFKIND  ",
  15.         "    STRAIGHT    ",
  16.         "     FLUSH      ",
  17.         "   FULLHOUSE    ",
  18.         "   FOUROFKIND   ",
  19.         " STRAIGHTFLUSH  "
  20.     };
  21.  
  22.     cout << "<<";
  23.     for ( int i = 0; i < _size; i++ )
  24.         std::cout << " " << _cards[ i ];
  25.     cout << " >>\n";
  26.  
  27.     if ( full )
  28.         cout << ">>" << hand_text[ eval() ] << "<<\n";
  29. }
  30.  
  31. bool Hand::isOnePair( )
  32. {   // aabcd abbcd abccd abcdd
  33.     rank r1 = _cards[ 0 ]._rank;
  34.     rank r2 = _cards[ 1 ]._rank;
  35.     rank r3 = _cards[ 2 ]._rank;
  36.     rank r4 = _cards[ 3 ]._rank;
  37.     rank r5 = _cards[ 4 ]._rank;
  38.  
  39.     if (r1 == r2 && r2 != r3 && r3 != r4 && r4 != r5)
  40.         return true;
  41.     if (r1 != r2 && r2 == r3 && r3 != r4 && r4 != r5)
  42.         return true;
  43.     if (r1 != r2 && r2 != r3 && r3 == r4 && r4 != r5)
  44.         return true;
  45.     if (r1 != r2 && r2 != r3 && r3 != r4 && r4 == r5)
  46.         return true;
  47.     return false;
  48. }
  49.  
  50. bool Hand::isTwoPairs( )
  51. {   // aabbc aabcc abbcc
  52.     rank r1 = _cards[ 0 ]._rank;
  53.     rank r2 = _cards[ 1 ]._rank;
  54.     rank r3 = _cards[ 2 ]._rank;
  55.     rank r4 = _cards[ 3 ]._rank;
  56.     rank r5 = _cards[ 4 ]._rank;
  57.  
  58.     if (r1 == r2 && r2 != r3 && r3 == r4 && r4 != r5)
  59.         return true;
  60.     if (r1 == r2 && r2 != r3 && r3 != r4 && r4 == r5)
  61.         return true;
  62.     if (r1 != r2 && r2 == r3 && r3 != r4 && r4 == r5)
  63.         return true;
  64.     return false;
  65. }
  66.  
  67. bool Hand::isThreeOfKind( )
  68. {   // aaabc abbbc abccc
  69.     rank r1 = _cards[ 0 ]._rank;
  70.     rank r2 = _cards[ 1 ]._rank;
  71.     rank r3 = _cards[ 2 ]._rank;
  72.     rank r4 = _cards[ 3 ]._rank;
  73.     rank r5 = _cards[ 4 ]._rank;
  74.  
  75.     if (r1 == r2 && r2 == r3 && r3 != r4 && r4 != r5)
  76.         return true;
  77.     if (r1 != r2 && r2 == r3 && r3 == r4 && r4 != r5)
  78.         return true;
  79.     if (r1 != r2 && r2 != r3 && r3 == r4 && r4 == r5)
  80.         return true;
  81.     return false;
  82. }
  83.  
  84. bool Hand::isStraight( )
  85. {   // a(a+1)(a+2)(a+3)(a+4)
  86.     rank r1 = _cards[ 0 ]._rank;
  87.     rank r2 = _cards[ 1 ]._rank;
  88.     rank r3 = _cards[ 2 ]._rank;
  89.     rank r4 = _cards[ 3 ]._rank;
  90.     rank r5 = _cards[ 4 ]._rank;
  91.  
  92.     if (r5 == r4+1 && r4 == r3+1 && r3 == r2+1 && r2 == r1+1)
  93.         return true;    // could be a straight flush
  94.  
  95.     return false;
  96. }
  97.  
  98. bool Hand::isFlush( )
  99. {
  100.     suit s1 = _cards[ 0 ]._suit;
  101.     suit s2 = _cards[ 1 ]._suit;
  102.     suit s3 = _cards[ 2 ]._suit;
  103.     suit s4 = _cards[ 3 ]._suit;
  104.     suit s5 = _cards[ 4 ]._suit;
  105.  
  106.     if (s1 == s2 && s2 == s3 && s3 == s4 && s4 == s5)
  107.         return true;    // could be a straight flush
  108.  
  109.     return false;
  110. }
  111.  
  112. bool Hand::isFullHouse( )
  113. {   // aaabb aabbb
  114.     rank r1 = _cards[ 0 ]._rank;
  115.     rank r2 = _cards[ 1 ]._rank;
  116.     rank r3 = _cards[ 2 ]._rank;
  117.     rank r4 = _cards[ 3 ]._rank;
  118.     rank r5 = _cards[ 4 ]._rank;
  119.  
  120.     if (r1 == r2 && r2 == r3 && r3 != r4 && r4 == r5)
  121.         return true;
  122.     if (r1 == r2 && r2 != r3 && r3 == r4 && r4 == r5)
  123.         return true;
  124.  
  125.     return false;
  126. }
  127.  
  128. bool Hand::isFourOfKind( )
  129. {   // aaaab abbbb
  130.     rank r1 = _cards[ 0 ]._rank;
  131.     rank r2 = _cards[ 1 ]._rank;
  132.     rank r3 = _cards[ 2 ]._rank;
  133.     rank r4 = _cards[ 3 ]._rank;
  134.     rank r5 = _cards[ 4 ]._rank;
  135.  
  136.     if (r1 == r2 && r2 == r3 && r3 == r4)
  137.         return true;
  138.     if (r2 == r3 && r3 == r4 && r4 == r5)
  139.         return true;
  140.  
  141.     return false;
  142. }
  143.  
  144. bool Hand::isStraightFlush( )
  145. {   // a(a+1)(a+2)(a+3)(a+4)
  146.     if (isStraight() && isFlush())
  147.         return true;
  148.  
  149.     return false;
  150. }
  151.  
  152. hand Hand::eval()
  153. {   // sort or nothing works!
  154.     Hand h = Hand( _size, _cards );
  155.     h.reorder();
  156.     // DON'T change order
  157.     if (h.isStraightFlush())
  158.         return STRAIGHTFLUSH;
  159.     if (h.isFourOfKind())
  160.         return FOUROFKIND;
  161.     if (h.isFullHouse())
  162.         return FULLHOUSE;
  163.     if (h.isFlush())
  164.         return FLUSH;
  165.     if (h.isStraight())
  166.         return STRAIGHT;
  167.     if (h.isThreeOfKind())
  168.         return THREEOFKIND;
  169.     if (h.isTwoPairs())
  170.         return TWOPAIRS;
  171.     if (h.isOnePair())
  172.         return ONEPAIR;
  173.  
  174.     return NOTHING;
  175. }
  176.  
  177. inline void swap( Card &c1, Card &c2 )
  178. {
  179.     Card c = c1;
  180.     c1 = c2;
  181.     c2 = c;
  182. }
  183.  
  184. void Hand::reorder( )
  185. {   // bubble sort
  186.     ONDEBUG7( cout << "Hand::reorder()\n"; );
  187.     for ( int i=_size-1; i > 0; i-- ) {
  188.         for ( int j=0; j < i; j++ )
  189.             if ( _cards[j]._rank > _cards[j+1]._rank )
  190.                 swap( _cards[j], _cards[j+1] );
  191.     }
  192. }
  193.  
  194. #if defined( STANDALONE )
  195.  
  196. #include <cstring>
  197. #include <cstdlib>
  198.  
  199. #ifdef DEBUG
  200. int debug = 1;  // 0 - off, 1 - on, 2 - more, 3 - even more... 9 - all
  201. #endif
  202.  
  203. main( int argc, char **argv )
  204. {
  205.     using namespace std;
  206.  
  207.     if ( argc > 1 && strncmp( argv[ 1 ], "-D", 2 ) == 0 )
  208.     {
  209.         if ( argc > 2 )
  210.             debug = atoi( argv[ 2 ] );
  211.         else if ( strlen( argv[ 1 ] ) > 2 )
  212.             debug = atoi( argv[ 1 ]+2 );
  213.         else
  214.             debug = 9;  // level max
  215.     }
  216.  
  217.     Card cards[ 5 ] =
  218.     {
  219.         Card( ACE, SPADES),
  220.         Card( THREE, CLUBS ),
  221.         Card( FOUR, DIAMONDS ),
  222.         Card( THREE, HEARTS ),
  223.         Card( SIX, SPADES ),
  224.     };
  225.     Hand hand = Hand( 5, cards );
  226.     hand.print();
  227.     hand.reorder();
  228.     hand.print();
  229.  
  230.     Card c1 = Card( THREE, SPADES );
  231.  
  232.     cout << "hand[ 3 ] = " << hand[ 3 ] << endl;
  233.     hand[ 3 ] = c1;
  234.     cout << "hand[ 3 ] = " << hand[ 3 ] << endl;
  235.     hand.print( true );
  236.     cout << endl;
  237.  
  238.     const int NHANDS = 9;
  239.  
  240.     int test_set[NHANDS][5][2] =
  241.     {   // NOTHING
  242.         {JACK, SPADES, KING, HEARTS, ACE, DIAMONDS, TWO, CLUBS, FIVE, SPADES},
  243.         // ONEPAIR
  244.         {ACE, SPADES, THREE, CLUBS, FOUR, DIAMONDS, THREE, HEARTS, SIX, SPADES},
  245.         // TWOPAIRS
  246.         {SEVEN, SPADES, KING, HEARTS, SEVEN, DIAMONDS, JACK, CLUBS, JACK, SPADES},
  247.         // THREEOFKIND
  248.         {FOUR, SPADES, TEN, HEARTS, TEN, DIAMONDS, EIGHT, CLUBS, TEN, SPADES},
  249.         // STRAIGHT
  250.         {KING, HEARTS, JACK, DIAMONDS, QUEEN, CLUBS, TEN, SPADES, ACE, DIAMONDS},
  251.         // FLUSH
  252.         {FOUR, HEARTS, NINE, HEARTS, ACE, HEARTS, SEVEN, HEARTS, QUEEN, HEARTS},
  253.         // FULLHOUSE
  254.         {FOUR, SPADES, TEN, HEARTS, TEN, DIAMONDS, FOUR, CLUBS, TEN, SPADES},
  255.         // FOUROFKIND
  256.         {ACE, CLUBS, NINE, HEARTS, NINE, DIAMONDS, NINE, CLUBS, NINE, SPADES},
  257.         // STRAIGHTFLUSH
  258.         {KING, DIAMONDS, JACK, DIAMONDS, QUEEN, DIAMONDS, TEN, DIAMONDS, ACE, DIAMONDS},
  259.     };
  260.  
  261.     for ( int i = 0; i < NHANDS; i++ )
  262.     {
  263.         Card cards[ 5 ] =
  264.         {
  265.             Card( rank(test_set[ i ][0][0]), suit(test_set[ i ][0][1]) ),
  266.             Card( rank(test_set[ i ][1][0]), suit(test_set[ i ][1][1]) ),
  267.             Card( rank(test_set[ i ][2][0]), suit(test_set[ i ][2][1]) ),
  268.             Card( rank(test_set[ i ][3][0]), suit(test_set[ i ][3][1]) ),
  269.             Card( rank(test_set[ i ][4][0]), suit(test_set[ i ][4][1]) ),
  270.         };
  271.         Hand hand = Hand( 5, cards );
  272.         hand.print( true );
  273.     }
  274. }
  275.  
  276. #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

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].