File Coverage

blib/lib/Poker/Score/High.pm
Criterion Covered Total %
statement 6 106 5.6
branch 0 2 0.0
condition n/a
subroutine 2 13 15.3
pod 0 8 0.0
total 8 129 6.2


line stmt bran cond sub pod time code
1             package Poker::Score::High;
2 1     1   863 use Moo;
  1         1  
  1         4  
3 1     1   165 use Algorithm::Combinatorics qw(combinations);
  1         1  
  1         902  
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 0     0     my $self = shift;
27 0           my %map = ( 1 => 'a High Card' );
28 0           my @hands = @{ $self->unpaired };
  0            
29 0           $map{ $#hands } = 'One Pair';
30 0           push(@hands, @{ $self->one_pair });
  0            
31 0           $map{ $#hands } = 'Two Pair';
32 0           push(@hands, @{ $self->two_pair });
  0            
33 0           $map{ $#hands } = 'Three-of-a-Kind';
34 0           push(@hands, @{ $self->threes });
  0            
35 0           $map{ $#hands } = 'a Straight';
36 0           push(@hands, @{ $self->straights });
  0            
37 0           $map{ $#hands } = 'a Flush';
38 0           push(@hands, @{ $self->flushes });
  0            
39 0           $map{ $#hands } = 'a Full House';
40 0           push(@hands, @{ $self->houses });
  0            
41 0           $map{ $#hands } = 'Four-of-a-Kind';
42 0           push(@hands, @{ $self->fours });
  0            
43 0           $map{ $#hands } = 'a Straight Flush';
44 0           push(@hands, @{ $self->straight_flushes });
  0            
45 0           $map{ $#hands } = 'Five-of-a-Kind';
46 0           push(@hands, @{ $self->fives });
  0            
47 0           $self->hands( [ @hands ] );
48 0           $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 0     0     '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 0     0     my $self = shift;
76 0           my %straight = map { $_, 1 } @{ $self->straights };
  0            
  0            
77 0           my $iter = combinations( [ reverse( 2 .. 14 ) ], 5 );
78 0           my @unpaired;
79 0           while ( my $c = $iter->next ) {
80             push @unpaired,
81 0           join( '', map { sprintf( "%02d", $_ ) } sort { $b <=> $a } @$c );
  0            
  0            
82             }
83 0           return [ grep { !exists $straight{$_} } sort { $a <=> $b } @unpaired ];
  0            
  0            
84             }
85              
86             # four-of-a-kind
87             sub fours {
88 0     0 0   my @temp;
89 0           for my $card1 ( 2 .. 14 ) {
90 0           for my $card2 ( grep { $_ != $card1 } ( 2 .. 14 ) ) {
  0            
91             push @temp,
92             join( '',
93 0           map { sprintf( "%02d", $_ ) }
94 0           sort { $b <=> $a } ( ($card1) x 4, $card2 ) );
  0            
95             }
96             }
97 0           return [@temp];
98             }
99              
100             # five-of-a-kind
101             sub fives {
102 0     0 0   my @temp;
103 0           for my $card ( 2 .. 14 ) {
104             push @temp,
105             join( '',
106 0           map { sprintf( "%02d", $_ ) }
  0            
107             ($card) x 5);
108             }
109 0           return [@temp];
110             }
111              
112             # full house
113             sub houses {
114 0     0 0   my @temp;
115 0           for my $card1 ( 2 .. 14 ) {
116 0           for my $card2 ( grep { $_ != $card1 } ( 2 .. 14 ) ) {
  0            
117             push @temp,
118             join( '',
119 0           map { sprintf( "%02d", $_ ) }
120 0           sort { $b <=> $a } ( ($card1) x 3, ($card2) x 2 ) );
  0            
121             }
122             }
123 0           return [@temp];
124             }
125              
126             # three-of-a-kind
127             sub threes {
128 0     0 0   my @temp;
129 0           for my $card ( 2 .. 14 ) {
130 0           for my $c (
131 0           reverse combinations( [ reverse grep { $_ != $card } ( 2 .. 14 ) ], 2 ) )
132             {
133             push @temp, join(
134             '',
135 0           map { sprintf( "%02d", $_ ) }
136              
137 0           sort { $b <=> $a } ($card) x 3, @$c
  0            
138             );
139             }
140             }
141 0           return [@temp];
142             }
143              
144             # two pair
145             sub two_pair {
146 0     0 0   my @temp;
147 0           for my $c ( reverse combinations( [ reverse( 2 .. 14 ) ], 2 ) ) {
148 0 0         for my $card ( grep { $_ != $c->[0] && $_ != $c->[1] } ( 2 .. 14 ) ) {
  0            
149             push @temp,
150             join( '',
151 0           map { sprintf( "%02d", $_ ) }
152 0           sort { $b <=> $a } ( ( $c->[0] ) x 2, ( $c->[1] ) x 2, $card ) );
  0            
153             }
154             }
155 0           return [@temp];
156             }
157              
158             # one pair
159             sub one_pair {
160 0     0 0   my @temp;
161 0           for my $card ( 2 .. 14 ) {
162 0           for my $c (
163 0           reverse combinations( [ reverse grep { $_ != $card } ( 2 .. 14 ) ], 3 ) )
164             {
165             push @temp,
166             join( '',
167 0           map { sprintf( "%02d", $_ ) }
168 0           sort { $b <=> $a } ( ($card) x 2, @$c ) );
  0            
169             }
170             }
171 0           return [@temp];
172             }
173              
174             # non-straight flushes
175             sub flushes {
176 0     0 0   my $self = shift;
177 0           return [ map { $_ . 's' } @{ $self->unpaired } ];
  0            
  0            
178             }
179              
180             # straight flushes
181             sub straight_flushes {
182 0     0 0   my $self = shift;
183 0           return [ map { $_ . 's' } @{ $self->straights } ];
  0            
  0            
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;