File Coverage

blib/lib/Games/JackThief.pm
Criterion Covered Total %
statement 113 127 88.9
branch 26 36 72.2
condition 18 24 75.0
subroutine 13 13 100.0
pod 0 6 0.0
total 170 206 82.5


line stmt bran cond sub pod time code
1             ##########################################################################################################################################
2             ### Games::JackThief -- 2015, Kapil Rathore
3             ###
4             ### What is JackThief Game ?
5             ###
6             ### This game is played with 51 * (Decks-1) cards. The jokers have no role here and out of 4 jacks,
7             ### one jack is removed which can be of any suit. This game is usually played by 2 players or more.
8             ### After the shuffle, it would be very tedious for the dealer to give one card to each and every player
9             ### since the entire 51 cards have to be distributed amongst all the players equally or nearly equally.
10             ###
11             ### After both the players get their respective bunch of cards, the process of separation begins.
12             ### All paired cards are discarded. For example, if the player 1 has two aces, two Kings, two 10s, two 5s,
13             ### then he will remove these cards. Similarly for cards such as four 7s, four 4s and so on,
14             ### because these form two pairs.
15             ### Once all the cards discarded, player will fetch a random card from neighbouring player,
16             ### he will again discard from his set of cards if match is found. Process continues until the
17             ### player with jack left and became the looser of the game
18             ###
19             ###
20             ### After the pairs are weeded out, both the players will be left with odd number of cards usually one of each,
21             ### since if there are three cards of six say, then two of them form pairs and are discarded and only one six is left.
22             ###
23             ### This would go on till the all the cards are not discarded except one jack and the player who will be having the Jack
24             ### in the end would be called as JackThief.
25             ###
26             ### How to Run the Games::JackThief ?
27             #####################################################################
28             ### use warnings;
29             ### use strict;
30             ### use Games::JackThief;
31             ### #use Data::Dumper; # To see the process of card Fetching enable this
32             ###
33             ### my $Decks_and_Players = {
34             ### no_of_Decks => 1,
35             ### no_of_Players => 3,
36             ### };
37             ###
38             ### my $JackThief = Games::JackThief->new($Decks_and_Players); #my $JackThief = Games::JackThief->new(); # Still Works and Takes default values
39             ### $JackThief->JackThief_Hand;
40             ### $JackThief->CreateFetchSeq;
41             ### do
42             ### {
43             ### #print Dumper($JackThief); # To see the process of card Fetching enable this
44             ### #print "\n\n#####\n\n"; # To see the process of card Fetching enable this
45             ### $JackThief->JackThief_RunFetchRound;
46             ### #; # To see the process of card Fetching enable this
47             ### } while($JackThief->LooserFound);
48             ###
49             ### print "Looser is Player $JackThief->{FetchSeq}[0]\n";
50             ### ########## END #############
51             ###
52             ####
53             ######################################################################
54             ### How to Run the Games::JackThief ?
55             ### 1) Defining the hash with information of no_of_Decks and no_of_Players.
56             ### 2) Taking the JackThief object --> generating the valid Deck Sequence of 51*(Decks-1) cards ---> Randomizing the sequence
57             ### 3) Now Distributing the cards to each players --> the process of separation begins and players discards the cards of same type
58             ### 4) create a circular fetch sequence --> after fetch player will discard the card --> Rotations goes until the loose with Jack is found
59             ###############################################################################################################################################
60             package Games::JackThief;
61            
62 4     4   41661 use 5.006;
  4         12  
  4         150  
63 4     4   19 use strict;
  4         6  
  4         120  
64 4     4   17 use warnings;
  4         10  
  4         101  
65 4     4   2770 use Data::Dumper;
  4         32870  
  4         4372  
