File Coverage

blib/lib/Poker/Eval/Wild.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Poker::Eval::Wild;
2 1     1   2238 use Algorithm::Combinatorics qw(combinations combinations_with_repetition);
  0            
  0            
3             use Moo;
4              
5             =head1 NAME
6              
7             Poker::Eval::Wild - Evaluate and score wildcard poker hands.
8              
9             =head1 VERSION
10              
11             Version 0.01
12              
13             =cut
14              
15             our $VERSION = '0.01';
16              
17             =head1 SYNOPSIS
18              
19             See Poker::Eval for code example.
20              
21             =head1 INTRODUCTION
22              
23             Evaluate highball wildcard hands. The lowball wildcard evaluator doesn't quite work yet. To mark a card as wild, set the wild_flag of the Poker::Card object to true.
24              
25             =cut
26              
27             extends 'Poker::Eval::Community';
28              
29             sub best_hand {
30             my ( $self, $hole ) = @_;
31             my $best = { score => 0 };
32             return $best
33             if $self->card_count >
34             ( scalar @$hole + scalar @{ $self->community_cards } );
35             my ( @wild, @normal );
36             for my $card ( @$hole, @{ $self->community_cards } ) {
37             if ( $card->is_wild ) {
38             push @wild, $card;
39             }
40             else {
41             push @normal, $card;
42             }
43             }
44             my $wild_count = scalar @wild;
45             $wild_count = $wild_count > 5 ? 5 : $wild_count;
46             my $norm_used = 5 > $wild_count ? 5 - $wild_count : 0;
47             my @wild_combos;
48             if ( $wild_count > 4 ) {
49             my $flat_hand = '1414141414';
50             $best = {
51             hand => $flat_hand,
52             score => $self->scorer->hand_score($flat_hand),
53             };
54             }
55             elsif ( $wild_count == 4 ) {
56             my @ranks = sort { $a <=> $b }
57             map { $self->scorer->rank_val( $_->rank ) } @normal;
58             my $high_rank = sprintf( "%02d", pop @ranks);
59             my $flat_hand = join '', ($high_rank) x 5;
60             $best = {
61             hand => $flat_hand,
62             score => $self->scorer->hand_score($flat_hand),
63             };
64             }
65             else {
66             @wild_combos =
67             combinations_with_repetition( [ map { sprintf( "%02d", $_ ) } 2 .. 14 ],
68             $wild_count );
69             my $norm_iter = combinations( [@normal], $norm_used );
70             while ( my $norm_combo = $norm_iter->next ) {
71              
72             my %suit;
73             my $max = 0;
74             my @norm_ranks = map { $self->scorer->rank_val( $_->rank ) } @$norm_combo;
75             for my $card (@$norm_combo) {
76             $suit{ $card->suit }++;
77             $max = $suit{ $card->suit } if $suit{ $card->suit } >= $max;
78             }
79             my $flush_possible = $max + $wild_count > 4 ? 1 : 0;
80              
81             for my $wild_combo (@wild_combos) {
82             my $flat_combo =
83             join( '', sort { $b <=> $a } ( @$wild_combo, @norm_ranks ) );
84             my $score = $self->scorer->hand_score($flat_combo);
85             if ($flush_possible) {
86             my $flush_score = $self->scorer->hand_score( $flat_combo . 's' ) || 0;
87             $score = $flush_score if $flush_score > $score;
88             }
89             if ( defined $score && $score >= $best->{score} ) {
90             $best = {
91             score => $score,
92             hand => $flat_combo,
93             };
94             }
95             }
96             }
97             }
98             $best->{name} = $self->scorer->hand_name( $best->{score} );
99             return $best;
100             }
101              
102             =head1 AUTHOR
103              
104             Nathaniel Graham, C<< >>
105              
106             =head1 LICENSE AND COPYRIGHT
107              
108             Copyright 2016 Nathaniel Graham.
109              
110             This program is free software; you can redistribute it and/or modify it
111             under the terms of the the Artistic License (2.0). You may obtain a
112             copy of the full license at:
113              
114             L
115              
116             =cut
117              
118             1;