File Coverage

blib/lib/Games/Cards/ShuffleTrack.pm
Criterion Covered Total %
statement 346 348 99.4
branch 113 114 99.1
condition 26 27 96.3
subroutine 58 58 100.0
pod 36 36 100.0
total 579 583 99.3


line stmt bran cond sub pod time code
1             package Games::Cards::ShuffleTrack;
2              
3 19     19   251218 use 5.006;
  19         47  
4 19     19   70 use strict;
  19         21  
  19         316  
5 19     19   58 use warnings;
  19         17  
  19         900  
6              
7 19     19   62 use List::Util qw/any min/;
  19         22  
  19         1624  
8 19     19   8865 use List::MoreUtils qw/zip first_index true/;
  19         146045  
  19         103  
9 19     19   9648 use Scalar::Util qw/looks_like_number/;
  19         26  
  19         51845  
10              
11             =head1 NAME
12              
13             Games::Cards::ShuffleTrack - Track cards through shuffles and cuts
14              
15             =head1 VERSION
16              
17             Version 0.04_1
18              
19             =cut
20              
21             our $VERSION = '0.05';
22              
23             my $cut_limits = {
24             normal => [0.19, 0.82], # on a 52 cards deck, cut between 10 and 43 cards
25             short => [0.09, 0.28], # on a 52 cards deck, cut between 5 and 15 cards
26             center => [0.36, 0.59], # on a 52 cards deck, cut between 19 and 31 cards
27             deep => [0.67, 0.86], # on a 52 cards deck, cut between 35 and 45 cards
28             };
29              
30             my $decks = {
31             empty => [],
32             new_deck_order => [qw/AH 2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH
33             AC 2C 3C 4C 5C 6C 7C 8C 9C 10C JC QC KC
34             KD QD JD 10D 9D 8D 7D 6D 5D 4D 3D 2D AD
35             KS QS JS 10S 9S 8S 7S 6S 5S 4S 3S 2S AS/],
36             fournier => [qw/AS 2S 3S 4S 5S 6S 7S 8S 9S 10S JS QS KS
37             AH 2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH
38             KD QD JD 10D 9D 8D 7D 6D 5D 4D 3D 2D AD
39             KC QC JC 10C 9C 8C 7C 6C 5C 4C 3C 2C AC/],
40             };
41              
42             my $shortcuts = {
43             'top' => 1,
44             'second' => 2,
45             'greek' => -2,
46             'bottom' => -1,
47             };
48              
49             my $expressions = {
50             A => qr/A[CHSD]/,
51             2 => qr/2[CHSD]/,
52             3 => qr/3[CHSD]/,
53             4 => qr/4[CHSD]/,
54             5 => qr/5[CHSD]/,
55             6 => qr/6[CHSD]/,
56             7 => qr/7[CHSD]/,
57             8 => qr/8[CHSD]/,
58             9 => qr/9[CHSD]/,
59             10 => qr/10[CHSD]/,
60             J => qr/J[CHSD]/,
61             Q => qr/Q[CHSD]/,
62             K => qr/K[CHSD]/,
63              
64             C => qr/(?:[A23456789JQK]|10)C/,
65             H => qr/(?:[A23456789JQK]|10)H/,
66             S => qr/(?:[A23456789JQK]|10)S/,
67             D => qr/(?:[A23456789JQK]|10)D/,
68             };
69              
70              
71             =head1 SYNOPSIS
72              
73             This module allows you to simulate shuffles and cuts.
74              
75             use Games::Cards::ShuffleTrack;
76              
77             my $deck = Games::Cards::ShuffleTrack->new();
78              
79             $deck->overhand_shuffle( 2 );
80             $deck->riffle_shuffle();
81             $deck->cut( 'short' );
82             $deck->riffle_shuffle();
83             print "@{$deck->get_deck()}";
84              
85             Or perhaps with more precision:
86              
87             my $deck = Games::Cards::ShuffleTrack->new();
88              
89             $deck->faro_in();
90             $deck->cut( 26 );
91             print $deck->get_deck();
92              
93             See the rest of the documentation for more advanced features. See the examples folder for more detailed usage.
94              
95              
96             =head1 INSTALLATION
97              
98             To install this module, run the following commands:
99              
100             perl Makefile.PL
101             make
102             make test
103             make install
104              
105              
106             =head1 DECK REPRESENTATION
107              
108             At the moment a deck is represented as a list of strings; each string represents a card where the first letter or digit (or digits, in the case of a 10) is the value of the card and the following letter is the suit:
109              
110             C - Clubs
111             H - Hearts
112             S - Spades
113             D - Diamonds
114              
115             As an example, some card representations:
116              
117             AC - Ace of Clubs
118             10S - Ten of Spades
119             4D - 4 of Diamonds
120             KH - King of Hearts
121              
122             Still, you can add whichever cards you want to the deck:
123              
124             $deck->put( 'Joker' ); # place a Joker on top of the deck
125              
126              
127             =head1 SUBROUTINES/METHODS
128              
129             =head2 Standard methods
130              
131             =head3 new
132              
133             Create a new deck.
134              
135             my $deck = Games::Cards::ShuffleTrack->new();
136              
137             The order of the deck is from top to bottom, which means it is the reverse of what you see when you spread a deck in your hands with the cards facing you.
138              
139             When you open most professional decks of cards you'll see the Ace of Spades (AS) in the front; this means it will actually be the 52nd card in the deck, since when you place the cards on the table facing down it will be the bottom card.
140              
141             Currently this module doesn't support specific orders or different orders other than the new deck.
142              
143             The order of the cards is as follows:
144              
145             Ace of Hearths through King of Hearts
146             Ace of Clubs through King of Clubs
147             King of Diamonds through Ace of Diamonds
148             King of Spades through Ace of Spades
149              
150             You can also specify the starting order of the deck among the following:
151              
152             =over 4
153              
154             =item * new_deck_order (the default order)
155              
156             =item * fournier
157              
158             =back
159              
160             my $deck = Games::Cards::ShuffleTrack->new( 'fournier' );
161              
162             You can also set your own order:
163              
164             my $pile = Games::Cards::ShufleTrack->new( [qw/10S JS QS KS AS/] );
165              
166             =cut
167              
168             # TODO: What happens if the user has a typo in the order?
169             sub new {
170 41     41 1 1251284 my ($self, $order) = @_;
171 41   100     186 $order ||= 'new_deck_order';
172              
173 41         42 my $cards;
174 41 100       255 if ( ref $order eq 'ARRAY' ) {
175 1         2 $cards = $order;
176             }
177             else {
178 40         81 $cards = $decks->{ $order };
179             }
180              
181 41         175 return bless {
182             'deck' => $cards,
183             'original' => $cards,
184             'orientation' => 'down',
185             }, $self;
186             }
187              
188             =head3 restart
189              
190             Reset the deck to its original status. The original is whatever you selected when you created the deck.
191              
192             $deck->restart;
193              
194             Do bear in mind that by doing so you are replenishing the deck of whatever cards you took out of it.
195              
196             =cut
197              
198             sub restart {
199 154     154 1 15558 my $self = shift;
200 154         156 return $self->_set_deck( @{$self->{'original'}} );
  154         457  
201             }
202              
203              
204             =head3 size, deck_size
205              
206             Returns the size of the deck.
207              
208             my $size = $deck->deck_size;
209              
210             =cut
211              
212             sub size {
213 97     97 1 819 my $self = shift;
214 97         164 return $self->deck_size;
215             }
216              
217             sub deck_size {
218 683     683 1 1921 my $self = shift;
219 683         450 return scalar @{$self->{'deck'}};
  683         1678  
220             }
221              
222              
223             =head3 original_size
224              
225             Returns the original size of the deck.
226              
227             if ($size < 0.5 * $deck->original_size) {
228             # if the deck has been exausted by over 50%
229             }
230              
231             =cut
232              
233             sub original_size {
234 4     4 1 5 my $self = shift;
235 4         2 return scalar @{$self->{'original'}};
  4         12  
236             }
237              
238              
239             =head3 is_original
240              
241             Checks to see if the order of the deck is still the same as the original order.
242              
243             if ($deck->is_original) {
244             # ...
245             }
246              
247             This method checks for each card and also the orientation of the deck. The only case where the orientation of the deck doesn't matter is when the deck is empty, in which case that property is ignored.
248              
249             =cut
250              
251             sub is_original {
252 16     16 1 21 my $self = shift;
253              
254             # check size
255 16         13 my @original = @{$self->{'original'}};
  16         58  
256 16 100       30 if ( $self->size != @original ) {
257 2         7 return 0;
258             }
259              
260 14 100       18 $self->size || return 1;
261              
262             # check orientation
263 11 100       18 if ( $self->orientation ne 'down' ) {
264 1         4 return 0;
265             }
266            
267             # check order
268 10         7 my @deck = @{$self->get_deck};
  10         14  
269 10         24 for ( 0 .. $#deck ) {
270 265 100       374 $deck[$_] eq $original[$_] || return 0;
271             }
272              
273 5         26 return 1;
274             }
275              
276              
277             =head3 get_deck
278              
279             Returns the deck (a reference to a list of strings).
280              
281             my $cards = $deck->get_deck();
282              
283             =cut
284              
285             # TODO: should we return a copy of the list instead of the list itself?
286             # TODO: use wantarray to allow for an array to be returned?
287             sub get_deck {
288 1290     1290 1 1083 my $self = shift;
289 1290         3704 return $self->{'deck'};
290             }
291              
292              
293             =head3 orientation
294              
295             Return whether the deck is face up or face down:
296              
297             if ( $deck->orientation eq 'down' ) {
298             ...
299             }
300              
301             The deck's orientation is either 'up' or 'down'.
302              
303             =cut
304              
305             sub orientation {
306 32     32 1 27 my $self = shift;
307              
308 32         83 return $self->{'orientation'};
309             }
310              
311              
312             =head3 turn
313              
314             If the deck was face up, it is turned face down; if the deck was face down, it is turned face up.
315              
316             Turning the deck reverses its order.
317              
318             $deck->turn;
319              
320             =cut
321              
322             sub turn {
323 18     18 1 17 my $self = shift;
324              
325 18 100       27 $self->{'orientation'} = $self->orientation eq 'down' ? 'up' : 'down';
326              
327 18         17 return $self->_set_deck( reverse @{$self->get_deck} );
  18         26  
328             }
329              
330             =head3 count
331              
332             Counts how many cards with specific characteristics are in the deck.
333              
334             # how many tens
335             $deck->count( '10' );
336              
337             # how many Clubs
338             $deck->count( 'C' );
339              
340             # how many Clubs and Hearts
341             my ($clubs, $hearts) = $deck->count( 'C', 'H' );
342             my $clubs_and_hearts = $deck->count( 'C', 'H' );
343              
344             # how many Jokers
345             $deck->count( 'Joker' );
346              
347             Since you can add whichever card you want to the deck, it should be noted how searching for values and suits works:
348              
349             =over 4
350              
351             =item * If looking for a value from 2 to A, you'll get the amount of cards with that value and one of the four suits
352              
353             =item * If looking for a suit (C, H, S, D), you'll get the amount of cards with a value from 2 through Ace and that suit
354              
355             =item * If looking for anything else, that something is compared to the whole card
356              
357             =back
358              
359             It is important to note:
360              
361             my $total = $deck->count( 'JC' ); # holds 4
362             my $total = $deck->count( 'C', 'J' ); # holds 16, because the JC is only counted once
363             my @total = $deck->count( 'C', 'J' ); # holds (13, 4)
364              
365             Also:
366              
367             $deck->put( 'Joker' );
368             $deck->put( 'Signed Joker' );
369             $deck->count( 'Joker' ); # returns 2
370              
371             $deck->put( 'Signed 4C' );
372             $deck->count( '4C' ); # returns 2, because you didn't removed the previous one
373              
374             =cut
375              
376             sub count {
377 40     40 1 3707 my $self = shift;
378 40         38 my @results;
379              
380 40 100 100     140 if ( wantarray and @_ > 1 ) {
381 3         7 return $self->_count_each( @_ );
382             }
383             else {
384 37         75 return $self->_count_all( @_ );
385             }
386             }
387              
388             sub _count_each {
389 3     3   3 my $self = shift;
390 3         3 my @results;
391 3         9 while (my $param = shift) {
392 6 100       12 if ( exists $expressions->{$param} ) {
393 5     264   12 push @results, true { /$expressions->{$param}/ } @{$self->get_deck};
  264         335  
  5         7  
394             }
395             else {
396 1     52   4 push @results, true { /$param/ } @{$self->get_deck};
  52         47  
  1         2  
397             }
398             }
399 3         17 return @results;
400             }
401              
402             sub _count_all {
403 37     37   27 my $self = shift;
404              
405 37         26 my @expressions;
406 37         57 for my $param (@_) {
407             push @expressions, exists $expressions->{$param} ?
408 42 100       175 $expressions->{$param} :
409             qr/$param/x,
410             }
411              
412 37         35 my @results;
413 37         27 for my $card (@{$self->get_deck}) {
  37         58  
414              
415 1856 100   2070   3372 if (any { $card =~ $_ } @expressions) {
  2070         5899  
416 262         492 push @results, $card;
417             }
418              
419             }
420 37         165 return scalar @results;
421             }
422              
423              
424             =head2 Shuffling
425              
426             =head3 Overhand Shuffle
427              
428             =head4 overhand_shuffle
429              
430             In an overhand shuffle the cards are moved from hand to the other in packets, the result being similar to that of running cuts (the difference being that the packets in an overhand shuffle may be smaller than the ones in a running cut sequence).
431              
432             $deck->overhand_shuffle;
433              
434             You can specify how many times you want to go through the deck (which is basically the same thing as calling the method that many times):
435              
436             $deck->overhand_shuffle( 2 );
437              
438             =cut
439              
440             sub overhand_shuffle {
441 7     7 1 12 my $self = shift;
442 7         8 my $times = shift;
443              
444 7 100       15 if (not defined $times) {
445 2         3 $times = 1;
446             }
447              
448 7 100       16 return $self if $times < 1;
449              
450 5         25 $self->_packet_transfer( 1, 10 );
451              
452 5 100       27 return $times > 1 ?
453             $self->overhand_shuffle( $times - 1 ) :
454             $self
455             }
456              
457              
458             =head4 run
459              
460             The act of running cards is similar to the overhand shuffle, but instead of in packets the cards are run singly.
461              
462             $deck->run( 10 );
463              
464             When running cards you can choose whether to drop those cards on the top or on the bottom of the deck. By default, the cards are moved to the bottom of the deck.
465              
466             $deck->run( 10, 'drop-top' );
467             $deck->run( 10, 'drop-bottom' );
468              
469             Running cards basically reverses their order.
470              
471             If no number is given then no cards are run.
472              
473             If we're doing multiple runs we can set everything at the same time:
474              
475             $deck->run( 4, 6, 2 );
476              
477             =cut
478              
479             # TODO: review this code
480             sub run {
481 15     15 1 22 my $self = shift;
482              
483 15         10 my @number_of_cards;
484             my $where_to_drop;
485              
486 15         30 while ( my $param = shift ) {
487 18 100       36 if ( looks_like_number( $param ) ) {
488 9         19 push @number_of_cards, $param;
489             }
490             else {
491 9         17 $where_to_drop = $param;
492             }
493             }
494              
495 15 100       41 @number_of_cards || return $self;
496 8   100     22 $where_to_drop ||= 'drop-bottom';
497              
498 8         5 my $number_of_cards = shift @number_of_cards;
499 8 100       16 $number_of_cards > 0 or return $self;
500              
501             # take cards from top and reverse their order
502 7         5 my @deck = @{$self->get_deck};
  7         7  
503 7         14 my @run = reverse splice @deck, 0, $number_of_cards;
504              
505 7 100       11 if ( $where_to_drop eq 'drop-top' ) {
506 2         4 $self->_set_deck( @run, @deck );
507             }
508             else { # drop-bottom is the default
509 5         6 $self->_set_deck( @deck, @run );
510             }
511              
512 7         23 return $self->run( @number_of_cards, $where_to_drop );
513             }
514              
515              
516             =head3 Hindu Shuffle
517              
518             =head4 hindu_shuffle
519              
520             In a Hindu shuffle the cards are moved from hand to the other in packets, the result being similar to that of running cuts (the difference being that the packets in an overhand shuffle may be smaller than the ones in a running cut sequence).
521              
522             $deck->hindu_shuffle;
523              
524             You can specify how many times you want to go through the deck (which is basically the same thing as calling the method that many times):
525              
526             $deck->hindu_shuffle( 2 );
527              
528             The Hindu shuffle differs in result from the Overhand shuffle in that the packets are usually thicker; the reason for this is that while in the Overhand shuffle it's the thumb that grabs the cards (and the thumb can easily carry just one or two cards) in the Hindu shuffle it's more than one finger accomplishing this task, grabbing the deck by the sides, which makes it more difficult (hence, rare) to cut just one or two cards.
529              
530             =cut
531              
532             sub hindu_shuffle {
533 4     4 1 8 my $self = shift;
534 4   100     15 my $times = shift || 1;
535              
536 4         11 $self->_packet_transfer( 4, 10 );
537              
538 4 100       19 return $times > 1 ?
539             $self->hindu_shuffle( $times - 1 ) :
540             $self
541             }
542              
543             sub _packet_transfer {
544 12     12   9 my $self = shift;
545 12         10 my $min = shift;
546 12         13 my $max = shift;
547              
548 12         7 my @deck = @{$self->get_deck};
  12         15  
549              
550 12         12 my @new_deck;
551              
552 12         22 while ( @deck ) {
553 119 100       163 if (@deck < $max) { $max = scalar @deck }
  29         25  
554 119 100       149 if (@deck < $min) { $min = scalar @deck }
  6         9  
555 119         116 unshift @new_deck, splice @deck, 0, _rand( $min, $max );
556             }
557              
558 12         23 return $self->_set_deck( @new_deck );
559             }
560              
561              
562             =head3 Riffle Shuffle
563              
564             =head4 riffle_shuffle
565              
566             Riffle shuffle the deck.
567              
568             $deck->riffle_shuffle();
569              
570             In the act of riffle shuffling a deck the deck is cut into two halves of approximately the same size; each half is riffled so that the cards of both halves interlace; these cards usually drop in groups of 1 to 5 cards.
571              
572             You can also decide where to cut the deck for the shuffle:
573              
574             $deck->riffle_shuffle( 'short' ); # closer to the top
575             $deck->riffle_shuffle( 'center' ); # near the center
576             $deck->riffle_shuffle( 'deep' ); # closer to the bottom
577             $deck->riffle_shuffle( 26 ); # precisely under the 26th card
578              
579             =cut
580              
581             # TODO: add an option for an out-shuffle
582             # TODO: add an option to control top or bottom stock
583             # TODO: when dropping cards, should we favor numbers 2 and 3?
584             # TODO: with a lot of cards, the riffle should be done breaking the deck in piles
585             # TODO: consider how fast each half is being depleted and whether the packets riffled on each side are of similar sizes
586             sub riffle_shuffle {
587 7     7 1 19 my $self = shift;
588 7         5 my $depth = shift;
589              
590             # cut the deck (left pile is the original top half)
591 7         18 my $cut_depth = _cut_depth( $self->deck_size, $depth );
592              
593 7         7 my @left_pile = @{$self->get_deck};
  7         12  
594 7         23 my @right_pile = splice @left_pile, $cut_depth;
595              
596 7         15 my @halves = ( \@left_pile, \@right_pile );
597              
598             # drop cards from the bottom of each half to the pile (1-5 at a time)
599 7         6 my @new_pile = ();
600 7   100     29 while ( @left_pile and @right_pile ) {
601 72         44 my $current_half = $halves[0];
602 72         112 my $number_of_cards = int(rand( min(5, scalar @$current_half) ))+1;
603              
604 72         106 unshift @new_pile, splice @$current_half, -$number_of_cards;
605              
606 72         197 @halves = reverse @halves;
607             }
608              
609             # drop the balance on top and set the deck to be the result
610 7         19 $self->_set_deck( @left_pile, @right_pile, @new_pile );
611              
612 7         29 return $self;
613             }
614              
615              
616             =head3 Faro shuffle
617              
618             In a faro shuffle the deck is split in half and the two halves are interlaced perfectly so that each card from one half is inserted in between two cards from the opposite half.
619              
620             =head4 faro out
621              
622             Faro out the deck.
623              
624             $deck->faro( 'out' );
625              
626             In a "faro out" the top and bottom cards remain in their original positions.
627              
628             Considering the positions on the cards from 1 to 52 the result of the faro would be as follows:
629              
630             1, 27, 2, 28, 3, 29, 4, 30, 5, 31, 6, 32, 7, 33, ...
631              
632             =head4 faro in
633              
634             Faro in the deck.
635              
636             $deck->faro( 'in' );
637              
638             In a "faro in" the top and bottom cards do not remain in their original positions (top card becomes second from the top, bottom card becomes second from the bottom).
639              
640             Considering the positions on the cards from 1 to 52 the result of the faro would be as follows:
641              
642             27, 1, 28, 2, 29, 3, 30, 4, 31, 5, 32, 6, 33, 7, ...
643              
644             =cut
645              
646             sub faro {
647 60     60 1 1697 my $self = shift;
648 60         43 my $faro = shift; # by default we're doing a faro out
649              
650             # TODO: what happens when the deck is odd-sized?
651 60         38 my @first_half = @{$self->get_deck};
  60         92  
652 60         70 my @second_half = splice @first_half, $self->deck_size / 2;
653              
654 60 100       429 $self->_set_deck(
655             $faro eq 'in' ?
656             zip @second_half, @first_half :
657             zip @first_half, @second_half
658             );
659              
660 60         384 return $self;
661             }
662              
663              
664             =head2 Cutting
665              
666             =head3 cut
667              
668             Cut the deck.
669              
670             $deck->cut();
671              
672             In a 52 cards deck, this would cut somewhere between 10 and 43 cards.
673              
674             Cut at a precise position (moving X cards from top to bottom):
675              
676             $deck->cut(26);
677              
678             If you try to cut to a position that doesn't exist nothing will happen (apart from a warning that you tried to cut to a non-existing position, of course).
679              
680             You can also cut at negative positions, meaning that you're counting from the bottom of the deck and cutting above that card. For instance, to cut the bottom two cards to the top:
681              
682             $deck->cut(-2);
683              
684             Additional ways of cutting:
685              
686             $deck->cut( 'short' ); # on a 52 cards deck, somewhere between 5 and 15 cards
687             $deck->cut( 'center' ); # on a 52 cards deck, somewhere between 19 and 31 cards
688             $deck->cut( 'deep' ); # on a 52 cards deck, somewhere between 35 and 45 cards
689              
690             =head3 cut_below
691              
692             You can cut below a specific card.
693              
694             $deck->cut_below( '9D' );
695              
696             If the desired card is already on the bottom of the deck nothing will happen.
697              
698             For more information on how to cut to a specific card please refer to the L section of this documentation.
699              
700             =head3 cut_above
701              
702             You can cut above a specific card.
703              
704             $deck->cut_above( 'JS' );
705              
706             If the desired card is already on top of the deck nothing will happen.
707              
708             For more information on how to cut to a specific card please refer to the L section of this documentation.
709              
710             =cut
711              
712             # TODO: delimit randomness of the cut between two numbers: $deck->cut( 1, 25 );
713             sub cut {
714 27     27 1 40 my $self = shift;
715 27         23 my $position = shift;
716              
717 27 50 100     138 if ( defined $position
      66        
718             and looks_like_number( $position )
719             and abs($position) > $self->deck_size ) {
720 0         0 warn "Tried to cut the deck at a non-existing position ($position).\n";
721 0         0 return $self;
722             }
723              
724 27         36 my $cut_depth = _cut_depth( $self->deck_size, $position );
725              
726 27         25 my @deck = @{$self->get_deck};
  27         35  
727 27         133 unshift @deck, splice @deck, $cut_depth;
728              
729 27         73 return $self->_set_deck( @deck );
730             }
731              
732             sub cut_below {
733 5     5 1 811 my $self = shift;
734 5         6 my $card = shift;
735              
736 5         9 return $self->cut( $self->find( $card ) );
737             }
738              
739             sub cut_above {
740 6     6 1 1287 my $self = shift;
741 6         7 my $card = shift;
742              
743 6         11 return $self->cut( $self->find( $card ) - 1 );
744             }
745              
746             =head3 cut_to
747              
748             Cuts a portion of the deck to another position
749              
750             $deck->cut_to( $pile );
751              
752             You can specify exactly how many cards to cut or delimit the randomness of the cut:
753              
754             # cut exactly 15 cards to $pile
755             $deck->cut_to( $pile, 15 );
756              
757             # cut between 10 and 26 cards to $pile
758             $deck->cut_to( $pile, 10, 26 );
759              
760             If the position doesn't exist yet you can also automatically create it:
761              
762             my $pile = $deck->cut_to();
763              
764             This method returns the new pile.
765              
766             =cut
767              
768             # FIXME: in some situations this method alters the original order of the deck
769             sub cut_to {
770 21     21 1 22 my $self = shift;
771              
772             # create the new pile if required
773 21         18 my $new_pile;
774 21 100 100     92 if ( defined($_[0]) and ref( $_[0] ) eq 'Games::Cards::ShuffleTrack' ) {
775 12         13 $new_pile = shift;
776             }
777             else {
778 9         22 $new_pile = Games::Cards::ShuffleTrack->new( 'empty' );
779             }
780              
781             # TODO: could this be done with _cut_depth? (perhaps changing it a bit)
782             # set the position
783 21         17 my $lower_limit = shift;
784 21         15 my $upper_limit = shift;
785              
786 21         16 my $position;
787              
788 21 100       45 if ( not defined $lower_limit ) {
    100          
789 2         4 $position = _rand( 1, $self->deck_size );
790             }
791             elsif ( not defined $upper_limit ) {
792 11         11 $position = $lower_limit;
793             }
794             else {
795 8         14 $position = _rand( $lower_limit, $upper_limit );
796             }
797              
798             # cut the deck
799 21         16 $new_pile->place_on_top( splice @{$self->get_deck}, 0, $position );
  21         26  
800              
801 21         37 return $new_pile;
802             }
803              
804              
805             =head3 place_on_top
806              
807             Places a pile of cards on top of the deck.
808              
809             $deck->place_on_top( qw/AS KS QS JS 10S/ );
810              
811             =cut
812              
813             # TODO place_on_top and put share similar code; review
814             sub place_on_top {
815 22     22 1 17 my $self = shift;
816 22         48 my @pile = @_;
817              
818 22         17 $self->_set_deck( @pile, @{$self->get_deck} );
  22         22  
819              
820 22         64 return $self;
821             }
822              
823             =head3 complete_cut, move_to
824              
825             Complete the cut by moving all cards from one deck onto another:
826              
827             $deck->complete_cut( $new_pile );
828            
829             # or
830              
831             $deck->move_to( $table );
832              
833             =cut
834              
835             sub complete_cut {
836 8     8 1 7 my $self = shift;
837 8         19 my $destination = shift;
838              
839 8         10 $self->cut_to( $destination, $self->deck_size );
840              
841 8         5 return $self;
842             }
843              
844             sub move_to {
845 8     8 1 6 my $self = shift;
846              
847 8         15 return $self->complete_cut( @_ );
848             }
849              
850              
851             =head3 running_cuts
852              
853             Cut packets:
854              
855             $deck->running_cuts();
856              
857             To do the procedure twice:
858              
859             $deck->running_cuts( 2 );
860              
861             =cut
862              
863             sub running_cuts {
864 3     3 1 6 my $self = shift;
865 3   100     18 my $times = shift || 1;
866              
867 3         10 $self->_packet_transfer( 5, 15 );
868              
869 3 100       16 return $times > 1 ?
870             $self->overhand_shuffle( $times - 1 ) :
871             $self
872             }
873              
874              
875             =head3 bury
876              
877             Buries a group of cards under another group:
878              
879             # bury the top 10 cards under the following 3 cards
880             $deck->bury(10, 3);
881              
882             # move the top card to the 13th position
883             $deck->bury( 1, 12 );
884              
885             =cut
886              
887             sub bury {
888 2     2 1 7 my $self = shift;
889 2         2 my $first_amount = shift;
890 2         2 my $second_amount = shift;
891              
892 2         2 my @deck = @{$self->get_deck};
  2         2  
893              
894 2         7 splice @deck, $second_amount, 0, splice @deck, 0, $first_amount;
895              
896 2         4 $self->_set_deck( @deck );
897              
898 2         7 return $self;
899             }
900              
901              
902             =head2 Handling cards
903              
904             There are a few different methods to track down cards.
905              
906             =head3 find
907              
908             Get the position of specific cards:
909              
910             my $position = $deck->find( 'AS' ); # find the position of the Ace of Spades
911              
912             my @positions = $deck->find( 'AS', 'KH' ); # find the position of two cards
913              
914             If a card is not present on the deck the position returned will be a 0.
915              
916             This method can also return the card at a specific position:
917              
918             my $card = $deck->find( 3 );
919              
920             You can also request a card in a negative position (i.e., from the bottom of the deck). To get the second to last card in the deck:
921              
922             $deck->find( -2 );
923              
924             If you're dealing five hands of poker from the top of the deck, for instance, you can easily find which cards will fall on the dealer's hand:
925              
926             $deck->find( 5, 10, 15, 20, 25 );
927              
928             =cut
929              
930             sub find {
931 424     424 1 28078 my $self = shift;
932 424         542 my @cards = @_;
933              
934 424         309 my @results;
935              
936 424         572 my $deck = $self->get_deck();
937              
938 424         532 for my $card ( @cards ) {
939              
940 462 100       1220 push @results, looks_like_number( $card )
941             ? $self->_find_card_by_position( $card )
942             : $self->_find_card_by_name( $card );
943              
944             }
945              
946 424 100       1210 return wantarray ? @results : $results[0];
947             }
948              
949             sub _find_card_by_position {
950 398     398   278 my $self = shift;
951 398         281 my $card = shift;
952              
953 398 100       480 if ($card) {
954 396 100       601 if ($card > 0) { $card--; }
  368         280  
955 396 100       505 return $card > $self->deck_size - 1 ?
956             q{} :
957             $self->get_deck->[ $card ];
958             }
959             else {
960 2         3 return q{};
961             }
962             }
963              
964             sub _find_card_by_name {
965 64     64   52 my $self = shift;
966 64         56 my $card = shift;
967              
968 64     1506   171 my $position = 1 + first_index { $_ eq $card } @{$self->get_deck};
  1506         995  
  64         80  
969              
970 64 100       223 return $position ? $position : 0;
971             }
972              
973              
974             =head3 find_card_before
975              
976             Finds the card immediately before another card:
977              
978             # return the card immediately before the Ace of Spades
979             $deck->find_card_before( 'AS' );
980              
981             If the specified card is on top of the deck you will get the card on the bottom of the deck.
982              
983             =cut
984              
985             sub find_card_before {
986 2     2 1 3 my $self = shift;
987 2         3 my $card = shift;
988              
989 2         3 my $position = $self->find( $card );
990              
991 2 100       4 if ($position == 1) {
992 1         3 return 0;
993             }
994             else {
995 1         3 return $self->find( $position - 1 );
996             }
997             }
998              
999              
1000             =head3 find_card_after
1001              
1002             Finds the card immediately after another card:
1003              
1004             # return the card immediately after the King of Hearts
1005             $deck->find_card_before( 'KH' );
1006              
1007             If the specified card is on the bottom of the deck you will get the card on the top of the deck.
1008              
1009             =cut
1010              
1011             sub find_card_after {
1012 2     2 1 3 my $self = shift;
1013 2         2 my $card = shift;
1014              
1015 2         3 my $position = 1 + $self->find( $card );
1016            
1017 2 100       3 if ( $position > $self->deck_size ) {
1018 1         3 return 0;
1019             }
1020              
1021 1         2 return $self->find( $self->find( $card ) + 1 );
1022             }
1023              
1024              
1025             =head3 distance
1026              
1027             Find the distance between two cards.
1028              
1029             To find the distance between the Ace of Spades and the King of Hearts:
1030              
1031             $deck->distance( 'AS', 'KH' );
1032              
1033             If the King of Hearts is just after the Ace of Spades, then the result is 1. If it's immediately before, the result is -1.
1034              
1035             =cut
1036              
1037             sub distance {
1038 7     7 1 606 my $self = shift;
1039 7         7 my $first_card = shift;
1040 7         8 my $second_card = shift;
1041              
1042 7         12 return $self->find( $second_card) - $self->find( $first_card );
1043             }
1044              
1045              
1046             =head3 put
1047              
1048             Put a card on top of the deck. This is a new card, and not a card already on the deck.
1049              
1050             $deck->put( $card );
1051              
1052             If the card was already on the deck, you now have a duplicate card.
1053              
1054             =cut
1055              
1056             sub put {
1057 21     21 1 24 my $self = shift;
1058 21         20 my $card = shift;
1059              
1060 21         21 $self->_set_deck( $card, @{$self->get_deck} );
  21         30  
1061              
1062 21         58 return $self;
1063             }
1064              
1065              
1066             =head3 insert
1067              
1068             Inserts a card in a specified position in the deck. If the position isn't specified than the card is inserted somewhere at random.
1069              
1070             # insert a Joker at position 20
1071             $deck->insert( 'Joker', 20 );
1072              
1073             # replace a card somewhere in the deck at random
1074             $deck->insert( $card );
1075              
1076             If the position doesn't exist the card will be replaced at the bottom of the deck.
1077              
1078             You can also add cards to negative positions, meaning that the resulting position will be that negative position:
1079              
1080             # insert card so that it ends up being the last one in the deck
1081             $deck->insert( $card, -1 );
1082              
1083             # insert card so that it ends up being the 10th from the bottom
1084             $deck->insert( $card, -10 );
1085              
1086             =cut
1087              
1088             # TODO: what if the user inserts at position 0?
1089             sub insert {
1090 7     7 1 11 my $self = shift;
1091 7         8 my $card = shift;
1092 7         8 my $position = shift;
1093              
1094 7 100       24 if ( not defined $position ) {
    100          
    100          
1095 1         4 $position = _rand( 1, $self->deck_size );
1096             }
1097             elsif ( $position > $self->deck_size ) {
1098 1         3 $position = $self->deck_size + 1;
1099             }
1100             elsif ( $position < 0 ) {
1101 2         4 $position = $self->deck_size + $position + 2;
1102             }
1103              
1104 7         8 splice @{$self->get_deck}, $position - 1, 0, $card;
  7         14  
1105              
1106 7         16 return $self;
1107             }
1108              
1109              
1110             =head3 deal
1111              
1112             Deals a card, removing it from the deck.
1113              
1114             my $removed_card = $deck->deal();
1115              
1116             Just as in regular gambling, you can deal cards from other positions:
1117              
1118             # deal the second card from the top
1119             my $card = $deck->deal( 'second' );
1120              
1121             # deal the second card from the bottom
1122             my $card = $deck->deal( 'greek' );
1123              
1124             # deal the card from the bottom of the deck
1125             my $card = $deck->deal( 'bottom' );
1126              
1127             For more information on false dealing see the L section.
1128              
1129             If you're dealing cards to a pile you can actually state where you're dealing:
1130              
1131             $deck->deal( $pile );
1132              
1133             You can still do a false deal to a pile:
1134              
1135             $deck->deal( 'second', $pile );
1136              
1137             # or
1138              
1139             $deck->deal( $pile, 'second' );
1140              
1141             Dealing from an empty deck won't do anything, but a warning will be issued.
1142              
1143             =cut
1144              
1145             sub deal {
1146 19     19 1 45 my $self = shift;
1147              
1148 19 100       20 if (not $self->size) {
1149 2         110 warn "Tried to deal without cards.\n";
1150 2         8 return $self;
1151             }
1152              
1153 17         30 my $params = _parse_params(@_);
1154              
1155             my $destination = $params->{_has_places} ?
1156 17 100       26 $params->{'places'}[0] :
1157             undef;
1158              
1159 17         15 my $position = $shortcuts->{'top'};
1160 17 100       29 if ($params->{_has_options}) {
1161 14         13 my $param = $params->{'options'}->[0];
1162 14 100       27 if (exists $shortcuts->{$param}) {
1163 13         15 $position = $shortcuts->{$param};
1164             }
1165             }
1166              
1167 17         22 my $card = $self->remove( $position );
1168              
1169 17 100       22 if ( defined $destination ) {
1170 11         19 return $destination->put( $card );
1171             }
1172             else {
1173 6         20 return $card;
1174             }
1175             }
1176              
1177             =head3 remove
1178              
1179             Removes a card from the deck.
1180              
1181             # remove the 4th card from the top
1182             my $card = $deck->remove( 4 );
1183              
1184             =cut
1185              
1186             # TODO: allow removal of several cards (do note that positions change as cards are removed)
1187             sub remove {
1188 75     75 1 76 my $self = shift;
1189 75         67 my $position = shift;
1190              
1191 75         67 my @deck = @{$self->get_deck};
  75         98  
1192              
1193 75 100       159 if ($position > 0) { $position--; }
  68         66  
1194              
1195 75         120 my $card = splice @deck, $position, 1;
1196              
1197 75         151 $self->_set_deck( @deck );
1198 75         482 return $card;
1199             }
1200              
1201              
1202             =head3 peek
1203              
1204             Peek at a position in the deck (this is essentially the same thing as &find()).
1205              
1206             # peek the top card
1207             my $card = $deck->peek( 1 );
1208              
1209             You can also peek the top and bottom card by using an alias:
1210              
1211             # peek the top card
1212             my $card = $deck->peek( 'top' );
1213              
1214             # peek the bottom card
1215             my $card = $deck->peek( 'bottom' );
1216              
1217             Negative indexes are also supported:
1218              
1219             # peek the second from bottom card
1220             my $card = $deck->peek( -2 );
1221              
1222             =cut
1223              
1224             sub peek {
1225 73     73 1 156 my $self = shift;
1226 73   100     125 my $position = shift || 1;
1227              
1228 73 100       101 if (_is_shortcut( $position )) {
1229 4         4 $position = $shortcuts->{$position};
1230             }
1231              
1232 73         105 return $self->find( $position );
1233             }
1234              
1235              
1236             =head3 take_random
1237              
1238             Remove a random card from the deck.
1239              
1240             my $random_card = $deck->take_random();
1241              
1242             You can also specify limits (if you're somehow directing the person taking the card to a particular section of the deck):
1243              
1244             my $random_card = $deck->take_random( 13, 39 );
1245              
1246             =cut
1247              
1248             sub take_random {
1249 57     57 1 67 my $self = shift;
1250              
1251 57   100     122 my $lower_limit = shift || 1;
1252 57         52 my $upper_limit = shift;
1253              
1254 57 100       102 $upper_limit = defined $upper_limit ?
1255             $upper_limit :
1256             $self->deck_size;
1257              
1258 57         132 return $self->remove( _rand( $lower_limit, $upper_limit ) );
1259             }
1260              
1261              
1262             =head3 remove_all
1263              
1264             Removes all cards that match a pattern from the deck.
1265              
1266             $deck->remove_all( 'Joker' ); # remove all Jokers
1267             $deck->remove_all( 'A' ); # remove all Aces
1268             $deck->remove_all( 'C' ); # remove all Clubs
1269             $deck->remove_all( 'J', 'Q', 'K' ); # remove all court cards
1270              
1271             Without arguments this method does precisely what it states:
1272              
1273             $deck->remove_all(); # removes everythin from the deck
1274              
1275             =cut
1276              
1277             sub remove_all {
1278 7     7 1 10 my $self = shift;
1279              
1280 7 100       11 if ( @_ ) {
1281 6         13 while (my $param = shift) {
1282 7 100       12 if ( exists $expressions->{$param} ) {
1283 4         3 $self->_set_deck( grep { not /$expressions->{$param}/ } @{$self->get_deck} );
  204         319  
  4         7  
1284             }
1285             else {
1286 3         4 $self->_set_deck( grep { not /$param/ } @{$self->get_deck} );
  159         165  
  3         4  
1287             }
1288             }
1289             }
1290             else {
1291 1         2 $self->_set_deck();
1292             }
1293            
1294 7         10 return $self;
1295             }
1296              
1297              
1298             =head3 dribble
1299              
1300             Dribble the cards (usually to select one, which could either be the last one to fall or the one that would be next).
1301              
1302             # dribble cards onto $pile
1303             $deck->dribble( $pile );
1304              
1305             # same thing, but declaring $pile
1306             $pile = $deck->dribble;
1307              
1308             # dribble to position 10 (in a 52 card deck, 42 cards would fall)
1309             $deck->dribble( 10 );
1310              
1311             # dribble 10 cards
1312             $deck->dribble( -10 );
1313              
1314             # dribble to position between 10 and 20
1315             $deck->dribble( 10, 20 );
1316              
1317             # dribble to position between 10th from the top and 10th from the bottom
1318             $deck->dribble( 10, -10 );
1319              
1320             =cut
1321              
1322             # TODO: what happens if you're dribbling and have no cards?
1323             sub dribble {
1324 7     7 1 14 my $self = shift;
1325 7         16 my $params = _parse_params( @_ );
1326              
1327 7         8 my $has_destination = @{$params->{'places'}};
  7         11  
1328             my $destination = $has_destination ?
1329 7 100       23 $params->{'places'}[0] :
1330             Games::Cards::ShuffleTrack->new( 'empty' );
1331              
1332 7         9 my ($lower_limit, $upper_limit) = $self->_fix_limits( @{$params->{'numbers'}} );
  7         18  
1333              
1334 7 100       13 if ( defined $lower_limit ) {
1335 4         9 $lower_limit = $self->size - $lower_limit;
1336 4 100       10 $upper_limit = defined $upper_limit ?
1337             $self->size - $upper_limit :
1338             $lower_limit;
1339             }
1340             else {
1341 3         7 $lower_limit = min( $self->size, 5 );
1342 3 100       6 $upper_limit = $self->size < 5 ? $self->size : $self->size - 5;
1343             }
1344              
1345 7         16 $self->turn;
1346 7         37 my $transfer = $self->cut_to( $lower_limit, $upper_limit );
1347 7         11 $transfer->turn;
1348 7         16 $transfer->move_to( $destination );
1349              
1350 7 100       40 return $has_destination ? $self : $destination;
1351             }
1352              
1353             # subroutines
1354              
1355             # TODO: fix limits in other methods (just being used in dribble)
1356             sub _fix_limits {
1357 7     7   13 my $self = shift;
1358 7         8 my @limits;
1359              
1360 7         21 while ( my $limit = shift ) {
1361 6 100       25 push @limits, $limit < 0 ? $self->size + $limit : $limit;
1362             }
1363              
1364 7         14 return @limits;
1365             }
1366              
1367             # TODO: use this for every method (just being used in dribble)
1368             sub _parse_params {
1369 24     24   62 my $params = {
1370             numbers => [],
1371             places => [],
1372             options => [],
1373             };
1374 24         50 while (my $param = shift) {
1375 33 100       91 if (looks_like_number($param)) {
    100          
1376 6         7 push @{$params->{'numbers'}}, $param;
  6         22  
1377             }
1378             elsif (ref $param eq 'Games::Cards::ShuffleTrack') {
1379 13         12 push @{$params->{'places'}}, $param;
  13         33  
1380             }
1381             else {
1382 14         12 push @{$params->{'options'}}, $param;
  14         34  
1383             }
1384             }
1385              
1386 24         41 for (qw/numbers places options/) {
1387 72         53 $params->{"_has_$_"} = @{$params->{$_}};
  72         145  
1388             }
1389 24         28 return $params;
1390             }
1391              
1392             sub _set_deck {
1393 413     413   647 my $self = shift;
1394 413         2852 return $self->{'deck'} = [@_];
1395             }
1396              
1397             sub _rand {
1398 198     198   174 my ($lower_limit, $upper_limit) = @_;
1399              
1400 198         925 return int($lower_limit + int(rand( $upper_limit - $lower_limit )));
1401             }
1402              
1403             sub _cut_depth {
1404 34     34   33 my $deck_size = shift;
1405 34         28 my $position = shift;
1406              
1407 34 100       62 if (not defined $position) {
1408 8         11 $position = 'normal';
1409             }
1410              
1411 34 100   124   172 if ( any { $_ eq $position } keys %$cut_limits ) {
  124         134  
1412 11         12 my ($lower, $upper) = @{$cut_limits->{ $position }};
  11         21  
1413 11         30 $position = _rand( $deck_size * $lower, $deck_size * $upper );
1414             }
1415              
1416 34         86 return $position;
1417             }
1418              
1419             sub _is_shortcut {
1420 73     73   53 my $shortcut = shift;
1421              
1422 73         171 return exists $shortcuts->{$shortcut};
1423             }
1424              
1425              
1426             =head1 GLOSSARY
1427              
1428             The following is not a comprehensive list of gambling terms; it is simply a list of some terms used somewhere in this module that may be useful.
1429              
1430             The text has been taken verbatim from The Expert at the Card Table.
1431              
1432             =over 4
1433              
1434             =item * Stock
1435              
1436             That portion of the deck that contains certain cards, placed in some particular order for dealing; or certain
1437             desirable cards placed at top or bottom of the deck.
1438              
1439             =item * Run
1440              
1441             To draw off one card at a time during the process of the hand shuffle. There is little or no difficulty in acquiring
1442             perfect ability to run the whole deck through in this manner with the utmost rapidity. The left thumb presses
1443             lightly on the top card, the right hand alone making the movement necessary to shuffle.
1444              
1445             =item * Break
1446              
1447             A space or division held in the deck. While shuffling it is held at the end by the right thumb. It is formed under
1448             the in-jog when about to under cut for the shuffle, by pushing the in-jog card slightly upwards with the right
1449             thumb, making a space of from an eighth to a quarter of an inch wide, and holding the space, by squeezing the
1450             ends of the packet to be drawn out, between the thumb and second and third fingers. The use of the break
1451             during a shuffle makes it possible to throw any number of cards that are immediately above it, in one packet
1452             into the left hand, without disarranging their order. The break is used when not shuffling, to locate any particular
1453             card or position, and is infinitely superior to the common method of inserting the little finger. A break can be
1454             held firmly by a finger or thumb of either hand, and entirely concealed by the other fingers of the same hand. It
1455             is also the principal aid in the blind riffles and cuts.
1456              
1457             =item * Throw
1458              
1459             To pass from the right hand to the left, during a shuffle, a certain number of cards in one packet, thereby
1460             retaining their order. A throw may be required at the beginning, during the process, or at the end of a shuffle;
1461             and the packet to be thrown may be located by the jog, or break, or by both.
1462              
1463             =item * Top Card
1464              
1465             The card on top of packet held in the left hand, or the original top card of the full deck, which about to be
1466             shuffled.
1467              
1468             =item * Riffle
1469              
1470             The modern method of shuffling on the table by springing, the ends of two packets into each other.
1471              
1472             =item * Crimp
1473              
1474             To bend one or a number of cards, so that they may be distinguished or located.
1475              
1476             =back
1477              
1478              
1479             =head1 AUTHOR
1480              
1481             Jose Castro, C<< >>
1482              
1483             =head1 BUGS
1484              
1485             Please report any bugs or feature requests to C, or through
1486             the web interface at L. I will be notified, and then you'll
1487             automatically be notified of progress on your bug as I make changes.
1488              
1489              
1490             =head1 SUPPORT
1491              
1492             You can find documentation for this module with the perldoc command.
1493              
1494             perldoc Games::Cards::ShuffleTrack
1495              
1496              
1497             You can also look for information at:
1498              
1499             =over 4
1500              
1501             =item * Github
1502              
1503             L
1504              
1505             =item * Search CPAN
1506              
1507             L
1508              
1509             =back
1510              
1511              
1512             =head1 SEE ALSO
1513              
1514             The following is an extremely small list of recommended books:
1515              
1516             =over 4
1517              
1518             =item * The Expert at the Card Table, by S. W. Erdnase
1519              
1520             =item * Card College, by Roberto Giobbi
1521              
1522             =back
1523              
1524              
1525             =head1 LICENSE AND COPYRIGHT
1526              
1527             Copyright 2016 Jose Castro.
1528              
1529             This program is free software; you can redistribute it and/or modify it
1530             under the terms of the the Artistic License (2.0). You may obtain a
1531             copy of the full license at:
1532              
1533             L
1534              
1535             Any use, modification, and distribution of the Standard or Modified
1536             Versions is governed by this Artistic License. By using, modifying or
1537             distributing the Package, you accept this license. Do not use, modify,
1538             or distribute the Package, if you do not accept this license.
1539              
1540             If your Modified Version has been derived from a Modified Version made
1541             by someone other than you, you are nevertheless required to ensure that
1542             your Modified Version complies with the requirements of this license.
1543              
1544             This license does not grant you the right to use any trademark, service
1545             mark, tradename, or logo of the Copyright Holder.
1546              
1547             This license includes the non-exclusive, worldwide, free-of-charge
1548             patent license to make, have made, use, offer to sell, sell, import and
1549             otherwise transfer the Package with respect to any patent claims
1550             licensable by the Copyright Holder that are necessarily infringed by the
1551             Package. If you institute patent litigation (including a cross-claim or
1552             counterclaim) against any party alleging that the Package constitutes
1553             direct or contributory patent infringement, then this Artistic License
1554             to you shall terminate on the date that such litigation is filed.
1555              
1556             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
1557             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
1558             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
1559             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
1560             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
1561             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
1562             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
1563             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1564              
1565              
1566             =cut
1567              
1568             1; # End of Games::Cards::ShuffleTrack