File Coverage

blib/lib/Games/JackThief.pm
Criterion Covered Total %
statement 109 120 90.8
branch 26 36 72.2
condition 18 24 75.0
subroutine 12 12 100.0
pod 0 6 0.0
total 165 198 83.3


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   34908 use 5.006;
  4         12  
  4         160  
63 4     4   24 use strict;
  4         5  
  4         127  
64 4     4   17 use warnings;
  4         9  
  4         4512  
65            
66             =head1 NAME
67            
68             Games::JackThief - The great new Games::JackThief!
69            
70             =head1 VERSION
71            
72             Version 0.01
73            
74             =cut
75            
76             our $VERSION = '0.01';
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 627 my $Class = shift;
107 5         6 my $Data = shift;
108            
109 5         7 my $Self = {};
110 5         10 bless $Self, $Class;
111            
112 5 100 66     41 $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     31 $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         14 $Self->_GenerateDeckSequence;
116            
117 5         43 return $Self;
118             }
119            
120             #################################
121             ## Creates Hand and Discards the pair
122             sub JackThief_Hand {
123             #################################
124 1     1 0 1 my $Self = shift;
125 1         2 while (scalar @{$Self->{AllCards}} > 0)
  27         51  
126             {
127 26         42 for (my $a = 1; $a <= $Self->{no_of_Players}; $a++)
128             {
129 260 100       167 push(@{$Self->{'Player'.$a}}, pop @{$Self->{AllCards}}) if (scalar @{$Self->{AllCards}} > 0);
  259         277  
  259         661  
  260         367  
130             }
131             }
132 1         5 $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       7 if (scalar (@{$Self->{'Player'.$_}}) == 0)
  10         21  
138             {
139 0         0 print "## Not a valid hand Try again ##\n";
140 0         0 exit;
141             }
142             }
143             #
144 1         5 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         2 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         2 push (@{$Self->{'Player'. $fetch_by}}, $ftchd_card);
  1         2  
158 1         5 $Self->JackThief_DiscardCards(1, $Self->{FetchSeq}[0]);
159            
160 1 50       1 if (scalar @{$Self->{'Player'. $fetch_by}} == 0)
  1 50       5  
