File Coverage

blib/lib/Games/Solitaire/Verify/HorneAutomovePrune.pm
Criterion Covered Total %
statement 41 42 97.6
branch 12 14 85.7
condition n/a
subroutine 6 6 100.0
pod 2 2 100.0
total 61 64 95.3


line stmt bran cond sub pod time code
1             package Games::Solitaire::Verify::HorneAutomovePrune;
2             $Games::Solitaire::Verify::HorneAutomovePrune::VERSION = '0.2403';
3 1     1   535 use strict;
  1         2  
  1         31  
4 1     1   6 use warnings;
  1         2  
  1         617  
5              
6             sub _calc_foundation_to_put_card_on
7             {
8 16     16   28 my ( $running_state, $card ) = @_;
9              
10             DECKS_LOOP:
11 16         34 for my $deck ( 0 .. $running_state->num_decks() - 1 )
12             {
13 16 100       42 if ( $running_state->get_foundation_value( $card->suit(), $deck ) ==
14             $card->rank() - 1 )
15             {
16 1         12 for my $other_deck_idx (
17             0 .. ( ( $running_state->num_decks() << 2 ) - 1 ) )
18             {
19 4 100       12 if (
    50          
20             $running_state->get_foundation_value(
21             $card->get_suits_seq->[ $other_deck_idx % 4 ],
22             ( $other_deck_idx >> 2 ),
23             ) < $card->rank() - 2 - (
24             (
25             $card->color_for_suit(
26             $card->get_suits_seq->[ $other_deck_idx % 4 ]
27             ) eq $card->color()
28             ) ? 1 : 0
29             )
30             )
31             {
32 0         0 next DECKS_LOOP;
33             }
34             }
35 1         6 return [ $card->suit(), $deck ];
36             }
37             }
38 15         21 return;
39             }
40              
41             sub perform_and_output_move
42             {
43 1     1 1 4 my ($args) = @_;
44 1         3 my $running_state = $args->{state};
45 1         2 my $out_running_state = $args->{output_state};
46 1         2 my $out_move = $args->{output_move};
47 1         2 my $move_s = $args->{move_string};
48 1         13 $out_move->($move_s);
49 1         27 $running_state->verify_and_perform_move(
50             Games::Solitaire::Verify::Move->new(
51             {
52             fcs_string => $move_s,
53             game => $running_state->_variant(),
54             },
55             )
56             );
57 1         15 $out_running_state->($running_state);
58              
59 1         4 return;
60             }
61              
62             sub _check_for_prune_move
63             {
64 24     24   49 my ( $running_state, $card, $prune_move, $out_running_state, $out_move ) =
65             @_;
66              
67 24 100       49 if ( defined($card) )
68             {
69 16         28 my $f = _calc_foundation_to_put_card_on( $running_state, $card );
70              
71 16 100       35 if ( defined($f) )
72             {
73 1         8 perform_and_output_move(
74             {
75             state => $running_state,
76             move_string => $prune_move,
77             output_state => $out_running_state,
78             output_move => $out_move
79             }
80             );
81 1         17 return 1;
82             }
83             }
84              
85 23         49 return 0;
86             }
87              
88             sub do_prune
89             {
90 1     1 1 16 my ($args) = @_;
91 1         3 my $running_state = $args->{state};
92 1         2 my $out_running_state = $args->{output_state};
93 1         3 my $out_move = $args->{output_move};
94             PRUNE:
95 1         11 while (1)
96             {
97 2         7 my $num_moved = 0;
98 2         6 foreach my $idx ( 0 .. ( $running_state->num_columns() - 1 ) )
99             {
100 16         37 my $col = $running_state->get_column($idx);
101              
102 16 50       36 $num_moved += _check_for_prune_move(
103             $running_state,
104             scalar( $col->len() ? $col->top() : undef() ),
105             "Move a card from stack $idx to the foundations",
106             $out_running_state,
107             $out_move,
108             );
109             }
110              
111 2         7 foreach my $idx ( 0 .. ( $running_state->num_freecells() - 1 ) )
112             {
113 8         22 $num_moved += _check_for_prune_move(
114             $running_state,
115             $running_state->get_freecell($idx),
116             "Move a card from freecell $idx to the foundations",
117             $out_running_state,
118             $out_move,
119             );
120             }
121 2 100       11 last PRUNE if $num_moved == 0;
122             }
123             }
124              
125             1;
126              
127             __END__