66             =head1 NAME
67            
68             Games::JackThief - The great new Games::JackThief!
69            
70             =head1 VERSION
71            
72             Version 0.02
73            
74             =cut
75            
76             our $VERSION = '0.02';
77            
78            
79             =head1 SYNOPSIS
80            
81             Quick summary of what the module does.
82            
83             Perhaps a little code snippet.
84            
85             use Games::JackThief;
86            
87             my $foo = Games::JackThief->new();
88             ...
89            
90             =head1 EXPORT
91            
92             A list of functions that can be exported. You can delete this section
93             if you don't export anything, such as for a purely object-oriented module.
94            
95             =head1 SUBROUTINES/METHODS
96            
97             =head2 function1
98            
99             =cut
100            
101            
102             #################################
103             ## Constructor -> GenerateDeckSequence -> Shuffle
104             sub new {
105             #################################
106 5     5 0 1153 my $Class = shift;
107 5         7 my $Data = shift;
108            
109 5         8 my $Self = {};
110 5         15 bless $Self, $Class;
111            
112 5 100 66     54 $Self->{no_of_Decks} = (defined $Data->{no_of_Decks} && $Data->{no_of_Decks} > 0 && $Data->{no_of_Decks} <= 5) ? $Data->{no_of_Decks} : 1;
113 5 100 66     44 $Self->{no_of_Players} = (defined $Data->{no_of_Players} && $Data->{no_of_Players} > 2 && $Data->{no_of_Players} <= 10) ? $Data->{no_of_Players} : 2;
114            
115 5         17 $Self->_GenerateDeckSequence;
116            
117 5         62 return $Self;
118             }
119            
120             #################################
121             ## Creates Hand and Discards the pair
122             sub JackThief_Hand {
123             #################################
124 1     1 0 2 my $Self = shift;
125 1         2 while (scalar @{$Self->{AllCards}} > 0)
  27         39  
126             {
127 26         63 for (my $a = 1; $a <= $Self->{no_of_Players}; $a++)
128             {
129 260 100       152 push(@{$Self->{'Player'.$a}}, pop @{$Self->{AllCards}}) if (scalar @{$Self->{AllCards}} > 0);
  259         247  
  259         460  
  260         377  
130             }
131             }
132 1         4 $Self->JackThief_DiscardCards($Self->{no_of_Players});
133             # valid hand to start
134 1         2 my $ValidHand = 1;
135 1         3 foreach(1..$Self->{no_of_Players})
136             {
137 10 50       6 if (scalar (@{$Self->{'Player'.$_}}) == 0)
  10         22  
138             {
139 0         0 print "## Not a valid hand Try again ##\n";
140 0         0 exit;
141             }
142             }
143             #
144 1         6 return $Self;
145             }
146            
147             #################################
148             # Run the Fetch Sequence until looser found
149             sub JackThief_RunFetchRound {
150             #################################
151 1     1 0 2 my $Self = shift;
152 1         2 my $fetch_by = $Self->{FetchSeq}[0];
153 1         2 my $fetch_from = $Self->{FetchSeq}[1];
154            
155 1         1 my $randSel = int rand @{$Self->{'Player'. $fetch_from}};
  1         5  
156 1         1 my $ftchd_card = splice(@{$Self->{'Player'. $fetch_from}}, $randSel , 1);
  1         4  
157 1         1 push (@{$Self->{'Player'. $fetch_by}}, $ftchd_card);
  1         3  
158 1         2 $Self->JackThief_DiscardCards(1, $Self->{FetchSeq}[0]);
159            
160 1 50       2 if (scalar @{$Self->{'Player'. $fetch_by}} == 0)
  1 50       4  
161 1         4 {
162             # $fetch_by player wins here;
163 0         0 $Self->_UpdateFetchSeq(0);
164             }
165             elsif (scalar @{$Self->{'Player'. $fetch_from }} == 0)
166             {
167             # $fetch_from player wins here;
168 0         0 $Self->_UpdateFetchSeq(1);
169             }
170             else
171             {
172             # non of the player wins;
173 1         2 $Self->_UpdateFetchSeq(2);
174             }
175            
176 1         3 return $Self;
177             }
178            
179             #################################
180             # Check looser found or not
181             sub LooserFound {
182             #################################
183 1     1 0 1 my $Self = shift;
184 1 50       2 return 1 if (scalar (@{$Self->{FetchSeq}}) > 1);
  1         6  
185 0 0       0 return 0 if (scalar (@{$Self->{FetchSeq}}) == 1);
  0         0  
186             }
187            
188             #################################
189             # it actually creates the Fetch Seq
190             sub CreateFetchSeq {
191             #################################
192 1     1 0 2 my $Self = shift;
193 1         4 $Self->{FetchSeq} = [1..$Self->{no_of_Players}];
194 1         3 return $Self;
195             }
196            
197             #################################
198             ## Discards the pair
199             sub JackThief_DiscardCards {
200             #################################
201 2     2 0 4 my $Self = shift;
202 2         2 my $Players = shift;
203 2         2 my $a=shift;
204 2 50       390 $Players = (defined $Players) ? $Players : 1;
205 2 100       5 $a = (defined $a) ? $a : 1;
206 2         4 foreach(1..$Players)
207             #for (my $a = 1; $a <= $Players; $a++)
208             {
209 11         14 my $plyr = 'Player'.$a;
210 11         12 @{$Self->{$plyr}} = sort (@{$Self->{$plyr}});
  11         70  
  11         58  
211 11         15 for (my $b = 0; $b < @{$Self->{$plyr}}; $b++)
  178         267  
212             {
213 167 100 66     489 if ((defined $Self->{$plyr}[$b]) && (defined $Self->{$plyr}[$b+1]))
214             {
215 160 100 100     1197 if ((($Self->{$plyr}[$b] =~ m/\d+/) && ($Self->{$plyr}[$b+1] =~ m/\d+/)) && ($Self->{$plyr}[$b] == $Self->{$plyr}[$b+1]))
    100 100        
      33        
      66        
216             {
217 69         84 $Self->{$plyr}[$b] = $Self->{$plyr}[$b+1] = "";
218 69         63 $b++;
219             }
220             elsif((($Self->{$plyr}[$b] =~ m/\w+/i) && ($Self->{$plyr}[$b+1] =~ m/\w+/i)) && ($Self->{$plyr}[$b] eq $Self->{$plyr}[$b+1]))
221             {
222 32         45 $Self->{$plyr}[$b] = $Self->{$plyr}[$b+1] = "";
223 32         27 $b++;
224             }
225             }
226             }
227 11         10 @{$Self->{$plyr}} = grep { $_ ne '' } @{$Self->{$plyr}};
  11         31  
  268         257  
  11         16  
228 11         14 $a++
229             }
230 2         4 return $Self;
231             }
232            
233             ##Private methods
234            
235             #################################
236             # rotate the Fetch Seq
237             sub _UpdateFetchSeq {
238             #################################
239 1     1   2 my $Self = shift;
240 1         2 my $arg = shift;
241 1 50       8 if (!$arg)
    50          
    50          
242             {
243 0         0 shift @{$Self->{FetchSeq}};
  0         0  
244             }
245             elsif($arg == 1)
246             {
247 0         0 my $tmp = shift @{$Self->{FetchSeq}};
  0         0  
248 0         0 shift @{$Self->{FetchSeq}};
  0         0  
249 0         0 push (@{$Self->{FetchSeq}}, $tmp);
  0         0  
250             }
251             elsif($arg == 2)
252             {
253 1         1 my $tmp = shift @{$Self->{FetchSeq}};
  1         2  
254 1         1 push (@{$Self->{FetchSeq}}, $tmp);
  1         2  
255             }
256 1         2 return $Self;
257             }
258            
259             #################################
260             ## generates the cards sequences and drops one jack
261             sub _GenerateDeckSequence {
262             #################################
263 5     5   6 my $Self = shift;
264 5         15 my @DeckTypes = ('Heart', 'Diamond', 'Spade', 'Club');
265 5         21 my @DeckNumbers = ('A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K');
266 5         6 my $i = 1;
267 5         4 my $DropOneJack = 0;
268 5         13 foreach(1..$Self->{no_of_Decks})
269             {
270 13         33 foreach(@DeckTypes) {
271 52         43 my $D = $_;
272 52         49 foreach(@DeckNumbers) {
273 676         457 my $N = $_;
274 676 100 100     1176 if (($N eq "J") && (!$DropOneJack)) { $DropOneJack++; }
  5         6  
275             else {
276             #$Self->{'AllCards'}->{$i}->{$D} = $N;
277 671         420 push(@{$Self->{AllCards}}, $N);
  671         823  
278 671         635 $i++;
279             }
280             }
281             }
282             }
283 5         19 $Self->_shuffle;
284 5         14 return $Self;
285             }
286            
287             #################################
288             ## randomize the sequence of cards
289             sub _shuffle {
290             #################################
291 5     5   8 my $Self = shift;
292 5         10 my $i;
293 5         7 for ($i = @{$Self->{AllCards}}; --$i; ) {
  5         20  
294 666         677 my $j = int rand ($i+1);
295 666 100       844 next if $i == $j;
296 643         420 @{$Self->{AllCards}}[$i,$j] = @{$Self->{AllCards}}[$j,$i];
  643         1328  
  643         718  
297             }
298             }
299            
300             #########################################################################################
301            
302             =head1 AUTHOR
303            
304             Kapil Rathore, C<< >>
305            
306             =head1 BUGS
307            
308             Please report any bugs or feature requests to C, or through
309             the web interface at L. I will be notified, and then you'll
310             automatically be notified of progress on your bug as I make changes.
311            
312            
313            
314            
315             =head1 SUPPORT
316            
317             You can find documentation for this module with the perldoc command.
318            
319             perldoc Games::JackThief
320            
321            
322             You can also look for information at:
323            
324             =over 4
325            
326             =item * RT: CPAN's request tracker (report bugs here)
327            
328             L
329            
330             =item * AnnoCPAN: Annotated CPAN documentation
331            
332             L
333            
334             =item * CPAN Ratings
335            
336             L
337            
338             =item * Search CPAN
339            
340             L
341            
342             =back
343            
344            
345             =head1 ACKNOWLEDGEMENTS
346            
347            
348             =head1 LICENSE AND COPYRIGHT
349            
350             Copyright 2015 Kapil Rathore.
351            
352             This program is free software; you can redistribute it and/or modify it
353             under the terms of the the Artistic License (1.0). You may obtain a
354             copy of the full license at:
355            
356             L
357            
358             Aggregation of this Package with a commercial distribution is always
359             permitted provided that the use of this Package is embedded; that is,
360             when no overt attempt is made to make this Package's interfaces visible
361             to the end user of the commercial distribution. Such use shall not be
362             construed as a distribution of this Package.
363            
364             The name of the Copyright Holder may not be used to endorse or promote
365             products derived from this software without specific prior written
366             permission.
367            
368             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
369             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
370             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
371            
372            
373             =cut
374            
375             1; # End of Games::JackThief