Task: Poker hand analyser


C++: #include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>

using namespace std;

class poker
{
public:
    poker() { face = "A23456789TJQK"; suit = "SHCD"; }
    string analyze( string h )
    {
	memset( faceCnt, 0, 13 ); memset( suitCnt, 0, 4 ); vector<string> hand;
	transform( h.begin(), h.end(), h.begin(), toupper ); istringstream i( h );
	copy( istream_iterator<string>( i ), istream_iterator<string>(), back_inserter<vector<string> >( hand ) );
	if( hand.size() != 5 ) return "invalid hand."; vector<string>::iterator it = hand.begin();
	sort( it, hand.end() ); if( hand.end() != adjacent_find( it, hand.end() ) ) return "invalid hand.";
	while( it != hand.end() )
	{
	    if( ( *it ).length() != 2 ) return "invalid hand.";
	    int n = face.find( ( *it ).at( 0 ) ), l = suit.find( ( *it ).at( 1 ) );
	    if( n < 0 || l < 0 ) return "invalid hand.";
	    faceCnt[n]++; suitCnt[l]++; it++;
	}
	cout << h << ": "; return analyzeHand();
    }
private:
    string analyzeHand()
    {
	bool p1 = false, p2 = false, t = false, f = false, fl = false, st = false;
	for( int x = 0; x < 13; x++ )
	    switch( faceCnt[x] )
	    {
		case 2: if( p1 ) p2 = true; else p1 = true; break;
		case 3: t = true; break;
		case 4: f = true;
	    }
	for( int x = 0; x < 4; x++ )if( suitCnt[x] == 5 ){ fl = true; break; }

	if( !p1 && !p2 && !t && !f )
        {
	    int s = 0;
	    for( int x = 0; x < 13; x++ )
	    { 
		if( faceCnt[x] ) s++; else s = 0;
		if( s == 5 ) break;
	    }
	    st = ( s == 5 ) || ( s == 4 && faceCnt[0] && !faceCnt[1] );
	}

	if( st && fl ) return "straight-flush";
	else if( f ) return "four-of-a-kind"; 
	else if( p1 && t ) return "full-house";
	else if( fl ) return "flush";
	else if( st ) return "straight";
	else if( t ) return "three-of-a-kind";
	else if( p1 && p2 ) return "two-pair";
	else if( p1 ) return "one-pair";
        return "high-card";
    }
    string face, suit;
    unsigned char faceCnt[13], suitCnt[4];
};

int main( int argc, char* argv[] )
{
    poker p; 
    cout << p.analyze( "2h 2d 2s ks qd" ) << endl; cout << p.analyze( "2h 5h 7d 8s 9d" ) << endl;
    cout << p.analyze( "ah 2d 3s 4s 5s" ) << endl; cout << p.analyze( "2h 3h 2d 3s 3d" ) << endl;
    cout << p.analyze( "2h 7h 2d 3s 3d" ) << endl; cout << p.analyze( "2h 7h 7d 7s 7c" ) << endl;
    cout << p.analyze( "th jh qh kh ah" ) << endl; cout << p.analyze( "4h 4c kc 5d tc" ) << endl;
    cout << p.analyze( "qc tc 7c 6c 4c" ) << endl << endl; return system( "pause" );
}







VB: option explicit
class playingcard
 dim suit
 dim pips
  
  
  public sub print
		dim s,p
		select case suit
		case "S":s=chrW(&h2660)
		case "D":s=chrW(&h2666)
		case "C":s=chrW(&h2663)
		case "H":s=chrW(&h2665)
		end select

		select case pips
		case 1:p="A"
		case 11:p="J"
		case 12:p="Q"
		case 13:p="K"
		case else: p=""& pips
		end select

		wscript.stdout.write  right("   "&p & s,3)&" "
  end sub
end class

sub printhand(byref h,start)
   dim i
   for i =start to ubound(h)
     h(i).print
   next
   
end sub

function checkhand(byval arr)
  dim ss,i,max,last,uses,toppip,j,straight, flush,used,ace
  redim nn(13)
  
  ss=arr(0).suit   
  straight=true:flush=true
  max=0:last=0:used=0:toppip=0:ace=0
  for i=0 to ubound(arr)
      j=arr(i).pips
      if arr(i).suit<>ss then flush=false
      if j>toppip then toppip=j
      if j=1 then ace=1
      nn(j)=nn(j)+1
      if nn(j)>max then max= nn(j) 
      if abs(j-toppip)>=4  then straight=0
   next
   for i=1 to ubound(nn)
      if nn(i) then used=used+1
   next   
   if max=1 then
      if nn(1) and nn(10) and nn(11) and nn(12) and nn(13) then straight=1
   end if
   if flush and straight and max=1 then
      checkhand= "straight-flush"
   elseif flush then  
      checkhand= "flush"
   elseif straight and max=1 then   
      checkhand= "straight"
   elseif max=4 then
     checkhand= "four-of-a-kind"
   elseif max=3 then
     if used=2 then
       checkhand= "full-house"
     else  
       checkhand= "three-of-a-kind"
     end if
  elseif max=2 then
     if used=3 then
       checkhand= "two-pair"
     else  
       checkhand= "one-pair"
     end if
  else
     checkhand= "Top "& toppip
  End If
end function


function readhand(h)
  dim i,b,c,p
  redim a(4)
  for i=0 to ubound(a)
    b=h(i)
    set c=new playingcard
    p=left(b,1)
    select case p
    case "j": c.pips=11
    case "q": c.pips=12
    case "k": c.pips=13
    case "t": c.pips=10
    case "a": c.pips=1
    case else c.pips=cint(p)
    end select
    c.suit=ucase(right(b,1))
    set a(i)=c
  next
  readhand=a
  erase a
end function

dim hands,hh,i
 hands = Array(_
Array("2h", "5h", "7d", "8c", "9s"),_ 
Array("2h", "2d", "2c", "kc", "qd"),_
Array("ah", "2d", "3c", "4c", "5d"),_
Array("2h", "3h", "2d", "3c", "3d"),_
Array("2h", "7h", "2d", "3c", "3d"),_
Array("th", "jh", "qh", "kh", "ah"),_
Array("4h", "4s", "ks", "5d", "ts"),_
Array("qc", "tc", "7c", "6c", "4c"),_
Array("ah", "ah", "7c", "6c", "4c"))

for i=1 to ubound(hands)
   hh=readhand(hands(i))
   printhand hh,0
   wscript.stdout.write vbtab & checkhand(hh)
   wscript.stdout.writeblanklines(1)
   
next