File Coverage

blib/lib/Dreamhack/Solitaire.pm
Criterion Covered Total %
statement 14 105 13.3
branch 0 30 0.0
condition 0 12 0.0
subroutine 5 11 45.4
pod 0 6 0.0
total 19 164 11.5


line stmt bran cond sub pod time code
1             package Dreamhack::Solitaire;
2 1     1   787 use 5.008001;
  1         3  
3 1     1   5 use strict;
  1         1  
  1         22  
4 1     1   15 use warnings;
  1         1  
  1         44  
5              
6 1     1   5 use List::Util qw(shuffle);
  1         1  
  1         116  
7 1     1   815 use List::MoreUtils 0.413 qw(uniq singleton);
  1         11243  
  1         10  
8              
9             our $VERSION = "0.01";
10              
11             our @suits = ('s','c','d','h');
12             our @valence = ('A','K','Q','J','10','9','8','7','6');
13              
14             sub new {
15 0     0 0   my $class = shift;
16 0           my %args = @_;
17 0           my @check = ();
18 0           my @errors = ();
19              
20 0 0 0       if (exists $args{'suits'} && (ref $args{'suits'} eq 'ARRAY')) {
    0          
21 0           @suits = @{$args{'suits'}}
  0            
22             }
23             elsif (exists $args{'lang'}) {
24 0 0         if (lc($args{'lang'}) eq 'ru_ru.utf8') {
25 0           @suits = ('п','к','б','ч');
26 0           @valence = ('Т','К','Д','В','10','9','8','7','6');
27             }
28             }
29              
30 0           @check = uniq @suits;
31 0 0         unless ($#check == $#suits) {
32 0           die 'Duplicate suits';
33             }
34              
35 0 0 0       if (exists $args{'valence'} && (ref $args{'valence'} eq 'ARRAY')) {
36 0           @valence = @{$args{'valence'}}
  0            
37             }
38              
39 0           @check = uniq @valence;
40 0 0         unless ($#check == $#valence) {
41 0           die 'Duplicate valence';
42             }
43              
44 0           my @deck = ();
45 0           my %complex = ();
46              
47 0           for my $suit (@suits) {
48 0           for my $valence (@valence) {
49 0           push @deck, $valence.$suit;
50 0           $complex{$valence.$suit} = [$valence,$suit];
51             }
52             }
53              
54 0           my $self = {
55             suits => \@suits,
56             valence => \@valence,
57             deck => \@deck,
58             layout => [],
59             leftcards => \@deck,
60             complex => \%complex,
61             convolution => [],
62             attempts => undef,
63             errors => \@errors,
64             };
65              
66 0           bless $self, $class;
67 0           return $self
68             }
69              
70             sub init_layout {
71 0     0 0   my ($self, $layout) = @_;
72              
73 0 0 0       unless ($layout && (ref $layout eq 'ARRAY')) {
74 0           die 'Not an arrayref for layout';
75             }
76              
77 0 0         if ($#$layout > $#{$self->{deck}}) {
  0            
78 0           die 'Initial layout too long: ' . (1 + $#$layout) . ' cards';
79             }
80              
81 0           my @cards = ();
82 0           map {s/\?//} @$layout;
  0            
83 0           for (@$layout) {
84 0 0         if ($_) {
85 0           push @cards, $_;
86             }
87             }
88              
89 0           my @test = uniq @cards;
90 0 0         unless ($#test == $#cards) {
91 0           die 'Duplicate cards in layout';
92             }
93              
94 0           for my $card (@cards) {
95 0 0         unless (grep {$card eq $_} @{$self->{'deck'}}) {
  0            
  0            
96 0           die "Bad card in layout: $card";
97             }
98             }
99              
100 0           $self->{'layout'} = $layout;
101              
102 0           my @diff = singleton(@{$self->{'deck'}}, @{$self->{'layout'}});
  0            
  0            
103 0           $self->{'leftcards'} = \@diff;
104              
105 0           return $self
106             }
107              
108             sub parse_init_string {
109 0     0 0   my ($self, $string) = @_;
110 0           my @layout = split /[\[\]\s\n]+/, $string;
111 0           @layout = grep {$_} @layout;
  0            
112 0 0         return wantarray ? @layout : \@layout;
113             }
114              
115             sub extract {
116 0     0 0   my ($self, $str) = @_;
117 0           my ($valence, $suit) = @{${$self->{'complex'}}{$str}};
  0            
  0            
118 0           return ($valence, $suit)
119             }
120              
121             sub add_rnd_layout {
122 0     0 0   my ($self, ) = @_;
123 0           my @cards = shuffle @{$self->{'leftcards'}};
  0            
124              
125 0           my @layout = ();
126 0           for my $card (@{$self->{'layout'}}) {
  0            
127 0 0         if ($card) {
128 0           push @layout, $card;
129             }
130             else {
131 0           push @layout, shift @cards;
132             }
133             }
134 0           @layout = (@layout, @cards);
135              
136             return @layout
137 0           }
138              
139             sub format {
140 0     0 0   my ($self, ) = @_;
141 0           my $string = '[';
142 0           my @layout = @{$self->{'layout'}};
  0            
143 0           my @convolution = @{$self->{'convolution'}};
  0            
144              
145 0           my $index = 0;
146 0           my $convolution = shift @convolution;
147 0           while (my $card = shift @layout) {
148 0           $string .= $card;
149 0 0 0       if ((defined $convolution) && ($convolution == $index++)) {
150 0           $string .= "]\n";
151 0           $convolution = shift @convolution;
152 0 0         $string .= '[' if $convolution;
153             }
154             else {
155 0           $string .= " ";
156             }
157             }
158 0           return $string
159             }
160              
161             1;
162             __END__