161 1         3 {
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         440 $Self->_UpdateFetchSeq(2);
174             }
175            
176 1         4 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       1 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         5 $Self->{FetchSeq} = [1..$Self->{no_of_Players}];
194 1         5 return $Self;
195             }
196            
197             #################################
198             ## Discards the pair
199             sub JackThief_DiscardCards {
200             #################################
201 2     2 0 2 my $Self = shift;
202 2         3 my $Players = shift;
203 2         1 my $a=shift;
204 2 50       5 $Players = (defined $Players) ? $Players : 1;
205 2 100       4 $a = (defined $a) ? $a : 1;
206 2         5 foreach(1..$Players)
207             #for (my $a = 1; $a <= $Players; $a++)
208             {
209 11         17 my $plyr = 'Player'.$a;
210 11         6 @{$Self->{$plyr}} = sort (@{$Self->{$plyr}});
  11         76  
  11         62  
211 11         18 for (my $b = 0; $b < @{$Self->{$plyr}}; $b++)
  182         286  
212             {
213 171 100 66     544 if ((defined $Self->{$plyr}[$b]) && (defined $Self->{$plyr}[$b+1]))
214             {
215 164 100 100     1324 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         96 $Self->{$plyr}[$b] = $Self->{$plyr}[$b+1] = "";
218 69         65 $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 28         37 $Self->{$plyr}[$b] = $Self->{$plyr}[$b+1] = "";
223 28         27 $b++;
224             }
225             }
226             }
227 11         9 @{$Self->{$plyr}} = grep { $_ ne '' } @{$Self->{$plyr}};
  11         43  
  268         253  
  11         14  
228 11         17 $a++
229             }
230 2         3 return $Self;
231             }
232            
233             ##Private methods
234            
235             #################################
236             # rotate the Fetch Seq
237             sub _UpdateFetchSeq {
238             #################################
239 1     1   3 my $Self = shift;
240 1         1 my $arg = shift;
241            
242 1 50       6 if (!$arg)
    50          
    50          
243             {
244 0         0 shift $Self->{FetchSeq};
245             }
246             elsif($arg == 1)
247             {
248 0         0 my $tmp = shift $Self->{FetchSeq};
249 0         0 shift $Self->{FetchSeq};
250 0         0 push (@{$Self->{FetchSeq}}, $tmp);
  0         0  
251             }
252             elsif($arg == 2)
253             {
254 1         3 my $tmp = shift $Self->{FetchSeq};
255 1         1 push (@{$Self->{FetchSeq}}, $tmp);
  1         4  
256             }
257 1         2 return $Self;
258             }
259            
260             #################################
261             ## generates the cards sequences and drops one jack
262             sub _GenerateDeckSequence {
263             #################################
264 5     5   5 my $Self = shift;
265 5         13 my @DeckTypes = ('Heart', 'Diamond', 'Spade', 'Club');
266 5         12 my @DeckNumbers = ('A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K');
267 5         2 my $i = 1;
268 5         6 my $DropOneJack = 0;
269 5         13 foreach(1..$Self->{no_of_Decks})
270             {
271 13         13 foreach(@DeckTypes) {
272 52         37 my $D = $_;
273 52         45 foreach(@DeckNumbers) {
274 676         471 my $N = $_;
275 676 100 100     1129 if (($N eq "J") && (!$DropOneJack)) { $DropOneJack++; }
  5         5  
276             else {
277             #$Self->{'AllCards'}->{$i}->{$D} = $N;
278 671         461 push(@{$Self->{AllCards}}, $N);
  671         756  
279 671         685 $i++;
280             }
281             }
282             }
283             }
284 5         14 $Self->_shuffle;
285 5         10 return $Self;
286             }
287            
288             #################################
289             ## randomize the sequence of cards
290             sub _shuffle {
291             #################################
292 5     5   6 my $Self = shift;
293 5         6 my $i;
294 5         5 for ($i = @{$Self->{AllCards}}; --$i; ) {
  5         18  
295 666         787 my $j = int rand ($i+1);
296 666 100       837 next if $i == $j;
297 652         455 @{$Self->{AllCards}}[$i,$j] = @{$Self->{AllCards}}[$j,$i];
  652         1311  
  652         638  
298             }
299             }
300            
301             #########################################################################################
302            
303             =head1 AUTHOR
304            
305             Kapil Rathore, C<< >>
306            
307             =head1 BUGS
308            
309             Please report any bugs or feature requests to C, or through
310             the web interface at L. I will be notified, and then you'll
311             automatically be notified of progress on your bug as I make changes.
312            
313            
314            
315            
316             =head1 SUPPORT
317            
318             You can find documentation for this module with the perldoc command.
319            
320             perldoc Games::JackThief
321            
322            
323             You can also look for information at:
324            
325             =over 4
326            
327             =item * RT: CPAN's request tracker (report bugs here)
328            
329             L
330            
331             =item * AnnoCPAN: Annotated CPAN documentation
332            
333             L
334            
335             =item * CPAN Ratings
336            
337             L
338            
339             =item * Search CPAN
340            
341             L
342            
343             =back
344            
345            
346             =head1 ACKNOWLEDGEMENTS
347            
348            
349             =head1 LICENSE AND COPYRIGHT
350            
351             Copyright 2015 Kapil Rathore.
352            
353             This program is free software; you can redistribute it and/or modify it
354             under the terms of the the Artistic License (1.0). You may obtain a
355             copy of the full license at:
356            
357             L
358            
359             Aggregation of this Package with a commercial distribution is always
360             permitted provided that the use of this Package is embedded; that is,
361             when no overt attempt is made to make this Package's interfaces visible
362             to the end user of the commercial distribution. Such use shall not be
363             construed as a distribution of this Package.
364            
365             The name of the Copyright Holder may not be used to endorse or promote
366             products derived from this software without specific prior written
367             permission.
368            
369             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
370             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
371             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
372            
373            
374             =cut
375            
376             1; # End of Games::JackThief