PDA

View Full Version : Poker hand evaluator in PERL


rr2000
06-24-2003, 07:46 AM
I'm aware of the pokersource hand evaluator which is in C. Does anyone know of a PERL code for evaluating a poker hand? Thx.

eMarkM
06-24-2003, 10:15 AM
If by hand evaluator, you mean something that will transalte a hand history to something readable then there was one written by majorkong some time back.

I found this thread (http://www.twoplustwo.com/forums/showthreaded.php?Cat=&Board=holdem&Number=165711&F orum=All_Forums&Words=%20perl%20&Match=Entire%20Ph rase&Searchpage=0&Limit=25&Old=allposts&Main=16571 1&Search=true#Post165711) where he posts the code. But I tried the link to the perl script and it's not there anymore. Majorkong, could you repost this script?

Ed Miller
06-24-2003, 06:25 PM
But I doubt it's what you are looking for. In fact, I think it is obselete because Paradise has changed their hand history format... but if it is something that interests you, you should be able to make a few small changes and make it work again.

<pre><font class="small">code:</font><hr>
################################################## ############
################################################## ############
################################################## ############
###### Paradise Poker Hand History Translator v1.0 ######
###### by MajorKong 10/29/02 ######
###### ######
###### Distribute freely and modify to taste. ######
###### ######
###### Takes Paradise Poker hand histories as input ######
###### and translates them into a sort of broken, ######
###### pidgin poker English for posting on the Internet ######
###### or your own edification. ######
###### ######
###### Command-line arguments: ######
###### -h causes the hand to end when our hero folds ######
###### -n causes the number of players remaining to ######
###### be printed after each betting round ######
###### -g suppresses printing the name of the game ######
###### ######
###### NB: Only Texas Holdem is supported currently ######
################################################## ############
################################################## ############
################################################## ############

#flags
$print_game = 1;
$print_num_after_round = 0;
$show_hero_only = 0;

foreach $arg (@ARGV)
{
if ( $arg =~ /^\-\S*h/ ) # -h
{
$show_hero_only = 1;
}
if ( $arg =~ /^\-\S*n/ ) # -n
{
$print_num_after_round = 1;
}
if ( $arg =~ /^\-\S*g/ ) # -g
{
$print_game = 0;
}
}

#code
$line_num = 0;
$hand_num = 1;
while (&lt;STDIN&gt;)
{
$line_num++;
chop();
if (/^---+/) # Beginning of a hand
{
last;
}
}
while (/^---+/)
{
&amp;do_hand;
}

sub do_hand
{
local(@names, @new_names, @posters, @sit_out);
$hero_folded = 0;
$printing_on = 1;
$last_bet_called = 1;
&amp;get_next_line;
$line = $_;
if ( $line =~ /If you have any questions regarding this hand history/ ) { return; }
if ( $line !~ /^Game #[0-9]* - (.*) -/ ) { print "Invalid hand in line $line_num.\n" ; die; }
print "Hand $hand_num:\n";
$hand_num++;
if ( $print_game ) { print "$1. "; }

&amp;get_next_line;
$line = $_;
if ( $line !~ /^Table .* -- Seat ([0-9]+) is the button/ ) { print "Invalid hand in line $line_num.\n" ; die; }
$button_seat = $1;

$num_players = 0;
while (&lt;STDIN&gt;)
{
$line_num++;
chop();
if ( /^Seat\s+([0-9]+): (.*\S) \(\$(.*) in chips\)/ )
{
if ( $3 &gt; 0 )
{
$num_players++;
push(@names, $2);
if ( $1 == $button_seat )
{
$button_name = $2;
$button_number = $num_players;
}
}
}
elsif ( /(.*\S)\s*: Post Small Blind/ )
{
$sb_name = $1;
$sb_number = ($button_number % $num_players) + 1;
for ( $i = $button_number ; $names[$i % $num_players] ne $sb_name ; $i++ )
{
$sb_number = (($i + 1) % $num_players) + 1;
push(@sit_out, $names[$i % $num_players]);
}
last;
}
}

while (&lt;STDIN&gt;)
{
$line_num++;
chop();
if ( /(.*\S)\s*: Post Big Blind/ )
{
$bb_name = $1;
for ( $i = $sb_number ; $names[$i % $num_players] ne $bb_name ; $i++ )
{
push(@sit_out, $names[$i % $num_players]);
}
}
elsif (/(.*\S)\s*: Post \(/)
{
push(@posters, $1);
}
elsif (/(.*\S)\s*: Sit out/)
{
push(@sit_out, $1);
}
elsif (/^Dealing.../ || /^Dealt/)
{
last;
}
}

# Remove players who are sitting out
$num_players = 0;
foreach $name ( @names)
{
$must_remove = 0;
foreach $sit_out_name ( @sit_out )
{
if ( $name eq $sit_out_name )
{
$must_remove = 1;
last;
}
}
if ( ! $must_remove )
{
$num_players++;
push( @new_names, $name );
if ( $button_name eq $name )
{
$button_number = $num_players;
}
}
}
@names = @new_names;

if ( $_ !~ /^Dealt/ ) { &amp;get_next_line; }
$line = $_;
if ($line !~ /Dealt to (.*) \[ ([2-9TJQKA][cdhs]) ]/)
{
print "Hero not dealt in.\n\n";
while (&lt;STDIN&gt;)
{
$line_num++;
chop();
if (/^---+/) # Beginning of a hand
{
return;
}
}
}
$hero_name = $1;
$hero_hand = $2;

&amp;get_next_line;
$line = $_;
if ($line !~ /Dealt to .* \[ ([2-9TJQKA][cdhs]) ]/) { print "Invalid hand in line $line_num.\n" ; die; }
$hero_hand = $hero_hand . $1;

&amp;get_positions;
print "$num_players players. ";
foreach $name (@posters)
{
print "$positions{$name} posts. ";
}

$hero_prep = "in";
if ( $positions{$hero_name} eq "UTG" )
{
$hero_prep = "";
}
elsif ( $positions{$hero_name} eq "CO" || $positions{$hero_name} eq "SB" || $positions{$hero_name} eq "BB" )
{
$hero_prep = "in the";
}
elsif ( $positions{$hero_name} eq "Button" )
{
$hero_prep = "on the";
}

print "Dealt $hero_hand $hero_prep $positions{$hero_name}. ";
$num_active_players = $num_players;
&amp;bet_round("preflop");
if ( /\*+ FLOP \*+ : \[ ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) \]/ )
{
$flop_cards = $1 . $2 . $3;
print "Flop comes $flop_cards. " if $printing_on;
&amp;bet_round("flop");
if ( /\*+ TURN \*+ : \[ [2-9TJQKA][cdhs] [2-9TJQKA][cdhs] [2-9TJQKA][cdhs] \] \[ ([2-9TJQKA][cdhs]) \]/ )
{
print "Turn comes $1. " if $printing_on;
&amp;bet_round("turn");
if ( /\*+ RIVER \*+ : \[ [2-9TJQKA][cdhs] [2-9TJQKA][cdhs] [2-9TJQKA][cdhs] [2-9TJQKA][cdhs] \] \[ ([2-9TJQKA][cdhs]) \]/ )
{
print "River comes $1. " if $printing_on;
&amp;bet_round("river");
}
}
}
&amp;showdown;
print "\n\n";
}

sub bet_round
{
$round_name = $_[0];
if ( $round_name eq "preflop" )
{
$num_bets = 1;
}
else
{
$num_bets = 0;
}
$num_checks = 0;
$num_folds = 0;
$print_it = 0;
while (1)
{
&amp;get_next_line;
if ( /^\*\*\*/) { last; }
if ( $_ !~ /(.*\S)\s*: (\S+)\s?(\S*)/) { print "Invalid hand in line $line_num\n" ; die; }
if ( $1 eq $hero_name )
{
$pos = "Hero";
}
else
{
$pos = $positions{$1};
}
$action = $2;
$action_mod = $3;
if ( $action eq "Check" )
{
if ( $round_name eq "preflop" )
{
$act_pos = $pos;
$act_name = "checks";
$print_it = 1;
}
else
{
$num_checks++;
}
}
elsif ( $action eq "Fold" )
{
if ( $num_checks &gt; 0 || $pos eq "Hero")
{
$act_pos = $pos;
$act_name = "folds";
$print_it = 1;
if ( $pos eq "Hero" ) { $hero_folded = 1; }
}
else
{
$folder = $pos;
$num_folds++;
}
$num_active_players--;
}
elsif ( $action eq "Call" )
{
if ( $round_name eq "preflop" &amp;&amp; $num_bets == 1 )
{
if ( $positions{$1} eq "SB" )
{
$act_name = "completes";
}
else
{
$act_name = "limps";
}
}
else
{
$act_name = "calls";
}
$act_pos = $pos;
$print_it = 1;
}
elsif ( $action eq "Bet" )
{
$act_pos = $pos;
$num_bets++;
$act_name = "bets";
$print_it = 1;
}
elsif ( $action eq "Raise" )
{
$act_pos = $pos;
$num_bets++;
if ( $num_bets == 2 ) { $act_name = "raises"; }
elsif ($num_bets == 3 ) { $act_name = "reraises"; }
elsif ($num_bets == 4 ) { $act_name = "caps"; }
else { print "Invalid action in line $line_num\n" ; die; }
$print_it = 1;
}
elsif ( $action eq "Winner" )
{
print "All fold." if $printing_on;
$last_bet_called = 0;
}
elsif ( $action eq "Timed" )
{
}
else
{
print "Invalid action in line $line_num\n" ;
die;
}
if ( $action_mod eq "All-in" ) { $act_name = $act_name . " all-in"; }
if ( $print_it )
{
if ( $num_checks &gt; 0 )
{
print "Checked to $act_pos who $act_name. " if $printing_on;
$num_checks = 0;
}
elsif ( $num_folds == 1 )
{
print "$folder folds. $act_pos $act_name. " if $printing_on;
$num_folds = 0;
}
elsif ( $num_folds &gt; 1 )
{
print "Folded to $act_pos who $act_name. " if $printing_on;
$num_folds = 0;
}
else
{
print "$act_pos $act_name. " if $printing_on;
}
$print_it = 0;
if ( $show_hero_only &amp;&amp; $hero_folded ) { $printing_on = 0 };
}
}
if ( $num_bets == 0 ) { print "Checked around. " if $printing_on; }
if ( $printing_on &amp;&amp; $print_num_after_round &amp;&amp; $round_name ne "river" )
{
if ( $num_active_players == 2 ) { print "Heads-up. "; }
elsif ($num_active_players &gt; 2 ) { print "$num_active_players-handed. "; }
}
}

sub showdown
{
while (&lt;STDIN&gt;)
{
$line_num++;
chop();
if (/^---+/) # Beginning of a hand
{
last;
}
if ( $last_bet_called &amp;&amp; /^Board: \[ ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) \]/ )
{
print "Final board: $1$2$3$4$5. " if $printing_on;
}
elsif ( /(.*\S) lost .* \[ ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) \]/ )
{
if ( $1 ne $hero_name )
{
print "$positions{$1} shows $2$3. " if $printing_on;
}
}
elsif ( /(.*\S) didn't bet .* \[ ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) \]/ )
{
}
elsif ( /(.*\S) bet .* \[ ([2-9TJQKA][cdhs]) ([2-9TJQKA][cdhs]) \]/ )
{
if ( $1 ne $hero_name )
{
print "$positions{$1} shows $2$3. " if $printing_on;
}
}
}
}

sub get_next_line
{
while ( &lt;STDIN&gt; )
{
$line_num++;
chop();
if ( ($_ !~ /.*\S said, ".*/) &amp;&amp; ($_ !~ /"$/) ) { last; }
}
}

sub get_positions
{
$positions{$names[$button_number % $num_players]} = "SB";
$positions{$names[($button_number + 1) % $num_players]} = "BB";
if ( $num_players == 3 )
{
$positions{$names[($button_number + 2) % $num_players]} = "Button";
}
elsif ( $num_players == 4 )
{
$positions{$names[($button_number + 2) % $num_players]} = "UTG";
$positions{$names[($button_number + 3) % $num_players]} = "Button";
}
elsif ( $num_players == 5 )
{
$positions{$names[($button_number + 2) % $num_players]} = "UTG";
$positions{$names[($button_number + 3) % $num_players]} = "CO";
$positions{$names[($button_number + 4) % $num_players]} = "Button";
}
elsif ( $num_players == 6 )
{
$positions{$names[($button_number + 2) % $num_players]} = "UTG";
$positions{$names[($button_number + 3) % $num_players]} = "MP";
$positions{$names[($button_number + 4) % $num_players]} = "CO";
$positions{$names[($button_number + 5) % $num_players]} = "Button";
}
elsif ( $num_players == 7 )
{
$positions{$names[($button_number + 2) % $num_players]} = "UTG";
$positions{$names[($button_number + 3) % $num_players]} = "EP";
$positions{$names[($button_number + 4) % $num_players]} = "MP";
$positions{$names[($button_number + 5) % $num_players]} = "CO";
$positions{$names[($button_number + 6) % $num_players]} = "Button";
}
elsif ( $num_players == 8 )
{
$positions{$names[($button_number + 2) % $num_players]} = "UTG";
$positions{$names[($button_number + 3) % $num_players]} = "EP";
$positions{$names[($button_number + 4) % $num_players]} = "MP";
$positions{$names[($button_number + 5) % $num_players]} = "MP";
$positions{$names[($button_number + 6) % $num_players]} = "CO";
$positions{$names[($button_number + 7) % $num_players]} = "Button";
}
elsif ( $num_players == 9 )
{
$positions{$names[($button_number + 2) % $num_players]} = "UTG";
$positions{$names[($button_number + 3) % $num_players]} = "EP";
$positions{$names[($button_number + 4) % $num_players]} = "EP";
$positions{$names[($button_number + 5) % $num_players]} = "MP";
$positions{$names[($button_number + 6) % $num_players]} = "MP";
$positions{$names[($button_number + 7) % $num_players]} = "CO";
$positions{$names[($button_number + 8) % $num_players]} = "Button";
}
elsif ( $num_players == 10 )
{
$positions{$names[($button_number + 2) % $num_players]} = "UTG";
$positions{$names[($button_number + 3) % $num_players]} = "EP";
$positions{$names[($button_number + 4) % $num_players]} = "EP";
$positions{$names[($button_number + 5) % $num_players]} = "MP";
$positions{$names[($button_number + 6) % $num_players]} = "MP";
$positions{$names[($button_number + 7) % $num_players]} = "LMP";
$positions{$names[($button_number + 8) % $num_players]} = "CO";
$positions{$names[($button_number + 9) % $num_players]} = "Button";
}
else
{
print "Invalid number of players at line $line_num\n.";
die;
}
}
</pre><hr>

rr2000
06-24-2003, 11:58 PM
No, I'm looking for a poker hand evaluator. Not a hand history parser.

Ed Miller
06-25-2003, 08:32 AM
So I didn't really think that what I wrote was what you wanted... but what exactly is a poker hand evaluator?

cybertilt
06-25-2003, 09:09 AM
RR, Poker room has a complete list of every hand's EV rating under about 2 million hands with real money. You can print this out. It maybe what you are looking for.

rr2000
06-25-2003, 11:30 PM
Looks like I wasn't clear. What I mean is: given a 7 card hand, e.g. As Ks Qd Jd 9h Ah 2d, the program should output whether it's a high card, one pair, two pair, ... or royal flush.