File Coverage

blib/lib/Poker/Score/High.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Poker::Score::High;
2 1     1   1082 use Moo;
  1         2  
  1         6  
3 1     1   656 use Algorithm::Combinatorics qw(combinations);
  0            
  0            
4              
5             =head1 NAME
6              
7             Poker::Score::High - Identify and score specific highball poker hand.
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::Score for code example.
20              
21             =cut
22              
23             extends 'Poker::Score';
24              
25             sub _build_hands {
26             my $self = shift;
27             my %map = ( 1 => 'a High Card' );
28             my @hands = @{ $self->unpaired };
29             $map{ $#hands } = 'One Pair';
30             push(@hands, @{ $self->one_pair });
31             $map{ $#hands } = 'Two Pair';
32             push(@hands, @{ $self->two_pair });
33             $map{ $#hands } = 'Three-of-a-Kind';
34             push(@hands, @{ $self->threes });
35             $map{ $#hands } = 'a Straight';
36             push(@hands, @{ $self->straights });
37             $map{ $#hands } = 'a Flush';
38             push(@hands, @{ $self->flushes });
39             $map{ $#hands } = 'a Full House';
40             push(@hands, @{ $self->houses });
41             $map{ $#hands } = 'Four-of-a-Kind';
42             push(@hands, @{ $self->fours });
43             $map{ $#hands } = 'a Straight Flush';
44             push(@hands, @{ $self->straight_flushes });
45             $map{ $#hands } = 'Five-of-a-Kind';
46             push(@hands, @{ $self->fives });
47             $self->hands( [ @hands ] );
48             $self->_hand_map( \%map );
49             }
50              
51             # straights
52             has 'straights' => (
53             is => 'rw',
54             isa => sub {
55             die "Not an array.\n" unless ref( $_[0] ) eq 'ARRAY';
56             },
57             builder => '_build_straights'
58             );
59              
60             sub _build_straights {
61             return [
62             '1405040302', '0605040302', '0706050403', '0807060504', '0908070605',
63             '1009080706', '1110090807', '1211100908', '1312111009', '1413121110'
64             ];
65             }
66              
67             # unpaired non-straight combinations
68             has 'unpaired' => (
69             is => 'rw',
70             isa => sub { die "Not an array.\n" unless ref( $_[0] ) eq 'ARRAY' },
71             builder => '_build_unpaired',
72             );
73              
74             sub _build_unpaired {
75             my $self = shift;
76             my %straight = map { $_, 1 } @{ $self->straights };
77             my $iter = combinations( [ reverse( 2 .. 14 ) ], 5 );
78             my @unpaired;
79             while ( my $c = $iter->next ) {
80             push @unpaired,
81             join( '', map { sprintf( "%02d", $_ ) } sort { $b <=> $a } @$c );
82             }
83             return [ grep { !exists $straight{$_} } sort { $a <=> $b } @unpaired ];
84             }
85              
86             # four-of-a-kind
87             sub fours {
88             my @temp;
89             for my $card1 ( 2 .. 14 ) {
90             for my $card2 ( grep { $_ != $card1 } ( 2 .. 14 ) ) {
91             push @temp,
92             join( '',
93             map { sprintf( "%02d", $_ ) }
94             sort { $b <=> $a } ( ($card1) x 4, $card2 ) );
95             }
96             }
97             return [@temp];
98             }
99              
100             # five-of-a-kind
101             sub fives {
102             my @temp;
103             for my $card ( 2 .. 14 ) {
104             push @temp,
105             join( '',
106             map { sprintf( "%02d", $_ ) }
107             ($card) x 5);
108             }
109             return [@temp];
110             }
111              
112             # full house
113             sub houses {
114             my @temp;
115             for my $card1 ( 2 .. 14 ) {
116             for my $card2 ( grep { $_ != $card1 } ( 2 .. 14 ) ) {
117             push @temp,
118             join( '',
119             map { sprintf( "%02d", $_ ) }
120             sort { $b <=> $a } ( ($card1) x 3, ($card2) x 2 ) );
121             }
122             }
123             return [@temp];
124             }
125              
126             # three-of-a-kind
127             sub threes {
128             my @temp;
129             for my $card ( 2 .. 14 ) {
130             for my $c (
131             reverse combinations( [ reverse grep { $_ != $card } ( 2 .. 14 ) ], 2 ) )
132             {
133             push @temp, join(
134             '',
135             map { sprintf( "%02d", $_ ) }
136              
137             sort { $b <=> $a } ($card) x 3, @$c
138             );
139             }
140             }
141             return [@temp];
142             }
143              
144             # two pair
145             sub two_pair {
146             my @temp;
147             for my $c ( reverse combinations( [ reverse( 2 .. 14 ) ], 2 ) ) {
148             for my $card ( grep { $_ != $c->[0] && $_ != $c->[1] } ( 2 .. 14 ) ) {
149             push @temp,
150             join( '',
151             map { sprintf( "%02d", $_ ) }
152             sort { $b <=> $a } ( ( $c->[0] ) x 2, ( $c->[1] ) x 2, $card ) );
153             }
154             }
155             return [@temp];
156             }
157              
158             # one pair
159             sub one_pair {
160             my @temp;
161             for my $card ( 2 .. 14 ) {
162             for my $c (
163             reverse combinations( [ reverse grep { $_ != $card } ( 2 .. 14 ) ], 3 ) )
164             {
165             push @temp,
166             join( '',
167             map { sprintf( "%02d", $_ ) }
168             sort { $b <=> $a } ( ($card) x 2, @$c ) );
169             }
170             }
171             return [@temp];
172             }
173              
174             # non-straight flushes
175             sub flushes {
176             my $self = shift;
177             return [ map { $_ . 's' } @{ $self->unpaired } ];
178             }
179              
180             # straight flushes
181             sub straight_flushes {
182             my $self = shift;
183             return [ map { $_ . 's' } @{ $self->straights } ];
184             }
185              
186             =head1 AUTHOR
187              
188             Nathaniel Graham, C<< >>
189              
190             =head1 LICENSE AND COPYRIGHT
191              
192             Copyright 2016 Nathaniel Graham.
193              
194             This program is free software; you can redistribute it and/or modify it
195             under the terms of the the Artistic License (2.0). You may obtain a
196             copy of the full license at:
197              
198             L
199              
200             =cut
201              
202             1;